【ZIGBEE(CC2530)学习】9-CC2530基础实验——ADC采集


在这里插入图片描述

一、实验介绍

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

  1. 可选的抽取率,这也设置了分辨率(7 到12 位);
  2. 8 个独立的输入通道,可接受单端或差分信号;
  3. 参考电压可选为内部单端、外部单端、外部差分或AVDD5;
  4. 产生中断请求;
  5. 转换结束时的DMA 触发;
  6. 温度传感器输入;
  7. 电池测量功能。

二、实验目的

  1. 通过本实验了解CC2530 ADC的相关寄存器配置;
  2. 通过本实验了解CC2530的ADC单次采集功能的运用。

三、实验设备

3.1、硬件设备

  1. ZIGBEE开发板
  2. SmartRF04EB仿真器
  3. Micro-USB数据线

3.2、软件环境

  1. IAR Embedded Workbench for 8051集成开发环境
  2. 串口调试助手

四、实验原理

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.30.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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值