专栏首页w候人兮猗的博客CC2530基础实验五 ADC转换实验

CC2530基础实验五 ADC转换实验

####一、任务分析

编写程序实现实验板测定芯片外部光敏传感器的电压,通过串口发送电压值。实验板安装上光线传感器,光线的强弱转换成电压的高低,经ADC转换以后通过串口将电压值发送给PC,可以通过串口调试软件读取电压值。每发送一次电压值的字符串消息,LED1闪亮一次。具体工作方式如下:

①通电后LED1熄灭。 ②UART0初始化。 ③设置ADC。 ④LED1点亮。 ⑤开启单通道ADC。 ⑥ADC对通道0进行模数转换测量电压。 ⑦发送字符串“光照传感器电压值”与测量电压值。 ⑧LED1熄灭。 ⑨延时一段时间,延时时间可以设置为3秒。 ⑩返回步骤④循环执行。

1.电信号的形式与转换 信息是指客观事物属性和相互联系特性的表征,它反映了客观事物的存在形式和运动状态。表示信息的形式可以是数值、文字、图形、声音、图像以及动画等。信号是信息的载体,是运载信息的工具,信号可以是光信号、声音信号、电信号。电话网络中的电流就是一种电信号,人们可以将电信号经过发送、接收以及各种变换,传递着双方要表达的信息。数据是把事件的属性规范化以后的表现形式,它能被识别,可以被描述,是各种事物的定量或定性的记录。信号数据可以表示任何信息,如文字、符号、语音、图像、视频等等。 从电信号的表现形式上,可以分为模拟信号和数字信号。

(1)模拟信号 模拟信号是指用连续变化的物理量所表达的信息,如温度、湿度、压力、长度、电流、电压等等,我们通常又把模拟信号称为连续信号,它在一定的时间范围内可以有无限多个不同的取值。 (2)数字信号 数字信号指自变量是离散的、因变量也是离散的信号,这种信号的自变量用整数表示,因变量用有限数字中的一个数字来表示,在计算机中,数字信号的大小常用有限位的二进制数表示。由于数字信号是用两种物理状态来表示0和1的,故其抵抗材料本身干扰和 和环境干扰的能力都比模拟信号强很多;在现代技术的信号处理中,数字信号发挥的作用越来越大,几乎复杂的信号处理都离不开数字信号,只要能把解决问题的方法用数学公式表示,就能用计算机来处理代表物理量的数字信号。 (3)模拟/数字转换 模拟/数字转换通常简写为ADC,是将输入的模拟信号转换为数字信号。各种被测控的物理量(如:速度、压力、温度、光照强度、磁场等)是一些连续变化的物理量,传感器将这些物理量转换成与之相对应的电压和电流就是模拟信号。单片机系统只能接收数字信号,要处理这些信号就必须把他们转换成数字信号。模拟/数字转换是数字测控系统中必须的信号转换。

2.CC2530的ADC模块 CC2530的ADC模块支持最高14位二进制的模拟数字转换,具有12位的有效数据位。它包括一个模拟多路转换器,具有8个各自可配置的通道;以及一个参考电压发生器。转换结果通过DMA写入存储器,还具有多种运行模式。ADC模块结构如图6-1所示。 CC2530的ADC模块有如下主要特征:

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

3.ADC的工作模式

(1)ADC模块的输入 对于CC2530的ADC模块,端口P0引脚可以配置为ADC输入端,依次为AIN0~AIN7。可以把输入配置为单端或差分输入。在选择差分输入的情况下,差分输入包括输入对AIN0-AIN1、AIN2-AIN3、AIN4-AIN5和AIN6-AIN7。除了输入引脚AIN0-AIN7,片上温度传感器的输出也可以选择作为ADC的输入用于温度测量;还可以输入一个对应AVDD5/3的电压作为一个ADC输入,在应用中这个输入可以实现一个电池电压监测器的功能。特别提醒,负电压和大于VDD(未调节电压) 的电压都不能用于这些引脚。它们之间的转换结果是在差分模式下每对输入端之间的电压差值。 8位模拟量输入来自I/O引脚,不必通过编程将这些引脚变为模拟输入,但是,当相应的模拟输入端在APCFG寄存器中被禁用时,此通道将被跳过。当使用差分输入时,相应的两个引脚都必须在APCFG寄存器中设置为模拟输入引脚。APCFG寄存器如表6-1所示。 (2)序列ADC转换与单通道ADC转换 CC2530的ADC模块可以按序列进行多通道的ADC转换,并把结果通过DMA传送到存储器,而不需要CPU任何参与。 转换序列可以由APCFG寄存器设置,八位模拟输入来自I/O引脚,不必经过编程变为模拟输入。如果一个通道是模拟I/O输入,它就是序列的一个通道,如果相应的模拟输入在APCFG中禁用,那么此I/O通道将被跳过。当使用差分输入,处于差分对的两个引脚都必须在APCFG寄存器中设置为模拟输入引脚。 寄存器位ADCCON2.SCH用于定义一个ADC转换序列。如果ADCCON2.SCH设置为一个小于8的值,ADC转换序列包括从0通道开始,直到并包括ADCCON2.SCH所设置的通道号码。当ADCCON2.SCH设置为一个在8和12之间的值,转换序列包括从通道8开始差分输入,到ADCCON2.SCH所设置的通道号码结束。 除可以设置为按序列进行ADC转换之外,CC2530的ADC模块可以编程实现任何单个通道执行一个转换,包括温度传感器(14)和AVDD5/3(15)两个通道。单通道ADC转换通过写ADCCON3寄存器触发,转换立即开始。除非一个转换序列已经正在进行,在这种情况下序列一完成,单个通道的ADC转换就会被执行。

