2018-10-12 07:10 AM
Hello.
I'm using STM32f030CC in which we have to use 2 ADC channels.
Following is the Initialization part.
ADC_InitTypeDef stADC_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB , ENABLE);
/********************* GPIO INITIALIZATION***************/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_0;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOB, &GPIO_InitStructure);
/********************* ADC1 INITIALIZATION***************/
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
/*ADC Deinit*/
ADC_DeInit(ADC1);
/*ADC Structure Initialization*/
ADC_StructInit(&stADC_InitStructure);
stADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
stADC_InitStructure.ADC_ContinuousConvMode = DISABLE;;
stADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
stADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
stADC_InitStructure.ADC_ScanDirection=ADC_ScanDirection_Upward;
ADC_Init(ADC1, &stADC_InitStructure);
/* Enable the ADC peripheral */
ADC_Cmd(ADC1, ENABLE);
/* Wait the ADRDY flag */
while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_ADRDY));
//while(ADC_GetCalibrationStatus(ADC1) == SET);
Now in the phantom loop we're continuously sampling the ADC channels sequentially as follows.
if(uiSamplingCount <= NO_OF_SAMPLES)
{
val1 = fnA();
val2 = fnB();
uiSamplingCount++;
}
else
{
uiSamplingCount=0;
/* Averaging the values along with calibration */
/* Print the values */
}
Definition for the above functions are as follows:
void fnA(void)
{
/* Configure channel */
ADC_ChannelConfig(ADC1, ADC_Channel_9, ADC_SampleTime_55_5Cycles);
/* Start the conversion */
ADC_StartOfConversion(ADC1);
/* Wait until conversion completion */
while(ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == RESET);
/* Get the conversion value */
return ADC_GetConversionValue(ADC1);
}
void fnB(void)
{
/* Configure channel */
ADC_ChannelConfig(ADC1, ADC_Channel_8, ADC_SampleTime_55_5Cycles);
/* Start the conversion */
ADC_StartOfConversion(ADC1);
/* Wait until conversion completion */
while(ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == RESET);
/* Get the conversion value */
return ADC_GetConversionValue(ADC1);
}
Now the issue is we're getting offset values when we use the above sequence.
Second test case:
We're reading only individual channel value and printing the same.
Output is proper.
Third test case:
fnB() is executed first and then fnA() ie Channel 8 first and then Channel 9.
In this case after 5 to 6 loops it stats giving proper values.
Fourth test case:
At a time we're either taking 1000 samples from Channel 8 or 1000 samples from Channel 9 with a delay of 4 secs in between them.
My question is, Is there a dependency between the channels we're using ?
Is there an issue of some settling time in ADC so some error in the sequence that we're missing?
Regards,
Aatif.
@Community member
@Community member
@Community member
@Pavel A.
@henry.dick
2018-10-12 07:59 AM
I don't understand why you initialize the ADC each time before taking a sample. This is waste of time and code space.
Ideally, you configure two channels at once including the calibration, and then trigger + read in a loop.
> My question is, Is there a dependency between the channels we're using ?
This depends.
The sampling time must correlate to the ADC input circuitry. In other words, the input must be able to fully charge/discharge the S&H capacitor in the configured sample time. Otherwise, you will experience a "bleeding" effect, i.e. channel values depend on the value (S&H charge) of the previous channel.
So, if there is any dependency, it is in your interface hardware and/or ADC configuration.
2018-10-12 08:26 AM
Can we please stop with this habit of calling out forum members in initial posts.
2018-10-13 05:42 AM
@Community member I guess this is done maybe because of the fact that the reply rate on ST's forum is less compared to other forums. Maybe. :)
2018-10-13 05:49 AM
@Community member
>I don't understand why you initialize the ADC each time before taking a sample.
I guess the initialization is done only once. By initialization did you mean this:
ADC_ChannelConfig(ADC1, ADC_Channel_9, ADC_SampleTime_55_5Cycles);
2018-10-13 03:30 PM
If providing support paid better I might care more?
I review things here, it's not necessary to flag posts
2018-10-14 11:14 PM
I have really trouble finding posts I viewed and participated hours or days ago.
The sorting criteria of the forum's "Latest" list is somehow a mystery, and there is no personalized view.
Up to now, I would not say the forum platform changed for the better.
> I guess the initialization is done only once. By initialization did you mean this: ...
Even if you call the fnA() and fnB() function only once, one of them is basically redundant.
You can configure the two pins and two channels at once.
2018-10-15 01:33 AM
Hello.
But if we don't write ADC_ChannelConfig(ADC1, ADC_Channel_8, ADC_SampleTime_55_5Cycles); and
ADC_ChannelConfig(ADC1, ADC_Channel_9, ADC_SampleTime_55_5Cycles); every time how can we known the return value after conversion is of which channel?
Regards,
Aatif.
2018-10-15 02:29 AM
I highly suggest to read the (whole) ADC section of the Reference Manual. It will answer your questions.