ZigBee CC2530 HalAdcRead ADC读取误差偏大

使用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读取误差偏大】ZigBee CC2530 HalAdcRead ADC读取误差偏大
文章图片

    推荐阅读