使用CC2530,以及TI提供的Z-Stack协议栈程序。
直接调用它协议栈里面的函数HalAdcRead,发现AD值读取出来误差很大,上下0.02V的波动(固定电压)。
感觉难以接受,然后就翻了它底层的程序。
有一个设置参考电压的地方感觉不对,修改了一下,误差基本在0.004V左右。
改动如下。
//adctemp &= ~(HAL_ADC_CHN_BITS | HAL_ADC_DEC_BITS | HAL_ADC_REF_BITS);
adctemp &= ~(HAL_ADC_CHN_BITS | HAL_ADC_DEC_BITS | HAL_ADC_REF_AVDD);
/**************************************************************************************************
* @fnHalAdcRead
*
* @briefRead the ADC based on given channel and resolution
*
* @paramchannel - channel where ADC will be read
* @paramresolution - the resolution of the value
*
* @return16 bit value of the ADC in offset binary format.
*
*Note that the ADC is "bipolar", which means the GND (0V) level is mid-scale.
*Note2: This function assumes that ADCCON3 contains the voltage reference.
**************************************************************************************************/
uint16 HalAdcRead (uint8 channel, uint8 resolution)
{
int16reading = 0;
#if (HAL_ADC == TRUE)uint8i, resbits;
uint8adctemp;
volatileuint8 tmp;
uint8adcChannel = 1;
uint8reference;
/* store the previously set reference voltage selection */
reference = ADCCON3 & HAL_ADC_REF_BITS;
/*
* 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_8:
resbits = HAL_ADC_DEC_064;
break;
case HAL_ADC_RESOLUTION_10:
resbits = HAL_ADC_DEC_128;
break;
case HAL_ADC_RESOLUTION_12:
resbits = HAL_ADC_DEC_256;
break;
case HAL_ADC_RESOLUTION_14:
default:
resbits = HAL_ADC_DEC_512;
break;
}/* read ADCL,ADCH to clear EOC */
tmp = ADCL;
tmp = ADCH;
/* Setup Sample */
adctemp = ADCCON3;
//adctemp &= ~(HAL_ADC_CHN_BITS | HAL_ADC_DEC_BITS | HAL_ADC_REF_BITS);
adctemp &= ~(HAL_ADC_CHN_BITS | HAL_ADC_DEC_BITS | HAL_ADC_REF_AVDD);
adctemp |= channel | resbits | (reference);
/* writing to this register starts the extra conversion */
ADCCON3 = adctemp;
/* 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_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;
}
#else
// unused arguments
(void) channel;
(void) resolution;
#endifreturn ((uint16)reading);
}
【ZigBee CC2530 HalAdcRead ADC读取误差偏大】
文章图片
推荐阅读
- stm32|基于STM32和freeRTOS智能门锁设计方案
- 日常分享|共享充电宝方案原理,具体部件组成以及主控MUC参数
- #|ARM裸机开发(汇编LED灯实验(I.MX6UL芯片))
- 物联网|从零开始开发物联网项目(8)——云服务器初体验
- 那些卖物联网卡起家的公司,为什么大都撑不过三年()
- 物联网|无线WIFI“信道”