微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 无线和射频 > TI蓝牙设计交流 > 关于CC2540芯片的内部ADC运行一段时间后,采集到的AD值会出现异常, 过度偏低的问题,求解答,谢谢!

关于CC2540芯片的内部ADC运行一段时间后,采集到的AD值会出现异常, 过度偏低的问题,求解答,谢谢!

时间:10-02 整理:3721RD 点击:

TI的工程师们:

     你们好!我使用蓝牙芯片CC2540搭载着ble 1.3.2协议栈,运行ADC程序,使用的是ble协议栈自带的ADC库函数,可是为什么运行一段时间后,我用CC-Debugger调试器调试,看到读取到的ADC数值偏低很多,完全不正常,求解答:谢谢!

下面是我的ADC采集程序的部分源代码:

// Configure ADC and perform a read
HalAdcSetReference( HAL_ADC_REF_125V );
adc = HalAdcRead( battServiceAdcCh, HAL_ADC_RESOLUTION_12 );

备注:我在这里监测adc变量的值,运行长期一段时间后,特别的低。

HalAdcRead内部的函数原型:

/* Resolution */
#define HAL_ADC_RESOLUTION_7 0x01
#define HAL_ADC_RESOLUTION_9 0x02
#define HAL_ADC_RESOLUTION_10 0x03
#define HAL_ADC_RESOLUTION_12 0x04

备注:红色凸出部分和ble协议栈自带的不太一样,我修改了一下。

uint16 HalAdcRead (uint8 channel, uint8 resolution)
{
int16 reading = 0;

#if (HAL_ADC == TRUE)
uint8 i, resbits;
uint8 adcChannel = 1;

/*
* If Analog input channel is AIN0..AIN7, make sure corresponing P0 I/O pin is enabled. The code
* does NOT disable the pin at the end of this function. I think it is better to leave the pin
* enabled because the results will be more accurate. Because of the inherent capacitance on the
* pin, it takes time for the voltage on the pin to charge up to its steady-state level. If
* HalAdcRead() has to turn on the pin for every conversion, the results may show a lower voltage
* than actuality because the pin did not have time to fully charge.
*/
if (channel < 8)
{
for (i=0; i < channel; i++)
{
adcChannel <<= 1;
}
}

/* Enable channel */
ADCCFG |= adcChannel;

/* Convert resolution to decimation rate */
switch (resolution)
{
case HAL_ADC_RESOLUTION_7:
resbits = HAL_ADC_DEC_064;
break;
case HAL_ADC_RESOLUTION_9:
resbits = HAL_ADC_DEC_128;
break;
case HAL_ADC_RESOLUTION_10:
resbits = HAL_ADC_DEC_256;
break;
case HAL_ADC_RESOLUTION_12:
default:
resbits = HAL_ADC_DEC_512;
break;
}

/* writing to this register starts the extra conversion */
ADCCON3 = channel | resbits | adcRef;

/* ADCCON1.ST =1 Trigger */
ADCCON1 |= HAL_ADC_STSEL_ST;

/* Starts Conversion */
ADCCON1 |= HAL_ADC_START;

/* Wait for the conversion to be done */
while (!(ADCCON1 & HAL_ADC_EOC));

/* Disable channel after done conversion */
ADCCFG &= (adcChannel ^ 0xFF);

/* Read the result */
reading = (int16) (ADCL);
reading |= (int16) (ADCH << 8);

/* Treat small negative as 0 */
if (reading < 0)
reading = 0;

switch (resolution)
{
case HAL_ADC_RESOLUTION_7:
reading >>= 8;
break;
case HAL_ADC_RESOLUTION_9:
reading >>= 6;
break;
case HAL_ADC_RESOLUTION_10:
reading >>= 4;
break;
case HAL_ADC_RESOLUTION_12:
default:
reading >>= 2;
break;
}
#else
// unused arguments
(void) channel;
(void) resolution;
#endif

reading = ADCL>>4;                         //2014-03-27 修订了ADC读取函数中的BUG部分
reading |= (((uint16)ADCH) << 4);
reading = (reading > 0 ? reading : 0);
if(reading & 0x0800)reading = 0x00;

return ((uint16)reading);
}

红色突出部分,为我修订的14位分辨率(12位精度,有效位)的数据提取,正常情况下运用换算电压公式:

Voltage=(adc/2048)*1.25V 算出来的电压值和万用表测试出来的一样,但是不知道为什么当内部ADC运行一段时间后,会出来采集到的ADC数值偏低,换算出的电压也和实际测试的不一样,偏差好大。

求TI的工程师和各位高手们帮我解答下,急需解决方法,谢谢!

我说下自己遇到的情况吧。用ADC采集电阻分压后的数值,按照参考电压计算得到的电压值会比直接用万用表测量的电压值小。后来考虑了一下,想到万用表的内阻非常大,基本上不分流,对测量的电压没有影响。查询CC2540的数据手册,发现其ADC输入电阻只有197k,比万用表的内阻小很多,说明用CC2540的ADC测量电压时它的内阻要在考虑范围内,特别是分压电阻和197K接近时最为明显。下面两张图片是仿真的实例

第一张图片是用万用表测量的电压

第二张是考虑ADC内阻后测量的电压,很明显偏小了

 

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top