一、实验介绍
ADC 支持多达14 位的模拟数字转换,具有多达12 位的ENOB(有效数字位)。它包括一个模拟多路转换器,具有多达8 个各自可配置的通道;以及一个参考电压发生器。转换结果通过DMA 写入存储器。还具有若干运行模式。
ADC 的主要特性如下:
- 可选的抽取率,这也设置了分辨率(7 到12 位);
- 8 个独立的输入通道,可接受单端或差分信号;
- 参考电压可选为内部单端、外部单端、外部差分或AVDD5;
- 产生中断请求;
- 转换结束时的DMA 触发;
- 温度传感器输入;
- 电池测量功能。
二、实验目的
- 通过本实验了解CC2530 ADC的相关寄存器配置;
- 通过本实验了解CC2530的ADC单次采集功能的运用。
三、实验设备
3.1、硬件设备
- ZIGBEE开发板
- SmartRF04EB仿真器
- Micro-USB数据线
3.2、软件环境
- IAR Embedded Workbench for 8051集成开发环境
- 串口调试助手
四、实验原理
4.1、ADC输入
端口0引脚的信号可以用作ADC输入,这些端口引脚置指的是AIN0-AIN7。
可以把输入配置为单端输入或差分输入,片上温度传感器的输出可以作为ADC的输入,用于测量芯片温度。

ADC也叫模拟数字转换器,用于将模拟形式的连续信号转换为数字形式的离散信号,一个数字模拟转换器可以提供信号用于测量。
A/D转换一般要经过采样、保持、量化和编码。
将事件上连续变化的模拟量转化为有无脉冲的数字量,该过程称为数字化。
4.2、ADC其他操作
ADC转换序列:可以按序列进行多通道的ADC转换,并把结果通过DMA传送到传感器,且过程不需要CPU参与。
单通道ADC转换:通过配置ADCCON3寄存器触发单通道ADC转换,一旦写入寄存器,转换器立即开始。
参考电压:内部生成的电压、AVDD5引脚、适用于AIN7输入引脚的外部电压或适用于AIN6-AIN7输入引脚的差分电压。
转换结果:对于单端,结果总是正的。对于差分,两引脚之间的差分被转换,可以为负数。当ADCCON1的第7位设置为1时,可以获得数字转换结果,该结果驻留在ADCH和ADCL寄存器组合的MSB段中。
中断请求:通过配置ADCCON3触发一个单通道转换完成时,将产生一个中断。但完成一次序列转换时,是不会产生一个中断的。每完成一个序列转换,ADC将产生一个DMA触发,当完成一个单个转换,不产生DMA触发。
采样率:指芯片每秒采集信号的个数,2kHz/s指每秒采集2k个点。采样率越高,采集点越多,还原度越高。
分辨率:衡量ADC精度的一个指标,一般为8bit/s、16bit/s或24bit/s。当采集电压范围为0-3.3V时,16bit/s的ADC最小刻度为
3.3
2
16
≈
0.00005035
V
\frac{3.3}{2^{16}} \approx 0.00005035V
2163.3≈0.00005035V
更大的分辨率能采集 更小的电压值。
4.3、相关寄存器
ADCL和ADCH用于存放数字转换结果。

ADC有3个控制寄存器:ADCCON1、ADCCON2、ADCCON3,用于配置ADC和报告结果。
ADCCON1等待第7为是状态位,当转换结束时该位置1;当读取ADCH时该位置0。第6位用于启动一个转换序列,当该位为1和第5、4位为11且当前没有转换时,启动一个序列,当序列转换完成时该位置0。第3、2位用于选择哪个事件将启动一个新的转换序列。

ADCCON2寄存器控制序列如何进行。第7、6位用于选择参考电压,只有在没有转换运行时才能修改。第5、4位用于选择抽取率,只有在没有转换运行时才能进行修改。后4位用于序列通道选择。

ACDCON3寄存器控制单个转换的通道号码、参考电压和抽取率。单个转换在ADCCON3寄存器写入后将立即发生,或如果一个转换序列正在进行,该序列结束之后立即发生。

TR0寄存器的第0位用于连接温度传感器到SOC_ADC。

ATEST寄存器用于使能温度传感器。

五、实验演示
现在我们要实现的是读取片内温度传感器的温度值,并通过串口显示。
首先我们创建adc.c和adc.h文件,在adc.c文件里初始化片内温度传感器:
void sensor_init(void) //初始化片内温度传感器
{
clk32m_init(); //切换为32MHz时钟源
TR0 = 0x01; //连接温度传感器到SOC_ADC
ATEST = 0x01; //使能温度传感器
}
初始化完片内温度传感器后,再写一个温度数值获取函数:
float gettemperature(void)
{
uint16_t value;
ADCCON3 = 0x3E; //0011 1110 内部参考电压、512抽取率、温度传感器
ADCCON1 |= 0x30; //0011 0000 启动模式选择手动
ADCCON1 |= 0x40; //0100 0000 开始转换
while((ADCCON1 & 0x80) == 0); //1000 0000 等待转换结束
value = ADCL >> 4; //ADCL寄存器低2位无效
value |=(((uint16_t)ADCH)<<4);
return (value - 1367.5) / 4.5- 4; //根据AD值计算出实际芯片温度
}
在main.c内获取温度并每1s更新一次:
#include "iocc2530.h" //头文件
#include "headfile.h"
float temp;
char buf[20];
void main(void)
{
led_init();
clk32m_init();
uart0_init();
sensor_init();
while(1)
{
float sum = 0;
for(uint8_t i=0;i<64;i++)
{
sum += gettemperature(); //获取温度总和
}
temp = sum/64; //取平均温度值
memset(buf,0,sizeof(buf)); //将buf内写入长度为buf长度的0
sprintf(buf,"%.02f\n",temp); //将temp内容写入buf
uartsendstring(buf,sizeof(buf)); //发送字符串
delayms(1000);
}
}
#pragma vector = URX0_VECTOR
__interrupt void uart0_rx(void)
{
URX0IF = 0; //清除串口0接收标志位
while(UTX0IF == 0); //等待串口0发送完毕
UTX0IF = 0; //清除串口0发送标志位
}
插上Micro-USB线,打开串口调试助手,打开串口可以看到:

有疑问可以加入QQ群交流:324611467
1061

被折叠的 条评论
为什么被折叠?



