特多东西要学 ,分配时间不当,导致后期才开始苦练CC2530,开始把CC2530的功能逐个啃。 平时练习都是这么个习惯,先查看单片机数据手册的ADC相关部分,例程怎么设置寄存器,闭着眼睛写代码,逐步调试,我尝试着把例程的模块功能移植到我的项目工程。(失败) 尴尬的事情开始发生了 我TM直接使用完整的例程项目,得到的结果也不是正确的。(失败) 将时间上连续变化的模拟量转化为脉冲有无的数字 量,这一过程叫数字化,实现数字化的关键设备是ADC。 TI提供的CC2530的A/D转换位数是8,10,12,14, 但转换的实际有效位ENOB只有7,9,10,12(不包括: 符号位、最后1位精度损失位)。 数字转换结果可以获得,且结果总是驻留在ADCH和ADCL寄存器组合的MSB(高位)段 在此我们选用实际有效12位 我们这里以 光敏二极管 为例子,采集ADC引脚P0^0,12位精度 1.设置IO口 2.置参考电压,分辨率 通道 启动转换 1.判断是否转换完成 1. 例程项目(带错误) 2. 书本(带错误) 3. 博主(验证过程) 最后提一下本书好多错误基于CC2530-ADC采集特别坑
写篇缘由
博主是一个非常懒的人,能不关注就不用关注,哈哈哈哈。 参加职业技能大赛,而我是组里负责单片机部分,往年是只有CC2530这种单片机 。 而今年是有CC2530 +(新增的STM32的Lora和NB-iot)。
暴躁脾气的小哥
给定自己实现一个功能,Zigbee +光敏二极管 采集(ADC值 和 电压值)数据发送到串口。什么是ADC(简单讲 模拟量–> 数字量)
ADC:数模转换器,将时间和幅值连续的模拟量转化为时间和幅值离散的数字量,A/D转换一般要经过采样、保持、量化、编码4个过程。
CC2530的A/D转换位数(注意这里)
CC2530内部ADC各精度对应位(没问题)
下图是从CC2530的中文手册里截出来,细品,您细品,是不是数据手册表达得有点问题(红色部分是我修正的内容),
初始化ADC相关寄存器
P0^0 设置为 外设功能、输入引脚、模拟引脚
通道0 512抽取率(12位精度) 参考电压AVDD5(3.3V)void initial_AD() { //设置IO口 P0SEL|=(1<<0); //P0^0外设引脚 P0DIR&=~(1<<0); //P0^0为输入引脚 APCFG|=0x01; //P0^0模拟引脚 //ADCIF = 0; //清除中断标志位 //设置参考电压,分辨率 通道 启动转换 ADCCON3=0xB0; //1011 0000 通道0 512抽取率 参考电压AVDD5,3.3V }
功能部分
2.获取AD值
3.处理AD值处理AD部分
uint getTemperature(void){ unsigned int value; //存储AD值 AdcValue = 0; ADCCON3|=0x3E; // 使用1.25V内部电压,12位分辨率,AD源为:片内温度传感器 ADCCON1|=0x40; //开启单通道ADC while(!(ADCCON1&0x80)); //等待AD转换完成 value = ADCL >> 2; //ADCL寄存器低2位无效 value |= (((uint)ADCH) << 6); return value*0.0629-303.3; //根据AD值,计算出实际的温度 }
ADCL和ADCH都是8位,
按照上面算法计算12位分辨率得出 Value 的值是 2^13=8192 比正常值大了一倍。()
错误在 ADCL应该往右移3位,这里却少移1位,导致后面ADCH的位数只能整体向左挪一位。
可怕的是书本也是按照这种算法写,得出的值大一倍。
首先让光敏二极管尽量接近最大值,直接把光敏二极管短接了
从上串口调试助手中能看到,得出的值接近8192,实锤,上述算法是有误的。
/*************************************************************************************************/
下面开始更正错误
12位精度的ADC_H(7)和ADC_L(5)的高低位(橙色区域表示有效)
大家动手指头亲自数一下有效是哪几位。
处理方法:
低位:ADCL>>3 去掉低4位包括(精度损失位和无效位)
高位:( ( ADCH<<1 ) >>1 ) (稳起见去掉符号位)
串口助手中可以看出AD值在 2^12=4096之间 ,说明获取的AD值没问题,加上转换电压公式,可以精准算出当前测量的电压值。
完整项目代码#include "iocc2530.h" unsigned char AD_data[]="0000-->"; unsigned char V_data[]="00000"; unsigned int adcvalue=0; //ADC值 unsigned int result=0; //电压值 /**********************/ void uart_senString(unsigned char *str); //发送字符串 void uart_senbit(unsigned char bit); //发送字符 void delay(unsigned int tt); void uart_init(); void Timeinit(); void initial_AD(); /**********************/ void main() { CLKCONCMD &=~0x40; //切换系统时钟源为32M晶振 while(CLKCONSTA & 0x40);//等待32M外部晶振稳定 CLKCONCMD &=~0x47; //设置系统主时钟频率为32M Timeinit(); //初始化定时器 uart_init(); //初始化串口 initial_AD(); //初始化AD while(1) { while(!(ADCCON1&0x80));//等待转换完成 //获取AD值 adcvalue=ADCL>>3; adcvalue|=(unsigned int)(ADCH<<1>>1) <<5; AD_data[0]=adcvalue/1000%10+0x30; AD_data[1]=adcvalue/100%10+0x30; AD_data[2]=adcvalue/10%10+0x30; AD_data[3]=adcvalue%10+0x30; //获取电压值 result=33000*adcvalue/40950; //AD值转换成电压 V_data[0]=(result/1000%10)+0x30; V_data[1]='.'; V_data[2]=(result/100%10)+0x30; V_data[3]=(result/10%10)+0x30; V_data[4]=(result%10)+0x30; uart_senString("ADC值:"); uart_senString(AD_data); //ADC值发送到PC端 uart_senString("电压值:"); uart_senString(V_data); //电压值发送到PC端 uart_senString("rn"); delay(8000); delay(8000); ADCCON3=0xB0; //再次启动转换 } } //中断服务函数 #pragma vector=T1_VECTOR __interrupt void Time1() { T1STAT &= ~0x01; } //串口接收服务函数 #pragma vector=URX0_VECTOR __interrupt void uartIE() { } void initial_AD() { //设置IO口 P0SEL|=(1<<0); //外设功能 P0DIR&=~(1<<0); //输入 APCFG|=0x01; //配置模拟IO //设置参考电压,分辨率 通道 启动转换 ADCCON3=0xB0; //1011 0000 通道0 512抽取率 参考电压AVDD5(3.3V) } void Timeinit() { //系统晶振32M T1CC0H =0x61; T1CC0L =0xA8; //定时0.1秒 T1CTL =0x0E; //分频系数是128,模模式 T1CCTL0 |=0x04; //通道0比较模式 T1IE=1; //使能定时器中断 T1OVFIM=1; //使能定时器溢出中断 EA=1; //总中断使能 } void uart_init() { //初始化引脚 P0SEL |=0x0C; //串口外设 //设置串口波特率 U0BAUD =59; U0GCR =8; //设置串口控制器和串口通讯 U0UCR |=0x80; //清除和控制 U0CSR |=0xC0; //串口状态和使能 //清除中断标志位 URX0IF =0; UTX0IF =0; //使能中断 URX0IE =1; //串口接收中断 EA=1; } void uart_senbit(unsigned char bit) { U0DBUF=bit; while(!UTX0IF); UTX0IF=0; } void uart_senString(unsigned char *str) { while(*str !=' ') { uart_senbit(*str++); } } void delay(unsigned int tt) { while(tt--); while(tt--); while(tt--); while(tt--); }
本网页所有视频内容由 imoviebox边看边下-网页视频下载, iurlBox网页地址收藏管理器 下载并得到。
ImovieBox网页视频下载器 下载地址: ImovieBox网页视频下载器-最新版本下载
本文章由: imapbox邮箱云存储,邮箱网盘,ImageBox 图片批量下载器,网页图片批量下载专家,网页图片批量下载器,获取到文章图片,imoviebox网页视频批量下载器,下载视频内容,为您提供.
阅读和此文章类似的: 全球云计算