【CC2530 教程 七】CC2530 ADC寄存器配置及使用

目录

一、CC2530 ADC介绍: 

(1)ADC特性说明:

(2)ADC方框图:

(3)ADC配置:

APCFG (0xF2) - 模拟外设 I/O 配置

 二、ADC 操作:

(1)ADC 输入:

(2)ADC 转换序列:

(3)单个 ADC 转换:

(4)ADC运行模式:

控制寄存器:

ADCCON1 寄存器:

ADCCON2 寄存器:

ADCCON3 寄存器:

(5)ADC 转换结果:

(6)ADC 参考电压:

(7)ADC 转换时间:

(8)ADC 中断:

(9)ADC DMA 触发:

三、ADC 寄存器:

ADCL(0xBA)-ADC数据低位

ADCH(0xBB)-ADC数据高位

ADCON1(0xB4)-ADC控制1

ADCCON2(0xB5)-ADC控制2

 ADCCON3(0xB6)–ADC控制3

TRO(0x624B)-测试寄存器0

四、代码编写:

(1)ADC.C文件编写:

(2)main.c文件编写:

(3)ADC读取光敏示例:

五、代码下载: 


一、CC2530 ADC介绍: 

ADC 支持 14 位的模拟数字转换,具有多达 12 位的有效位(ENOB)。它包括一个模拟多路转换器,具有多达 8 个各自可配置的通道,以及一个参考电压发生器。转换结果通过 DMA 写入存储器。还具有若干运行模式。

(1)ADC特性说明:

特性名称 描述
抽取率及分辨率 可选的抽取率,设置分辨率(7到12位)
输入通道 8个独立的输入通道,可接受单端或差分信号
参考电压 内部单端、外部单端、外部差分或 AVDD5
中断请求 产生中断请求
DMA触发 转换结束时的 DMA 触发
温度传感器输入 温度传感器输入
电池测量功能 电池测量功能

(2)ADC方框图:

(3)ADC配置:

当使用 ADC 时,端口 0 引脚必须配置为 ADC 输入。可以使用多达八个 ADC 输入引脚。要配置一个端口0引脚为一个 ADC 输 入 ,APCFG 寄存器中相应的位必须设置为 1。这个寄存器的默认值选择端口 0 引脚为非 ADC输入,即数字输入/输出。

APCFG 寄存器的设置将覆盖 P0SEL 的设置。

ADC 可以配置为使用通用 I/O 引脚 P2.0 作为内部触发器来启动转换。当用作 ADC 内部触发器时,P2.0 必须在输入模式下配置为通用 I/O。

APCFG (0xF2) - 模拟外设 I/O 配置
名称 复位 R/W 描述
7:0 APCFG[7:0] 0x00 R/W

模拟外设I/O配置。APCFG[7:0]选择P0.7-P0.0作为模拟I/O。

0: 模拟I/O禁用;

1: 模拟I/O使能;

 二、ADC 操作:

(1)ADC 输入:

        端口 0 引脚的信号可以用作 ADC 输入。在下面的描述中,这些端口引脚指的是 AIN0-AIN7 引脚。输入引脚 AIN0-AIN7 是连接到 ADC 的。

        可以把输入配置为单端或差分输入。在选择差分输入的情况下,差分输入包括输入对AIN0-1、AIN2-3、AIN4-5 和 AIN6-7。注意负电压不适用于这些引脚,大于 VDD(未调节电压)的电压也不能。它们之间的差别是在差分模式下转换。它是在差分模式下转换的输入对之间的差。

        除了输入引脚 AIN0-AIN7,片上温度传感器的输出也可以选择作为 ADC 的输入,用于温度测量。为此寄存器 TR0.ADCTM 和 ATEST.ATESTCTRL 必须分别按ADC 寄存器和 无线电寄存器所述设置。

        还可以输入一个对应 AVDD5/3 的电压作为一个 ADC 输入。这个输入允许诸如需要在应用中实现一个电池监测器的功能。注意在这种情况下参考电压不能取决于电源电压,比如 AVDD5 电压不能用作一个参考电压。

        单端电压输入 AIN0 到 AIN7 以通道号码 0 到 7 表示。通道号码 8 到 11 表示差分输入,由 AIN0–AIN1、AIN2–AIN3、AIN4–AIN5 和 AIN6–AIN7 组成。通道号码12到15表示 GND(12)温度传感器(14),和 AVDD5/3(15)。这些值在 ADCCON2.SCH 和 ADCCON3.SCH 域中使用。

