- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi everyone,
I'm running into an issue on my Cy8C5468LTI-LP026 when first starting the ADC component.
I typically keep an array of ADC readings for temperature in my code and use it to generate a rolling average. In order to do this, when I first start up, I need to populate the array with initial values. I do so with the following functions:
#define ADC_NUM_SAMPLES 16
/* ADC_Read
* - Reads and returns a single reading from the ADC
*/
static uint16_t ADC_Read(void){
ADC_SAR_StartConvert();
while (ADC_SAR_IsEndConversion(ADC_SAR_RETURN_STATUS));
return ADC_SAR_GetResult16();
}
/* Sample_Temperature
* - Takes a single ADC read and places it into the next position in the ADC_Vals array
*/
static void Sample_Temperature (void){
static uint8_t sample_pos = 0;
uint16_t adc_val = ADC_Read();
/*ignore obviously faulty readings (T > 180C)*/
if (adc_val > ADC_TEMP_FAULT_COUNT){
adc_val = 0;
}
ADC_Vals[sample_pos++] = adc_val;
if (sample_pos >= ADC_NUM_SAMPLES){
sample_pos = 0;
}
}
/* Init_Temperature
* - Populates ADC Array and Average Temperature global with starting values
*/
void Init_Temperature (void){
uint8_t i;
ADC_SAR_Start();
for(i = 0; i < ADC_NUM_SAMPLES; i++){
Sample_Temperature();
}
g_TemperatureAvg = Get_Temp_Avg();
}
What I find here, is when I run Init_Temperature in my initialization, my ADC_Vals array ends up with elements 0-4 being zero, with valid readings starting at element 5. Does anyone know what's occurring here? I tried putting a delay (10mS) between starting the component and beginning to take readings, but that didn't seem to have any effect.
I have found a workaround, which is if i simply drop a second for() loop into Init_Temperature after the first one in order to populate the ADC_Vals array again, I have no issues. Reads after those initial 5 after starting the component don't seem to have a problem. So I have a workaround, but I'd like to know why it's behaving as it is.
Component is configured as follows:
Any thoughts or suggestions are appreciated.
Thanks!
Solved! Go to Solution.
- Tags:
- sar adc
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Firmware issue, change ADC_Read() function as follow can fix the issue.
ADC_SAR_IsEndConversion() API returns 0 when ADC is still calculating the last result, returns 1 only when last conversion is complete.
static uint16_t ADC_Read(void)
{
ADC_SAR_StartConvert();
while (!ADC_SAR_IsEndConversion(ADC_SAR_RETURN_STATUS));
return ADC_SAR_GetResult16();
}
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Firmware issue, change ADC_Read() function as follow can fix the issue.
ADC_SAR_IsEndConversion() API returns 0 when ADC is still calculating the last result, returns 1 only when last conversion is complete.
static uint16_t ADC_Read(void)
{
ADC_SAR_StartConvert();
while (!ADC_SAR_IsEndConversion(ADC_SAR_RETURN_STATUS));
return ADC_SAR_GetResult16();
}
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
It's always something really glaringly obvious in hindsight isn't it...
Can't believe I didn't catch that. Sometimes a 2nd pair of eyes is all it takes
Follow-up question: If I'm in free-running mode as I am here, presumably those five '0' values I get are waiting for the first conversion to finish. Since all my readings past that were fine, does that mean I would only need to worry about waiting for the conversion when I'm populating my values array at the beginning of application execution?
Past that point I'm only calling ADC_Read at a rate of about 1Hz. After that initial population of the ADC values array there should basically always be a result ready and waiting in the ADC results buffer by the time my next call of ADC_Read(), correct?
Thank You!