AnsweredAssumed Answered

ADC readings in KL27 take minutes to stabilize

Question asked by Robert Poor on Jan 15, 2017
Latest reply on Jan 20, 2017 by Robert Poor

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!

Outcomes