(2)ADC 转换序列:

        ADC 将执行一系列的转换,并把结果移动到存储器(通过 DMA),不需要任何 CPU 干预。
转换序列可以被 APCFG 寄存器影响,八位模拟输入来自 I/O 引脚,不必经过编程变为模拟输入。如果一个通道正常情况下应是序列的一部分,但是相应的模拟输入在 APCFG 中禁用,那么通道将被跳过。

        当使用差分输入,处于差分对的两个引脚都必须在 APCFG 寄存器中设置为模拟输入引脚。
ADCCON2.SCH 寄存器位用于定义一个 ADC 转换序列,它来自 ADC 输入。如果ADCCON2.SCH 设置为一个小于 8 的值,转换序列包括一个转换,来自每个通道,从 0 往上,包括 ADCCON2.SCH 编程的通道号码。

        当 ADCCON2.SCH 设置为一个在 8 和 12 之间的值,序列包括差分输入,从通道 8 开始,在已编程的通道结束。对于 ADCCON2.SCH 大于或等于 12,序列仅包括所选的通道。

(3)单个 ADC 转换:

除了这一转换序列,ADC 可以编程为从任何通道执行一个转换。这样一个转换通过写 ADCCON3 寄存器触发。除非一个转换序列已经正在进行,转换立即开始,在这种情况下序列一完成单个转换就被执行。

(4)ADC运行模式:

控制寄存器:

ADC 有三种控制寄存器:ADCCON1、ADCCON2 和 ADCCON3。这些寄存器用于配置 ADC 并报告结果。

ADCCON1 寄存器:
  • EOC 位:状态位,当一个转换结束时设置为高电平,当读取 ADCH 时被清除。
  • ST 位:用于启动一个转换序列。当设置为高电平且 ADCCON1.STSEL = 11,且当前没有转换正在进行时,就启动一个序列。
  • STSEL 位:选择哪个事件将启动新的转换序列。选项包括外部引脚 P2.0 上升沿、外部引脚事件、之前序列的结束事件、定时器 1 的通道 0 比较事件或 ADCCON1.ST = 1。
ADCCON2 寄存器:
  • SREF 位:用于选择参考电压。可选的参考电压包括内部单端、外部单端、外部差分或 AVDD5。参考电压只能在没有转换运行时修改。
  • DIV 位:选择抽取率(并因此也设置了分辨率和完成一个转换所需的时间,或样本率)。抽取率只能在没有转换运行时修改。
  • SCH 位:选择转换序列的最后一个通道。
ADCCON3 寄存器:
  • ADCCON3 寄存器控制单个转换的通道号码、参考电压和抽取率。单个转换在寄存器ADCCON3 写入后将立即发生,或如果一个转换序列正在进行,该序列结束之后立即发生。该寄存器位的编码和 ADCCON2 是完全一样的。

(5)ADC 转换结果:

        数字转换结果以 2 的补码形式表示。对于单端配置,结果总是为正。这是因为结果是输入信号和地面之间的差值,它总是一个正符号数(Vconv=Vinp-Vinn,其中 Vinn=0V)。当输入幅度等于所选的电压参考 VREF时,达到最大值。对于差分配置,两个引脚对之间的差分被转换,这个差分可以是负符号数。对于抽取率是 512的一个数字转换结果的 12 位 MSB,当模拟输入 Vconv 等于 VREF 时,数字转换结果是 2047。当模拟输入等于-VREF 时,数字转换结果是-2048。

        当 ADCCON1.EOC 设置为 1 时,数字转换结果是可以获得的,且结果放在 ADCH 和 ADCL 中。注意转换结果总是驻留在 ADCH 和 ADCL 寄存器组合的 MSB 段中。

        当读取 ADCCON2.SCH 位时,它们将指示转换在哪个通道上进行。ADCL 和 ADCH 中的结果一般适用于之前的转换。如果转换序列已经结束,ADCCON2.SCH 的值大于最后一个通道号码,但是如果最后写入ADCCON2.SCH 的通道号码是 12 或更大,将读回同一个值。

(6)ADC 参考电压:

        模拟数字转换的正参考电压可选择为一个内部生成的电压,AVDD5 引脚,适用于 AIN7 输入引脚的外部电压,或适用于 AIN6-AIN7 输入引脚的差分电压。

        转换结果的准确性取决于参考电压的稳定性和噪音属性。希望的电压有偏差会导致 ADC 增益误差,与希望电压和实际电压的比例成正比。参考电压的噪音必须低于 ADC 的量化噪音,以确保达到规定的 SNR。