####二、初始化 1、定义结果变量; unsigned long value; //无符号long类型 2、ADC初始化 APCFG |= 1; //模拟 I/O 使能 P0SEL |= 0X01; //片上外设 P0DIR &= ~0X01; //设置输入模式 ADCIF = 0; //ADC中断标志位 3、参考电压、分辨率、序列通道选择(ADCCON2/ADCCON3) ADCCON3 = 0X90; //AVDD5引脚;9位分辨率; 3、采用基准电压 acdd5: 3.3v,通道0, 启动 AD 转换 ADCCON3 = (0x80 | 0x10 | 0x00); 4、等待ADC转换结束 while(!ADCIF); 5、得到的数据放到变量value 中 value = ADCH; value = value << 8; value |= ADCL; value = value*330; //电压值 = (value * 3.3) / 32768 value = value >>15; // value * 330 是为了后面处理数据所以多乘 100 6、返回value值 unsigned short 类型 return value;

ADC数据处理(光电传感器)

buf[0] = val / 100 + ‘0’; buf[1] = ‘.’; buf[2] = val / 10 % 10 + ‘0’; buf[3] = val % 10 + ‘0’; buf[4] = ‘V’; buf[5] = ‘\n’;

寄存器

ADCCON1
    选择ADC的启动模式和开启AD转换
    例如:设置ADC的启动模式为手动,并开启AD转换
      ADCCON1 |= 0X30;   //选择ADC的启动模式为手动
      ADCCON1 |= 0X40;   //开启AD转换

ADCCON2 选择内部参考电压;分辨率;多通道选择 与ADCCON3的区别是单/多通道的选择,其他配置相同。

ADCCON3
选择内部参考电压;分辨率;单通道选择
与ADCCON3的区别是单/多通道的选择,其他配置相同。
例如:选择内部参考电压;12位分辨率;对片内温度传感器采样
  ADCCON3 = 0X3E;
ADCL、ADCH
注意:低8位的0、1位一直为0;

APCFG

ADCIF ADC中断标志

###代码实现 /* 包含头文件 */ #include “ioCC2530.h” #include <string.h>

#define LED1 P1_0     // P1_0定义为P1_0  led灯端口
#define uint16 unsigned short
#define uint32 unsigned long
#define uint unsigned int

unsigned int flag,counter=0; //统计溢出次数
unsigned char s[8];//定义一个数组大小为8

void InitLED()
{
    P1SEL&=~0X01;          //P1_0设置为普通的IO口 1111 1110
    P1DIR |= 0x01;              //配置P1_0的方向为输出
    LED1=0;
}

void adc_Init(void)
{
    APCFG  |=1;
    P0SEL  |= 0x01; 
    P0DIR  &= ~0x01;    
}
/************************************************************
* 名称       get_adc
* 功能       读取ADC通道0电压值
* 入口参数   无
* 出口参数   16位电压值,分辨率为10mV
***************获取ADC通道0电压值************************/
uint16 get_adc(void)
{
    uint32 value;
    ADCIF = 0;   //清ADC 中断标志
    //采用基准电压avdd5:3.3V,通道0,启动AD转化
    ADCCON3 = (0x80 | 0x10 | 0x00);
    while ( !ADCIF )
    {
        ;  //等待AD转化结束
    }
    value = ADCH;
    value = value<< 8;
    value |= ADCL;
    // AD值转化成电压值
    // 0 表示 0V ,32768 表示 3.3V
    // 电压值 = (value*3.3)/32768 (V)
    value = (value * 330);
    value = value >> 15;   // 除以32768
    // 返回分辨率为0.01V的电压值
    return (uint16)value;
}
/**********串口通信初始化************************/
void initUART0(void)
{
    PERCFG = 0x00;  
    P0SEL = 0x3c;   
    U0CSR |= 0x80;
    U0BAUD = 216;
    U0GCR = 10;
    U0UCR |= 0x80;
    UTX0IF = 0;  // 清零UART0 TX中断标志
    EA = 1;   //使能全局中断
}

