We are running a survey to help us improve the experience for all of our members. If you see the survey appear, please take the time to tell us about your experience if you can.
Hi
I am currently having a issue about ADC conversion because I always get the first wrong ADC sample but get correct reading after second try. I assume it is reading dummy data.
Now I tried to read three channels starting from channel 0 to channel 2 respectively at first try and second try.
I measured the voltage signal on each channel and know what to expect from ADC channel from zero to two. I obtained incorrect readings.
Here is my extracted code:
// 1st Try // Channel 0 ADC_vConfConv(ADC_FIXED, ADC_ANA_0); ADC_vStartConv(); while(ADC_ubBusy()); ReturnedADC = ADC_DAT & 0x0FFC; adc_result[ADC_ANA_0] = _iror_(ReturnedADC,2); First_Try_Channel[0]=adc_result[ADC_ANA_0]; // Channel 1 ADC_vConfConv(ADC_FIXED, ADC_ANA_1); ADC_vStartConv(); while(ADC_ubBusy()); ReturnedADC = ADC_DAT & 0x0FFC; adc_result[ADC_ANA_1] = _iror_(ReturnedADC,2); First_Try_Channel[1]=adc_result[ADC_ANA_1]; // Channel 2 ADC_vConfConv(ADC_FIXED, ADC_ANA_2); ADC_vStartConv(); while(ADC_ubBusy()); ReturnedADC = ADC_DAT & 0x0FFC; adc_result[ADC_ANA_2] = _iror_(ReturnedADC,2); First_Try_Channel[2]=adc_result[ADC_ANA_2]; // 2nd Try // Channel 0 ADC_vConfConv(ADC_FIXED, ADC_ANA_0); ADC_vStartConv(); while(ADC_ubBusy()); ReturnedADC = ADC_DAT & 0x0FFC; adc_result[ADC_ANA_0] = _iror_(ReturnedADC,2); Second_Try_Channel[0]=adc_result[ADC_ANA_0]; // Channel 1 ADC_vConfConv(ADC_FIXED, ADC_ANA_1); ADC_vStartConv(); while(ADC_ubBusy()); ReturnedADC = ADC_DAT & 0x0FFC; adc_result[ADC_ANA_1] = _iror_(ReturnedADC,2); Second_Try_Channel[1]=adc_result[ADC_ANA_1]; // Channel 2 ADC_vConfConv(ADC_FIXED, ADC_ANA_2); ADC_vStartConv(); while(ADC_ubBusy()); ReturnedADC = ADC_DAT & 0x0FFC; adc_result[ADC_ANA_2] = _iror_(ReturnedADC,2); Second_Try_Channel[2]=adc_result[ADC_ANA_2];
Is there summat wrong with my snippet code?
Regards
RC
Hallo!
What is inside you magic functions and what ADC mode are you using? In some cases there is noting bad to get what you got. Please refer to C167 User Manual, ADC section, to learn more about it. E.g., as I can interpret an illustration in there, in Auto Scan Convertion Mode example, you will have "garbage" for the very first convertion output (there is an effective shift of samples). It is not visible from the snippets how do you program the ADC. E.g., even when I use single channel mode I use "clean-up" code as shown below t obe on safe side.
static WORD iadc_get_average(int ch, int n, int ms) { long s= 0L; int i, x; // clean-it ;-) ADCON= 0xF080 + ch; // start new conversion on channel 'ch' so it pre-set while (ADBSY); // wait for conversion to finish x= ADDAT & 0x3FF; // sample for(i= 0; i< n; i++) { IAdcDelay(ms); ADCON= 0xF080 + ch; while (ADBSY); x= ADDAT & 0x3FF; // sample s+= x; }; return (WORD)((((float)s)/((float)n)) + 0.5); }
As I can imagine for auto-scan convertion mode where multiple number of channels participate, this behavior of ADC is OK. It is because when you start internal ADC convertion routine for the very first time you CAN NOT yet communicate to the chip which channel HAD to be set in its pre-history ;-)
I.e., launching the ADC starting from channel A, you ask ADC to convert previously latched channel X and as soon as initiated conversion done, you will get answer for a previously multiplexed channel X which is a 'garbage'. Correct sequence you expecting for, will appear with one sample shift (at least for scan mode).
P.S. Can somebody prove this understanding is incorrect, i.e. ADC should yield the first sample correctly under any circumstances?
Regards, Nikolay.
If you are using an XC16x device then if is recommended not to used the ADBSY bit (Sorry DAvE).
ADC_X.H1 Polling of Bit ADBSY After an A/D conversion is started (standard conversion by setting bit ADST = 1, injected conversion by setting ADCRQ = 1), flag ADBSY is set 5 clock cycles later. When polling for the end of a conversion, it is therefore recommended to check e.g. the interrupt request flags ADC_CIC_IR (for standard conversions) or ADC_EIC_IR (for injected conversions) instead of ADBSY.
Meaning you read it before it was actually converted.