(7)ADC 转换时间:

ADC 只能运行在 32 MHz XOSC 上,用户不能整除系统时钟。实际 ADC 采样的 4 MHz 的频率由固定的内部划分器产生。执行一个转换所需的时间取决于所选的抽取率。总的来说,转换时间由以下公式给定:Tconv = (抽取率 + 16) x 0.25 μs。

(8)ADC 中断:

当通过写 ADCCON3 触发的一个单个转换完成时,ADC 将产生一个中断。当完成一个序列转换时,不产生一个中断。

(9)ADC DMA 触发:

        每完成一个序列转换,ADC 将产生一个 DMA 触发。当完成一个单个转换,不产生 DMA 触发。

        对于 ADCCON2.SCH 中头 8 位可能的设置所定义的八个通道,每一个都有一个 DMA 触发。当通道中一个新的样本准备转换,DMA 触发是活动的。DMA 触发命名为表 8-1 中的 ADC_CHsd,其中 s 是单端通道,d 是差分通道。

        另外,还有一个 DMA 触发 ADC_CHALL,当 ADC 转换序列的任何通道中有新的数据准备好时,它是活动的。

三、ADC 寄存器:

ADCL(0xBA)-ADC数据低位

名称 复位 R/W 描述
7:2 ADC[5:0] 000000 R ADC转换结果的低位部分
1:0 - 00 R0 没有使用。读出来一直是 0

ADCH(0xBB)-ADC数据高位

名称 复位 R/W 描述
7:0 ADC[13:6] 0x00 R ADC转换结果的高位部分

ADCON1(0xB4)-ADC控制1

名称 复位 R/W 描述
7 EOC 0 R/H0

转换结束。当ADCH被读取的时候清除。如果已读取前一数据之前,完成一个新的转换,EOC位仍然为高。

0: 转换没有完成;

1: 转换完成

6 ST 0 R/W

开始转换。读为1,直到转换完成。

0: 没有转换正在进行;

1: 如果ADCCON1.STSEL=11并且没有序列正在运行就启动一个转换序列。

5:4 STSEL[1:0] 11 R/W1

启动选择。选择该事件,将启动一个新的转换序列。

00: P2.0引脚的外部触发;

01: 全速。不等待触发器;

10: 定时器1通道0比较事件;

11: ADCCON1.ST=1;

3:2 RCTRL[1:0] 00 R/W

控制16位随机数发生器。当写01时,当操作完成时设置将自动返回到00。

00: 正常运行。(13X型展开);

01: LFSR的时钟一次(没有展开);

10: 保留;

11: 停止。关闭随机数发生器;

1:0 - 11 R/W 保留。一直设为11

ADCCON2(0xB5)-ADC控制2

名称 复位 R/W 描述
7:6 SREF[1:0] 00 R/W

选择参考电压用于序列转换。

00: 内部参考电压;

01: AIN7引脚上的外部参考电压;

10: AVDD5引脚;

11: AIN6-AIN7差分输入外部参考电压;

5:4 SDIV[1:0] 01 R/W

为包含在转换序列内的通道设置抽取率。抽取率也决定完成转换需要的时间和分辨率。

00: 64抽取率(7位ENOB);

01: 128抽取率(9位ENOB);

10: 256抽取率(10位ENOB);

11: 512抽取率(12位ENOB);

3:0 SCH[3:0] 0000 R/W

序列通道选择。选择序列转换的通道。一个序列可以是从AIN0到AIN7(SCH<=7)也可以是从差分输入AIN0-AIN1到AIN6-AIN7(8<=SCH<=11)。对于其他的设置,只能执行单个转换。当读取的时候,这些位将代表有转换进行的通道号码。

0000: AIN0;

0001: AIN1;

0010: AIN2;

0011: AIN3;

0100: AIN4;

0101: AIN5;

0110: AIN6;

0111: AIN7;

1000: AIN0-AIN1;

1001: AIN2-AIN3;

1010: AIN4-AIN5;

1011: AIN6-AIN7;

1100: GND;

1101: 正电压参考;

1110: 温度传感器;

1111: VDD/3;

 ADCCON3(0xB6)–ADC控制3

名称 复位 R/W 描述
7:6 EREF[1:0] 00 R/W

选择用于额外转换的参考电压。

00: 内部参考电压;

01: AIN7引脚上的外部参考电压;

10: AVDD5引脚;

