My project needs to take ADC readings - not quickly, but at low power.
Summary: I'm observing ADC readings starting far lower than expected, then over a period of five minutes, climbing very slowly before stabilizing. I suspect I'm not configuring the ADC system properly.
My setup: I'm driving the ADC with a voltage divider with an output voltage of about 0.77V and effective impedance of about 3K. With the ADC configured with VREFL of 1.2V, I would expect the converted count to be 0.77/1.2 of full scale, or 65536 * (0.77/1.2) = 42052.
What I observe: When I first start up the system, I see readings of about 27000, and over a period of five minutes, the readings climb to about 37000 -- somewhat lower than expected. So there are two problems: the system takes a LONG time to stabilize, and I'm not sure the readings are accurate.
My code:
Here is the setup code. Note that adc_t is a structure that carries with it an ADC_type, a channel group and a channel configuration.
void _adcSetup(adc_t *adc) {
adc16_config_t adc16_config;
ADC16_GetDefaultConfig(&adc16_config);
adc16_config.resolution = kADC16_ResolutionSE16Bit;
adc16_config.enableLowPower = true;
adc16_config.longSampleMode = kADC16_LongSampleCycle16;
ADC16_Init(adc->_base, &adc16_config);
ADC16_EnableHardwareTrigger(adc->_base, false); /* Use software trigger */
assert(kStatus_Success == ADC16_DoAutoCalibration(adc->_base));
adc->_channel_config.enableInterruptOnConversionCompleted = false;
adc->_channel_config.enableDifferentialConversion = false;
}
Here's the code that takes a readings:
uint32_t adcRead(adc_t *adc) {
ADC16_SetChannelConfig(adc->_base,
adc->_channel_group,
&adc->_channel_config);
while (0U == (kADC16_ChannelConversionDoneFlag &
ADC16_GetChannelStatusFlags(adc->_base, adc->_channel_group))) {
}
uint32_t v = ADC16_GetChannelConversionValue(adc->_base, adc->_channel_group);
return v;
}
Additional information: I am running my system in VLPR mode with a system clock of 2Mhz. I measure the time spent inside adcRead() to be about 275 uSec. And (for what it's worth), I call adcRead() every 50 mSec or so.
Am I configuring the ADC properly? Or perhaps the problem is in the way I'm reading it? Or are my clocks improperly configured? I appreciate any suggestions in advance!