2024-02-09 12:29 AM
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
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);
Solved! Go to Solution.
2024-02-09 02:08 AM
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.
2024-02-09 12:42 AM
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
2024-02-09 12:54 AM
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
2024-02-09 01:01 AM
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
2024-02-09 01:46 AM
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
2024-02-09 01:51 AM
If you have a multi-voltage setup, check that there is no positive injection on some pin.
2024-02-09 01:53 AM
everything is powered by the same 3,3V supply
2024-02-09 02:08 AM
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.
2024-02-09 02:11 AM
so this behaviour can be explained by the big capacitor and the fact the just before, the pin had the internal pull-up connected?
2024-02-09 02:14 AM
Just give it a try.