/*************************************************
* 函数名称:inittTimer1
* 功    能:初始化定时器T1控制状态寄存器
******************定时器初始化*****************************/
void inittTimer1()
{
    CLKCONCMD &= 0x80;   //时钟速度设置为32MHz
    T1CTL = 0x0E;    // 配置128分频,模比较计数工作模式,并开始运行
    T1CCTL0 |= 0x04;  //设定timer1通道0比较模式
    T1CC0L =50000 & 0xFF;    // 把50000的低8位写入T1CC0L
    T1CC0H = ((50000 & 0xFF00) >> 8); //把50000的高8位写入T1CC0H

    T1IF=0;           //清除timer1中断标志(同IRCON &= ~0x02)
    T1STAT &= ~0x01;  //清除通道0中断标志

    TIMIF &= ~0x40;  //不产生定时器1的溢出中断
    //定时器1的通道0的中断使能T1CCTL0.IM默认使能
    IEN1 |= 0x02;    //使能定时器1的中断
    EA = 1;        //使能全局中断
}
/***********************************************************
* 函数名称:UART0SendByte
* 功    能:UART0发送一个字节
* 入口参数:c
* 出口参数:无
* 返 回 值:无
************************************************************/
void UART0SendByte(unsigned char c)
{
    U0DBUF = c;     // 将要发送的1字节数据写入U0DBUF
    while (!UTX0IF) ;  // 等待TX中断标志,即U0DBUF就绪
    UTX0IF = 0;       // 清零TX中断标志
}

/**************************************************************
* 函数名称:UART0SendString
* 功    能:UART0发送一个字符串
* 入口参数:*str
* 出口参数:无
* 返 回 值:无
**********************************************************/
void UART0SendString(unsigned char *str)
{
    while(*str != '\0')
    {
        UART0SendByte(*str++);   // 发送一字节
    }
}

/**************获取电压值并处理数据******************/
void Get_val()
{
    uint16 sensor_val;
    sensor_val=get_adc();
    s[0]=sensor_val/100+'0';
    s[1]='.';
    s[2]=sensor_val/10%10+'0';
    s[3]=sensor_val%10+'0';
    s[4]='V';
    s[5]='\n';
    s[6]='\0';
}
/******************************************
* 功    能:定时器T1中断服务子程序
************************************/
#pragma vector = T1_VECTOR //中断服务子程序
__interrupt void T1_ISR(void)
{
    EA = 0;   //禁止全局中断
    counter++;
    T1STAT &= ~0x01;  //清除通道0中断标志
    EA = 1;   //使能全局中断
}
/******************************************
* 函数名称:main
* 功    能:main函数入口
* 入口参数:无
* 出口参数:无
* 返 回 值:无
**************************************************/
void main(void)
{
    InitLED();
    inittTimer1();  //初始化Timer1
    initUART0();  // UART0初始化
        adc_Init(); // ADC初始化
    while(1)
    {
        if(counter>=15)     //定时器每0.2S溢出中断计次
           {
            counter=0;       //清标志位
            LED1 = 1;    //指示灯点亮
            Get_val();
            UART0SendString("光照传感器电压值  ");
            UART0SendString(s); 
            LED1 = 0;    //指示灯熄灭
            }
    }
}

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • CC2530基础实验三 定时器

    ####一、任务要求 使用CC2530单片机内部定时/计数器来控制LED1进行周期性闪烁,具体闪烁效果要求如下:

    w候人兮猗
  • CC2530基础实验之四通道模拟量值采集

    w候人兮猗
  • CC2530基础实验之采集模拟量传感器值

    w候人兮猗
  • Leetcode-Easy 977. Squares of a Sorted Array

    假设有两个指针,分别从头和从尾向中间移动,然后比较左右两个值的绝对值大小,绝对值大的将平方和添加到最左边,一直到两个指针相遇。

    致Great
  • [置顶] 《Python机器学习算法》勘误

    本书在出版的过程中已经经过详细的检查,但是大小问题依旧存在,感谢各位细心的读者为本书指出的错误。 第34页的错误在Python2.7.9版本上不会报错。 第1...

    zhaozhiyong
  • 解决你困扰已久的台式机无线WiFi网卡断流、高PING、丢包的问题

    最近组装了一台台式机给自己用,因为家里没有布置网线接口,而路由器又在客厅,所以在淘宝买了个高通的无线网卡,但是买回来之后总是时不时网卡出现无网络连接的情况,特别...

    lollipop72
  • java采坑之路

    为什么n3== n4 是false呢?由于包装类的缓存机制。包装类的比较用equals去判断。最推荐的还是用工具类去判断。例如上面的列子如果n3=null的话n...

    java金融
  • 在项目中随手把haseMap改成了currenHaseMap差点被公司给开除了。

    所以涉及金钱的计算一定不要使用float和double。使用BigDecimal并且一定要用String来构造。 上面的列子我们可以这样来初始化 new Big...

    java金融
  • web基础(回顾)

    <?php //chr() 函数从指定的 ASCII 值返回字符。 for($i=32;$i<127;$i++){ echo chr($i); } /...

    wangxl
  • Zynga:披着游戏公司外衣的分析公司

    大数据文摘

扫码关注云+社区

领取腾讯云代金券