嵌入式系统(六)模数转换
Published in:2023-12-07 | category: 嵌入式系统

模拟/数字转换 (Analog to Digital Converter,简称ADC)

是将输入的模拟信号转换为数字信号。

各种被测控的物理量(如:速度、压力、温度、光照强度、磁场等)是一些连续变化的物理量,传感器将这些物理量转换成与之相对应的电压和电流就是模拟信号。单片机只能接收数字信号,要处理这些信号就必须转换成数字信号,模拟/数字转换是数字测控系统中必须的信号转换。

原理是进行,以一定的频率采样电压值,连续采样一段时间

1 CC2530的ADC模块

CC2530的ADC模块 支持最高14位二进制 的模拟数字转换具有12位的有效数据位。

它包括一个输入多路切换器,具有8个各自可配置的通道;以及一个参考电压发生器。

转换结果通过DMA(直接内存访问)写入存储器,还具有多种运行模式。

先介绍运行模式

2 ADC工作模式

1 输入

ADC模块的输入——从哪些端口输入

对于CC2530的ADC模块,端口P0引脚可以配置为ADC输入端,

依次为AIN0~AIN7。

可以把输入配置为单端或差分输入

在选择单端输入的情况下,通道号码0-7

在选择差分输入的情况下,通道号码8-11,差分输入包括输入对AIN0-AIN1、

AIN2-AIN3、AIN4-AIN5和AIN6-AIN7 共四对、

通道12-15分别是GND,预留通道,温度传感器,AVDD5 在应用中这个输入可以实现一个电池电压监测器的功能。

为什么要进行差分输入,差分输入方式比单端输入来说,有更强的抗干扰能力

序列ADC转换与单通道ADC转换

3 ADC相关寄存器

3.1数据寄存器

ADC有两个数据寄存器:用来存放转换结果

ADCL(0xBA)-ADC数据低位寄存器、

ADCH(0xBB)-ADC数据高位寄存器,

3.2 控制寄存器

APCFG

8位模拟量输入来自I/O引脚,不必通过编程将这些引脚变为模拟输入。但是,当相应的模拟输入端在APCFG寄存器中被禁用时,此通道将被跳过。当使用差分输入时,相应的两个引脚都必须在APCFG寄存器中设置为模拟输入引脚。

APCFG寄存器描述如图所示

image-20240106211552376

ADC还有三个控制寄存器:ADCCON1、ADCCON2和ADCCON3

ADCCON1

ADCCON1.ST用于启动一个转换序列。当没有转换正在运行时这个位设置为高电平

ADCCON1.STSEL位选择哪个事件将启动一个新的转换序列。该选项可以选择为外部引脚P2.0上升沿或外部引脚事件,之前序列的结束事件,定时器1的通道0比较事件或ADCCON1.ST是1。

ADCCON2

寄存器位ADCCON2.SCH用于定义一个ADC转换序列,如果ADCCON2.SCH设置为一个小于8的值,ADC转换序列包括

从0通道开始,直到并包括所设置的通道号码。当ADCCON2.SCH设置为一个8和12之间的值,转换序列包括

从通道8开始差分输入,到ADCCON2.SCH所设置的通道号码结束。

ADCCON2.SREF用于选择参考电压。

ADCCON2.SDIV位用来选择抽取率,抽取率的设置决定分辨率和完成一个转换所需要的时间。

ADCCON2.SCH设置转换序列的最后一个通道数

ADCCON3

单通道ADC转换通过写ADCCON3寄存器触发,转换立即开始。

除非一个转换序列已经正在进行,在这种情况下序列一完成,单个通道的ADC转换就会被执行。

除可以设置为按序列进行ADC转换之外,CC2530的ADC模块可以编程实现任何单个通道执行一个转换,包括温度传感器(14)和AVDD5/3(15)两个通道。

单通道ADC转换通过写ADCCON3寄存器触发,转换立即开始。除非一个转换序列已经正在进行,在这种情况下序列一完成,单个通道的ADC转换就会被执行。

4 ADC初始化配置

LED初始化

串口通信初始化

AD初始化

注意分辨率与精确度的区别

分辨率 分辨率由比特数决定,比如16位器件,则可以表示65536个独立的数字值,那么对于1bit而言,代表着最小的电平为 $ADC电压范围× \frac{1}{65536}$

精确度 是指对于给定模拟输入,实际数字输出与理论预期数字输出之间的接近度。

理论上精确度和分辨率相同,但由于实际中出现各种误差源,因而不能达到很高的精确度,比如只能16位器件只能提供12位精确度(有效数据),对于这种情况,4LSb(最低有效位)表示ADC中生成的随机噪声

电压计算公式 =ADC/精度*参考电压。

Value=(ADCH×256+ADCL)×3.3/8192。

ADC:把AD转换后得到的ADCL、ADCH做处理,将ADCL(低6位)放在低字节,ADCH(高8位)放在高字节。将一个uint16右移两位(最后两位没有用),即得到14位ADC。精度:根据所选位数,例如本任务位数选14位,精度=2^13=8192。

注意三个ADCCON1,2,3区别

首先通过ADCCON1寄存器将EOC标志清零。若为序列ADC转化则需要用到ADCCON2寄存器,若为单通道ADC转换则需要使用ADCCON3寄存器。通过这两个寄存器其一可以设置ADC转换的参考电压和通道的抽取率(精度)。若为ADCCON2寄存器还可以设置序列转换的范围,对于ADCCON3寄存器可以设置单个通道的转化。最后通过ADCCON1寄存器的STSEL位和ST位来启动ADC转换。

5 ADC使用方式

5.1 轮询方式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
while(1) {
if(ADCCON1>=0x80) { //ADCCON1.EOC,转换完毕判断
LED1 = 0; //转换完毕指示
LED2= 1; //打开数据处理指示灯
temp[1] = ADCL;
temp[0] = ADCH;
adc |= (uint)temp[1];
adc |= ( (uint) temp[0] )<<8;
adc>>=2; // ADCL[1:0]没用使用
num = adc*3.3/8192;//定参考电压为3.3V。14位分辨率
adcdata[1] = (char)(num)%10+48;
adcdata[3] = (char)(num*10)%10+48;
UartTX_Send_String(adcdata,6); //串口送数
LED2= 0; //完成数据处理
delay(30000);
InitialAD(); //启动下一次转换
}
}

5.2 中断方式

通过设置ADCCON3启动的单次ADC转换完成时才会产生中断。 (序列ADC转换完成不会产生中断)

1
2
3
4
5
6
7
8
9
10
11
12
13
#pragma vector = ADC_VECTOR
__interrupt void ADC_ISR(void) {
float num; char temp[2]; uint adc=0;
temp[1] = ADCL;
temp[0] = ADCH;
adc |= (uint)temp[1];
adc |= ( (uint) temp[0] )<<8;
adc>>=2; // ADCL[1:0]没用使用
num = adc*1.25/8192;//参考电压为1.25V,12位有效位
adcdata[1] = (char)(num)%10+48;
adcdata[3] = (char)(num*10)%10+48;
adcComplete1 = 1; //设置转换完成的全局变量
}

序列转换和单次转换的区别

Prev:
嵌入式系统(七)脉冲宽度调制
Next:
数据库系统(六)数据库规范