CC2430 CC2530 AD转换分辨率之“争”

来源:互联网 发布:大数据医疗行业的挑战 编辑:程序博客网 时间:2024/05/05 06:13

http://blog.csdn.net/xukai871105/article/details/7318886


CC2430 CC2530 片内AD转换详解1

         本周五开始就开始学习CC2430的AD转换模块。看似简单,但是费了我休息日全部的时间。其中最严重的问题——这个片内的AD转换的分辨率到底是多少位,12位还是14位。

         开门见山:经过多次试验和查找的资料,我认为TI的数据手册是对的,最高分辨率为12位,分为4档 7位,9位,10位和12位。毫无疑问,CC2430/CC2530中的片内AD转换器采用simga-delta原理,和大多数的逐次比较式不同。

         下面我们来简单看看,各派是如何描述的,为什么会有这个分歧。

       1 数据手册

中文和英文的数据手册写的非常清楚,AD转换可以达到12位精度,可以分为4档,分别是7位,9位,10位,12位。

虽然数据手册写的非常清楚,但是也留给人一点悬念。第一,数据手册中出现了一个大家都比较陌生的抽取率,这个概念或许是sigma-delta类型AD所特有的。第二,有关ADCL和ADCH寄存器,其中ADCH位8位,全部使用;而ADCL使用了高6位,而低2位没有使用。所以ADC结果寄存器组成了一个14位有效的寄存器,这就给人很大的想象空间,到底这个AD的分辨率有多少!!!

       2 网上和图书资料

         学习CC2430就只有一本书,该书关于片内AD章节中,第一句话就提到AD转换为14位分辨率(见Zigbee技术实践教程  北航出版社 P157)。在本书的寄存器说明中,提到分辨率有关的设置时,是这样写的:

00:7比特

01:9比特

10:10比特

11:12比特

         在书中的ADCCON2和ADCCON3寄存器中可以看到。而英文手册中,却是写的抽取率,括号中写了分辨率。本书该部分由点含糊其次。书中提供了AD转换的相关代码,把这些寄存器的操作写成一组宏定义:代码是这样的:

// Resolution (decimation rate):

#define ADC_8_BIT           0x00     //  64 decimation rate

#define ADC_10_BIT          0x10     // 128 decimation rate

#define ADC_12_BIT          0x20     // 256 decimation rate

#define ADC_14_BIT          0x30     // 512 decimation rate

看宏定义的名称,我自然认为ADC的分辨率为8,10,12,14四个档位。

         再者,华中科技大学 刘志鹏同学写了一篇ZigBee ADC使用的文章,名为《Zigbee之旅(六):几个重要的CC2430基础实验——ADC单次采样》,文中也提到AD的分辨率为14位,而不是数据手册中的12位。

http://www.cnblogs.com/hustlzp/archive/2011/02/25/1962572.html

 

       3 和我一样的纠结者

         但是网上也有一些纠结于此问题的同仁。例如飞比论坛中的shamiexiaotan同学,他也在这个问题上纠结很久,发了几个帖子,最后写了关于《CC2530的AD重大发现》一文,里面描述了CC2530 ZigBee协议栈中代码和数据手册不符的情况。

http://www.feibit.com/forum.php?mod=viewthread&tid=3167

         国内有觉得有问题的,国外也有人觉得很迷惑。例如TI的官网论坛上,也有人提出例如这个问题。

http://e2e.ti.com/support/low_power_rf/f/155/t/15944.aspx

TI的工作人员的回复倒是干脆,也点破了大多数人的疑问。

我认为这句话的意思是这样的“根据测试的结果,CC2430的分辨率从14位降低为12位,但它还是那个ADC,这就是为什么它还是一个14bit的寄存器(测试的结果貌似和设计的初衷不相同,就是这个意思!)。无论ADC如何被使用,转换结果的高位总从ADCH寄存器的最高位开始保存。剩余的2位作为噪声,实际没有任何的作用。”

 

    总结

         1 TI的CC2430的片内AD转换采用sigma-delta原理,由于测试结果不能没有达到设计要求,所以TI把分辨率从14位调整至12位。(或许以前的说明书出现了14位分辨率的情况)。分辨率分为7位,9位,10位和12位。

         2 AD转换的结果采用补码的形式保存,所以若采用7位分辨率,可以得到的值范围在-64到63之间。

         2 AD转换的结果实行左对齐,而且该对齐方式不能选择。如果使用7位分辨率,结果为于ADCH寄存器的高7位。其他的分辨率以此类推。


