cancel
Showing results for 
Search instead for 
Did you mean: 

L412 ADC gets different results on consecutive reads

b.a.
Associate III

I am using STM32L412KBU and read in different ADC channels.

Now I see that the first read returns 23451, the second read immediately after returns 20338.

I use x16 OVS, hence the big numbers.

After the second read, values seem to become stable.

external circuit is as follows

 ba_0-1707466859583.png

ADC and pin config

 

 

    GPIO_InitStruct.Pin = LL_GPIO_PIN_0;
    GPIO_InitStruct.Mode = LL_GPIO_MODE_ANALOG;
    GPIO_InitStruct.Pull = LL_GPIO_PULL_NO;
    LL_GPIO_Init(GPIOB, &GPIO_InitStruct);
  ADC_InitStruct.Resolution = LL_ADC_RESOLUTION_12B;
  ADC_InitStruct.DataAlignment = LL_ADC_DATA_ALIGN_RIGHT;
  ADC_InitStruct.LowPowerMode = LL_ADC_LP_MODE_NONE;
  LL_ADC_Init(ADC1, &ADC_InitStruct);
  ADC_REG_InitStruct.TriggerSource = LL_ADC_REG_TRIG_SOFTWARE;
  ADC_REG_InitStruct.SequencerLength = LL_ADC_REG_SEQ_SCAN_DISABLE;
  ADC_REG_InitStruct.SequencerDiscont = LL_ADC_REG_SEQ_DISCONT_DISABLE;
  ADC_REG_InitStruct.ContinuousMode = LL_ADC_REG_CONV_SINGLE;
  ADC_REG_InitStruct.DMATransfer = LL_ADC_REG_DMA_TRANSFER_NONE;
  ADC_REG_InitStruct.Overrun = LL_ADC_REG_OVR_DATA_PRESERVED;
  LL_ADC_REG_Init(ADC1, &ADC_REG_InitStruct);
  LL_ADC_ConfigOverSamplingRatioShift(ADC1, LL_ADC_OVS_RATIO_16, LL_ADC_OVS_SHIFT_NONE);
  LL_ADC_SetOverSamplingDiscont(ADC1, LL_ADC_OVS_REG_CONT);
  ADC_CommonInitStruct.CommonClock = LL_ADC_CLOCK_ASYNC_DIV1;
  ADC_CommonInitStruct.Multimode = LL_ADC_MULTI_INDEPENDENT;
  LL_ADC_CommonInit(__LL_ADC_COMMON_INSTANCE(ADC1), &ADC_CommonInitStruct);
  LL_ADC_SetCommonPathInternalCh(__LL_ADC_COMMON_INSTANCE(ADC1), LL_ADC_PATH_INTERNAL_NONE);

  /* Disable ADC deep power down (enabled by default after reset state) */
  LL_ADC_DisableDeepPowerDown(ADC1);
  /* Enable ADC internal voltage regulator */
  LL_ADC_EnableInternalRegulator(ADC1);

 

 

this is how I read the ADC

 

    LL_ADC_REG_SetSequencerRanks(ADC1, LL_ADC_REG_RANK_1, LL_ADC_CHANNEL_15);
    LL_ADC_SetChannelSamplingTime(ADC1, LL_ADC_CHANNEL_15, LL_ADC_SAMPLINGTIME_2CYCLES_5);
    LL_ADC_SetChannelSingleDiff(ADC1, LL_ADC_CHANNEL_15, LL_ADC_SINGLE_ENDED);
  	LL_ADC_REG_StartConversion(ADC1);
  	while(LL_ADC_REG_IsConversionOngoing(ADC1));
  	PB0_ADC_value = LL_ADC_REG_ReadConversionData32(ADC1);
  	LL_ADC_REG_StartConversion(ADC1);
  	while(LL_ADC_REG_IsConversionOngoing(ADC1));
  	PB0_ADC_value = LL_ADC_REG_ReadConversionData32(ADC1);
  	LL_ADC_REG_StartConversion(ADC1);
  	while(LL_ADC_REG_IsConversionOngoing(ADC1));
  	PB0_ADC_value = LL_ADC_REG_ReadConversionData32(ADC1);
  	LL_ADC_REG_StartConversion(ADC1);
  	while(LL_ADC_REG_IsConversionOngoing(ADC1));
  	PB0_ADC_value = LL_ADC_REG_ReadConversionData32(ADC1);

 