11: 在AIN6-AIN7差分输入的外部参考电压

5:4 EDIV[1:0] 00 R/W

设置用于额外转换的抽取率。抽取率也决定了完成转换需要的时间和分辨率。

00: 64抽取率(7位ENOB);

01: 128抽取率(9位ENOB);

10: 256抽取率(10位ENOB);

11: 512抽取率(12位ENOB);

3:0 ECH[3:0] 0000 R/W

单个通道选择。选择写ADCCON3触发的单个转换所在的通道号码。当单个转换完成,该位自动清除。

0000: AIN0;

0001: AIN1;

0010: AIN2;

0011: AIN3;

0100: AIN4;

0101: AIN5;

0110: AIN6;

0111: AIN7;

1000: AIN0-AIN1;

1001: AIN2-AIN3;

1010: AIN4-AIN5;

1011: AIN6-AIN7;

1100: GND;

1101: 正电压参考;

1110: 温度传感器;

1111: VDD/3;

TRO(0x624B)-测试寄存器0

名称 复位 R/W 描述
7:1 - 0000 000 R0 保留。写作0。
0 ACTM 0 R/W 设置为1来连接温度传感器到SOC_ADC。也可以看ATEST寄存器描述来使能温度传感器

四、代码编写:

(1)ADC.C文件编写:

#include <ioCC2530.h>
/*
APCFG (0xF2) –模拟外设 I/O 配置
位       名称      复位      R/W     描述
7:0     APCFG[7:0] 0x00      R/W  模拟外设I/O配置。
                                  APCFG[7:0]选择P0.7 - P0.0作为模拟I/O
                                  0: 模拟I/O禁用
                                  1: 模拟I/O使能

*/

/*
ADCL (0xBA) – ADC 数据低位
位       名称      复位      R/W     描述
7:2    ADC[5:0]   000000      R      ADC转换结果的低位部分
1:0       -         00        R0     没有使用。读出来一直是 0
*/

/*
ADCH (0xBB) – ADC 数据高位
位       名称      复位      R/W     描述
7:0    ADC[13:6]   0x00       R      ADC转换结果的高位部分。
*/

/*
ADCCON1 (0xB4)–ADC 控制 1
位       名称      复位      R/W         描述
7        EOC        0        R/H0       转换结束。当 ADCH 被读取的时候清除。
                                        如果已读取前一数据之前,完成一个新的转换,EOC 位仍然为高。
                                        0: 转换没有完成
                                        1: 转换完成
6         ST        0                   开始转换。读为1,直到转换完成
                                        0: 没有转换正在进行
                                        1: 如果 ADCCON1.STSEL = 11并且没有序列正在运行就启动一个转换序列。
5:4   STSEL[1:0]    11        R/W1      启动选择。选择该事件,将启动一个新的转换序列。
                                        00: P2.0引脚的外部触发。
                                        01: 全速。不等待触发器
                                        10: 定时器1通道0比较事件
                                        11: ADCCON1.ST = 1
3:2   RCTRL[1:0]    00        R/W       控制16位随机数发生器(第 13 章)。
                                        当写 01 时,当操作完成时设置将自动返回到 00。
                                        00: 正常运行。(13X 型展开)
                                        01: LFSR 的时钟一次(没有展开).
                                        10: 保留
                                        11: 停止。关闭随机数发生器
1:0      -          11         R/W      保留。一直设为 11 。
*/

/*
ADCCON2 (0xB5)–ADC 控制 2
位       名称      复位      R/W         描述
7:6    SREF[1:0]    00       R/W         选择参考电压用于序列转换
                                          00: 内部参考电压
                                          01: AIN7 引脚上的外部参考电压
                                          10: AVDD5 引脚
                                          11: AIN6 - AIN7 差分输入外部参考电压
5:4    SDIV[1:0]    01       R/W          为包含在转换序列内的通道设置抽取率。
                                          抽取率也决定完成转换需要的时间和分辨率。
                                          00: 64 抽取率(7 位 ENOB)
                                          01: 128 抽取率(9 位 ENOB)
                                          10: 256 抽取率(10 位 ENOB)
                                          11: 512 抽取率(12 位 ENOB)
3:0    SCH[3:0]    0000      R/W          序列通道选择。选择序列结束。一个序列可以是从 AIN0 到 AIN7(SCH<=7) 
                                          也可以从差分输入AIN0-AIN1到AIN6-AIN7(8<=SCH<=11)。
                                          对于其他的设置,只能执行单个转换。
                                          当读取的时候,这些位将代表有转换进行的通道号码。
                                          0000: AIN0
                                          0001: AIN1
                                          0010: AIN2
                                          0011: AIN3
                                          0100: AIN4
                                          0101: AIN5
                                          0110: AIN6
                                          0111: AIN7
                                          1000: AIN0-AIN1
                                          1001: AIN2-AIN3
                                          1010: AIN4-AIN5
                                          1011: AIN6-AIN7
                                          1100: GND
                                          1101: 正电压参考
                                          1110: 温度传感器
                                          1111: VDD/3
*/