http://www.feibit.com/forum.php?mod=viewthread&tid=3167


使用ADC有两种情况:
第一种是连续转换,此时需要配置ADCCON1和ADCCON2寄存器;
第二种是单次转换,此时只需要配置寄存器ADCCON3即可。
请初学者搞清楚哈,单次转换只需要配置寄存器ADCCON3就可以。
我今天实验的情况:
使用ADC测量单节干电池的电压。
选择的参考电压基准为:AVDD=3.3V,模拟通道选择通道0.
则初始化函数为:
static uint16 readV(uint8 channal,uint8 resolution)
{
          uint16 value ; 
          APCFG |= 1 << channal ; //注意这里是设置ADC输入通道!!
          ADCIF = 0 ;
         
          ADCCON3 = (HAL_ADC_REF_AVDD | resolution | channal) ;          
          while ( !ADCIF ) ;
          
          value = ADCL ;
          value |= ((uint16) ADCH) << 8 ;//这里注意一下
          
          if(channal == HAL_ADC_DEC_064)//7位分辨率
                    value >>= 9 ;
          else if(channal == HAL_ADC_DEC_128) //9位分辨率
                  value >>= 7 ;
          else if(channal == HAL_ADC_DEC_256) //10位分辨率
                 value >>= 6 ;
          else if(channal == HAL_ADC_DEC_512) //12位分辨率
                  value >>= 4;
          
          return value; 
}
使用如下方式调用该函数:
1        temp = readV(HAL_ADC_CHN_AIN0,HAL_ADC_DEC_256) ;//10位分辨率
2        _ltoa(temp,vdataformat.Test,16) ;
3        temp = (temp + (temp << 5) ) >> 6 ; 

4        Data[0] = (uint8)temp/10 + '0' ;
5        Data[1] = '.' ;
6        Data[2] = (uint8)temp%10 + '0' ;
第1行,选择模拟通道0,10位分辨率;
第2行,将读取到的AD转换值以十六进制的形式显示出来。
第3行,这是将读取到的值转换为实际的电压值。为了显示方便,将其扩大了10倍。
实际电压值 =  AD转换值 * 33 /1024    
注意这里是10位分辨率,同时将读取的电压值扩大了10倍数。
但是,经过一天半的测试我发现上述公式不行!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
后来发现AD转换值最大是0x3F,也就是说是6位,所以,果断修改上述公式,如下:
实际电压值 =  AD转换值 * 33 /64   
当然,没有人会傻到让个小51单片机去计算乘法和除法;
一般处理技巧是:将乘法转换为左移运算,除法转换为右移运算;
所以:推导过程如下:
实际电压值 =  AD转换值 * 33 /64   = (AD转换值 *32 + AD转换值)/ 64
          =  ((AD转换值 << 5 ) + AD转换值) >> 6 
呵呵,我敢说,有部分初学者肯定没用过上述方法,算上给大家个小技巧吧。
第4—6行,将数据显示出来,输出到串口上。
然后,我使用稳压电源,型号:TPR3003-3C,输出0---3.3V,然后输如到AD通道0,测试结果如下:



当然,需要说明的是,我买CC2530是散新的,所以,我怀疑片子确实存在问题!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
此外,对于TI这款芯片,感觉数据手册写的太烂了,一个内部参考电压,整个数据手册都没说过是多少,最后从网上看到貌似是1.25V,而CC2420内部的参考电压是1.15V,貌似是,现在不确定!!!
还有就是协议栈里的ADC驱动是完全照搬的CC2430吧,不相信的朋友可以查看一下,CC2530的ADC分辨率是7位、9位、10位和12位,但是协议栈里面的驱动如下:
switch (resolution)
  {
    case HAL_ADC_RESOLUTION_8:
      reading >>= 8;
      break;
    case HAL_ADC_RESOLUTION_10:
      reading >>= 6;
      break;
    case HAL_ADC_RESOLUTION_12:
      reading >>= 4;
      break;
    case HAL_ADC_RESOLUTION_14:
    default:
      reading >>= 2;
    break;
}
这绝对是恶心人,上述分辨率是CC2430的,貌似是,真让人寒心!!!


0 0
原创粉丝点击