1 ACCEPTED SOLUTION

Accepted Solutions
Peter BENSCH
ST Employee

Anyway, the time constant of the resulting RC network is well into the millisecond range due to the 100nF, which must of course be taken into account. A pull-up in the order of 40kohms will also have a significant influence, which is why you need to give the system enough time to settle.

In order to give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.

View solution in original post

10 REPLIES 10
b.a.
Associate III

the above was in debug-mode with breakpoints...
if I let the code run normally, just a consecutive read is not enough, the values decrease only slightly from one read to the next.

To get to stable values, I have to add a 10ms delay at least

Peter BENSCH
ST Employee

Well, since in your case it is a high-impedance temperature measurement with some significant capacitor, which is therefore very slow, you should set the ADC from 2.5 cycles to the slowest 640.5 cycles.

Regards
/Peter

In order to give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.
b.a.
Associate III

well, my thoughts went that way too

But I reasoned that it should only be relevant after powering up the system, not when it is running and I merely reset the controller...

changing to 640,5 cycles did not change the behaviour relevantly 

b.a.
Associate III

I also notice a drastic change in returned ADC value depending on if and where I set a breakpoint before the read.

Setting a breakpoint before the GPIO gets set to analog (line 1 in the below code) returns 39897

line 5 : 19913

 

Might this be because the pin was configured as input with pullup right before?

 

    GPIO_InitStruct.Pin = LL_GPIO_PIN_0;
    GPIO_InitStruct.Mode = LL_GPIO_MODE_ANALOG;
    GPIO_InitStruct.Pull = LL_GPIO_PULL_NO;
    LL_GPIO_Init(GPIOB, &GPIO_InitStruct);
    LL_ADC_REG_SetSequencerRanks(ADC1, LL_ADC_REG_RANK_1, LL_ADC_CHANNEL_15);
    LL_ADC_SetChannelSamplingTime(ADC1, LL_ADC_CHANNEL_15, LL_ADC_SAMPLINGTIME_640CYCLES_5);
    LL_ADC_SetChannelSingleDiff(ADC1, LL_ADC_CHANNEL_15, LL_ADC_SINGLE_ENDED);
  	LL_ADC_REG_StartConversion(ADC1);
  	while(LL_ADC_REG_IsConversionOngoing(ADC1));
  	PB0_ADC_value = LL_ADC_REG_ReadConversionData32(ADC1);
  	LL_ADC_REG_StartConversion(ADC1);
  	while(LL_ADC_REG_IsConversionOngoing(ADC1));
  	PB0_ADC_value1 = LL_ADC_REG_ReadConversionData32(ADC1);
  	LL_ADC_REG_StartConversion(ADC1);
  	while(LL_ADC_REG_IsConversionOngoing(ADC1));
  	PB0_ADC_value2 = LL_ADC_REG_ReadConversionData32(ADC1);
  	LL_mDelay(20);
  	LL_ADC_REG_StartConversion(ADC1);
  	while(LL_ADC_REG_IsConversionOngoing(ADC1));
  	PB0_ADC_value3 = LL_ADC_REG_ReadConversionData32(ADC1);

 (line 1 

If you have a multi-voltage setup, check that there is no positive injection on some pin.

b.a.
Associate III

everything is powered by the same 3,3V supply

Peter BENSCH
ST Employee

Anyway, the time constant of the resulting RC network is well into the millisecond range due to the 100nF, which must of course be taken into account. A pull-up in the order of 40kohms will also have a significant influence, which is why you need to give the system enough time to settle.

In order to give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.
b.a.
Associate III

so this behaviour can be explained by the big capacitor and the fact the just before, the pin had the internal pull-up connected?

Peter BENSCH
ST Employee

Just give it a try.

In order to give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.