CC2530的ADC工作原理与应用
Posted 364.99°
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CC2530的ADC工作原理与应用相关的知识,希望对你有一定的参考价值。
1.A/D转换的基本工作原理
- 数字化: 将时间上连续变化的模拟量转化为脉冲有无的数字量(ADC)
- ADC: 数模转换器,将时间和幅值连续的模拟量转化为时间和幅值离散的数字量
- 过程: 采样、保持、量化、编码
常用ADC: 逐次逼近型、双积分型、∑-△型
A/D转换器的几个技术指标:
- 量程: ADC所能输入模拟信号的类型和电压范围(参考电压),信号类型包括单极性和双极性
- 转换位数: 量化过程中的量化位数n,A/D转换后的输出结果用n位二进制数表示
- 分辨率: ADC能够分辨的模拟信号最小变化量,分辨率 = 量程 / 2^n
- 转换时间: ADC完成一次完整的A/D转换所用时间,包括采样、保持、量化、编码的全过程
ADC的四个基本过程
采样、保持、量化、编码
例: 有一个温度测控系统,已知温度传感器在0到100度之间为线性输出,参考电压为5V,采用8为的A/D转换器,0度的时候,测的电压为1.8伏,100度的时候,测的电压为4.3伏。
问: 系统的分辨率是多少?采集到数据10010001,表示多大电压?温度是多少?
由于采用的是8位ADC,参考电压为5V,所以分辨率为:
5* 1/2^8= 5/256 = 0.0195V= 1.95mV (最小能分辨的电压,分辨率)
0.0195 * 40= 0.78度(最小能分辨的温度)
由于温度是线性变化,先求得斜率k,得到温度和电压的关系表达式:
k= (100- 0)/(4.3-1.8)=40,y = 40*(x-1.8) (x为采样得到的电压)
因为10010001B=91H= 145,所以0.0195* 145= 2.83V
温度: (2.83V- 1.8V)* 40= 41.2℃
2.CC2530的A/D转换模块
此ADC模块的主要特征:
- 可选取的抽取率,设置分辨率(7~12位)
- 8个独立的输入通道,可接收单端或差分信号
- 参考电压可选为内部单端、外部单端、外部差分或AVDD5
- 单通道转换结束可产生中断请求
- 序列转换结束可发出DMA触发
- 可将片内温度传感器作为输入
- 电池电压测量功能
3.ADC模块的信号输入
端口0引脚可以配置为ADC输入端,依次为AINO~AIN7
- 输入端可配置为单端输入或差分输入
- 差分输入对: AIN0~AIN1、AIN2 ~ AIN3、AIN4 ~ AIN5 、AIN6 ~ AIN7
- 片上温度传感器的输出也可以作为ADC的输入用于测量芯片的温度
- 可以将一个对应AVDD5/3的电压作为ADC的输入,实现电池电压检测
- 负电压和大于VDD的电压都不能用于P0这些引脚
- 单端电压输入AINO~ AIN7,以通道号码0~7表示
- 四个差分输入对则以通道号码8~11表示
- 温度传感器的通道号码为14
- AVDD5/3电压输入的通道号码为15
4.ADC相关的几个概念
- 序列ADC转换: 可以按序列进行多通道的ADC转换,并把结果通过DMA传送到存储器,而不需要CPU任何参与。
- 单通道ADC转换: 通过写ADCCON3寄存器触发单通道ADC转换,一旦寄存器被写入,转换立即开始
- 参考电压: 内部生成的电压、AVDD5引脚、适用于AIN7输入引脚的外部电压,或者适用于AIN6~ AIN7输入引脚的差分电压
- 转换结果:
4.1. 数字转换结果以二进制的补码形式表示
4.2. 对于单端,结果总是正的
4.3. 对于差分配置,两个引脚之间的差分被转换,可以是负数
4.4. 当ADCCON1.EOC设置为1时,数字转换结果可以读取
4.5. 转换结果总是驻留在ADCH和ADCL寄存器组合的MSB段中- 中断请求:
5.1. 通过写ADCCON3触发一个单通道转换完成时,将产生一个中断
5.2. 完成一个序列转换时,ADC将产 生一个DMA触发,而不产生中断- 三个控制寄存器: ADCCON1、ADCCON2、ADCCON3,用来配置ADC
- 两个数据寄存器: ADCL和ADCH,用来返回转换结果
5.1.案例——定时采集电压数据发送到上位机
要求:
将光照度传感器接到的Zigbee小模块上,每隔1秒以单通道的式采样一次该传 感器的电压值,并按照指定的格式将数据传送到上位机。上位机与CC2530的 串口0相连,系统时钟为16MHz,波特率为9600BPS, 发送数据采用查询的方式。数据帧有4个字节,格式如下:
0xFA (帧头) ADCH ADCL 0xAF (帧尾)
设计思路:
- 初始化定时器1,实现0.1秒定时
- 在定时中断函数中实现1秒定时
- 按照参数要求初始化串口0
- 设计字节数组发送函数
- 初始化ADC (单通道采集)
- 实现数据采集并发送到上位机
配置APCFG寄存器
- 当使用ADC时,端口0的引脚必须配置为ADC模拟输入
- 要配置一个端口0引脚为一个ADC输入,APCFG寄 存器中相应的位必须设置为1。这个寄存器的默认值是0,选择端口0为非模拟输入,即作为数字I/O端口
- 注意: APCFG寄存器的设置将覆盖POSEL的设置
- APCFG模拟I/O配置寄存器:
配置ADCCON3寄存器
- 单通道的ADC转换,只需要将控制字写入ADCCON3寄存器即可
- ADCCON3控制寄存器(单通道相关):
ADC初始化
- 对端口的功能进行选择
- 设置其传输方向
- 将端口设为模拟输入
ADC数据采集
- 将ADCIF标志位清0
- 配置ADCCON3寄存器,该寄存器一旦被写入,转换立即开始
- 等待ADCIF置1,标示转换完成
- 读取数据
代码:
#include "ioCC2530.h"
/*=============================定时器1初始化函数==============================*/
void Init_Timer1(){
T1CC0L = 0xd4; //设置最大计数值的低8位
T1CC0H = 0x30; //设置最大计数值的高8位
T1CCTL0 |= 0x04; //开启通道0的输出比较模式
T1IE = 1; //使能定时器1中断
T1OVFIM = 1; //使能定时器1溢出中断
EA = 1; //使能总中断
T1CTL = 0x0e; //分频系数是128,模模式
}
unsigned char count = 0;
unsigned char F_time = 0;
/*=============================定时器1服务函数================================*/
#pragma vector = T1_VECTOR
__interrupt void Timer1_Sevice(){
T1STAT &= ~0x01; //清除定时器1通道0中断标志
count++ ;
if(count == 10){ //定时1秒到
F_time = 1;
count = 0;
}
}
/*=============================UR0初始化函数==================================*/
void Init_Uart0(){
PERCFG = 0x00; //串口0的引脚映射到位置1,即PO_2和P0_3
P0SEL = 0x0C; //将PO_ 2和PO_ _3端口设置成外设功能
U0BAUD = 59; //16MHz的 系统时钟产生9600BPS的波特率
U0GCR = 9;
U0UCR |= 0x80; //禁止流控, 8位数据,清除缓冲器
U0CSR |= 0xCe; //选择UART模式,使能接收器
UTX0IF = 0; //清除TX发送中断标志
URX0IF = 0; //清除RX接收中断标志
URX0IE = 1; //使能URAT0的接收中断
EA = 1; //使能总中断
}
/*=============================UR0发送字符串函数==============================*/
void UR0SendString(unsigned char *str, unsigned char count){
while (count--){
U0DBUF = *str++; //将要发送的1字节数据写入U0DBUF
while(!UTX0IF); //等待TX中断怺志,即数据爰送完成
UTX0IF = 0;
}
}
/*=============================ADC初始化函数==================================*/
void Init_ADC0(){
P0SEL |= 0x01; //P0_0端口设置为外设功能
P0DIR &= ~0x01; //P0_0端口设置为输入端口
APCFG |= 0x01; //P0_0作为模拟I/0使用
}
unsigned char dat[4];
/*===========================读取ADC的数据====================================*/
void Get_ADC0_Value(){
ADCIF = 0;
//参考电圧迭拝AVDD5引脚,256抽取率,AIN0通道0
ADCCON3 = (0x80| 0x10| 0x00);
while(!ADCIF); //等待A/D装換完成
dat[0] = 0xaf;
dat[1] = ADCH; //读取ADC数据低位寄存器
dat[2] = ADCL; //读取ADC数据高位寄存器
dat[3] = 0xfa;
}
/*===========================main函数=========================================*/
void main(){
Init_Uart0();
Init_Timer1();
Init_ADC0();
while(1){
if(F_time == 1){ //定时1秒时间到
Get_ADC0_Value(); //进行A/D转换并读取数据
UR0SendString(dat,4); //向上位机发送数据
F_time = 0; //定时1秒标志清0
}
}
}
以上是关于CC2530的ADC工作原理与应用的主要内容,如果未能解决你的问题,请参考以下文章