/*
ADCCON3 (0xB6)–ADC 控制 3
位       名称      复位      R/W             描述
7:6     EREF[1:0]   00       R/W          选择用于额外转换的参考电压
                                          00: 内部参考电压
                                          01: AIN7 引脚上的外部参考电压
                                          10: AVDD5 引脚
                                          11: 在 AIN6-AIN7 差分输入的外部参考电压
5:4     EDIV[1:0]   00       R/W          设置用于额外转换的抽取率。抽取率也决定了完成转换需要的时间和分辨率。
                                          00: 64 抽取率(7 位 ENOB)
                                          01: 128 抽取率(9 位 ENOB)
                                          10: 256 抽取率(10 位 ENOB)
                                          11: 512 抽取率(12 位 ENOB)
3:0     ECH[3:0]   0000       R/W         单个通道选择。选择写 ADCCON3 触发的单个转换所在的通道号码。
                                          当单个转换完成,该位自动清除。
                                            0000: AIN0
                                            0001: AIN1
                                            0010: AIN2
                                            0011: AIN3
                                            0100: AIN4
                                            0101: AIN5
                                            0110: AIN6
                                            0111: AIN7
                                            1000: AIN0-AIN1
                                            1001: AIN2-AIN3
                                            1010: AIN4-AIN5
                                            1011: AIN6-AIN7
                                            1100: GND
                                            1101: 正电压参考
                                            1110: 温度传感器
                                            1111: VDD/3
*/

/*
TR0 (0x624B) –测试寄存器 0
位       名称      复位      R/W             描述
7:1       -      0000000     R0            保留。写作0。
0       ACTM         0      R/W            设置为1来连接温度传感器到SOC_ADC。
                                           也参考ATEST寄存器描述来使能温度传感器
  

*/
// ADC初始化函数
void ADC_Init(void) {
  
    // 配置P0.0为ADC输入
    APCFG |= 0x01;       // 使能P0.0作为模拟输入
                         // APCFG寄存器的设置将覆盖P0SEL的设置
 // P0DIR &= ~0x01;      //P0_0端口设置为输入端口 ,默认输入可不写

    // 配置ADC控制寄存器
    ADCCON1 = 0x30; // 选择手动启动转换,STSEL = 11 (ADCCON1.ST = 1)
    ADCCON2 = 0xB0; // 使用AVDD5引脚电压,512 抽取率(12 位 ENOB),选择AIN0通道
}

// ADC读取函数
unsigned int ADC_Read(void) {
    unsigned int ADC_Value;

    // 启动ADC转换
    ADCCON1 |= 0x40; // 设置ST位为1,启动转换

    // 等待转换完成
    while (!(ADCCON1 & 0x80)); // 等待EOC位变为1

    // 读取ADC结果
    ADC_Value = ADCL;          // 读取低字节
    ADC_Value |= (ADCH << 8); // 读取高字节并组合成完整的ADC值

    /*
    数据手册存在问题,有效位ADC[13:0],其中ADC[0]为无效位
    ADC[13]为符号位,ADC[12:1]为数据位
    即,读取的ADC值要右移三位才正确
    */
    ADC_Value >>=3;           // 0-4095

    return ADC_Value;
}

(2)main.c文件编写:

#include <ioCC2530.h>
#include <stdio.h>
#include "Delay.h"
#include "Clock.h"
#include "uart.h"
#include "LED.h"
#include "ADC.h"

unsigned int ADC;
void main(void) {

    Clock_config_32MHz();    // 时钟配置32MHz
    Uart_Init();
    ADC_Init();

    while (1) {

      ADC=ADC_Read();
      printf("%d\n",ADC);
      Delay_s(1);
    }
}

(3)ADC读取光敏示例:

五、代码下载:

http://通过网盘分享的文件:ADCRead 链接: https://pan.baidu.com/s/1_zd0A4z1QFIwEDQZI02ABA?pwd=gxhy 提取码: gxhy