AnsweredAssumed Answered

STM32L4 Oversampler producing odd results

Question asked by Ancaritha on Nov 9, 2017
Latest reply on Nov 10, 2017 by waclawek.jan

STM32L496

CubeMX v4.21  (Edit, updated to V4.22.1, same issue)

HAL Framework: 1.8

 

I'm trying to reduce some of the noise in my system by using the hardware oversampling.  However, I've noticed that the resulting conversions are slightly lower than without it enabled.  My basic software setup is every 10ms I read 15 ADC channels and process the data.  I have code that keeps track of the minimum and maximum raw tick values that I've seen, so I have a general idea the amount of noise that I'm seeing.

 

Note, I'm seeing this shift (though it may not by exactly the same amount) on every channel, i'm just going to use channel 1 as my sole example to make it easier to display the data.  If anyone really really wants I can display all my data.

 

Oversampling off, 2 cycle sampling time, 1047-1051 ticks

Oversampling 8x, 2 cycle sampling time, 1027-1030 ticks

Oversampling 8x, 92 cycle sampling time, 1038-1039 ticks

Oversampling 8x, 640 cycle sampling time, 1051-1052 ticks

 

The example channel I'm using happens to be a voltage sensor that i'm feeding 15.9V into.  With oversampling off, those tick values result in a reading of ~15.85V.  With Oversampling and 2 cycle sample time, it reads 15.5V (and thus why I think the oversampling values are wrong).

 

Below is my setup for the ADC

 

hadc1.Instance = ADC1;
hadc1.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV1;
hadc1.Init.Resolution = ADC_RESOLUTION_12B;
hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
hadc1.Init.ScanConvMode = ADC_SCAN_ENABLE;
hadc1.Init.EOCSelection = ADC_EOC_SEQ_CONV;
hadc1.Init.LowPowerAutoWait = ENABLE;
hadc1.Init.ContinuousConvMode = DISABLE;
hadc1.Init.NbrOfConversion = 15;
hadc1.Init.DiscontinuousConvMode = DISABLE;
hadc1.Init.NbrOfDiscConversion = 1;
hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
hadc1.Init.DMAContinuousRequests = ENABLE;
hadc1.Init.Overrun = ADC_OVR_DATA_PRESERVED;
hadc1.Init.OversamplingMode = ENABLE;
hadc1.Init.Oversampling.OversamplingStopReset = ADC_REGOVERSAMPLING_RESUMED_MODE;
hadc1.Init.Oversampling.Ratio = ADC_OVERSAMPLING_RATIO_8;
hadc1.Init.Oversampling.RightBitShift = ADC_RIGHTBITSHIFT_3;
hadc1.Init.Oversampling.TriggeredMode = ADC_TRIGGEREDMODE_SINGLE_TRIGGER;
if (HAL_ADC_Init(&hadc1) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}

/**Configure the ADC multi-mode
*/
multimode.Mode = ADC_MODE_INDEPENDENT;
if (HAL_ADCEx_MultiModeConfigChannel(&hadc1, &multimode) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}

/**Configure Regular Channel
*/
sConfig.Channel = ADC_CHANNEL_1;
sConfig.Rank = 1;
sConfig.SamplingTime = ADC_SAMPLETIME_2CYCLES_5;
sConfig.SingleDiff = ADC_SINGLE_ENDED;
sConfig.OffsetNumber = ADC_OFFSET_NONE;
sConfig.Offset = 0;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}

 

 

The rest of the channels are all the same setup.  I didn't want to include them to keep the post size down since they should be irrelevant.

 

I start the process using this command:

HAL_ADC_Start_DMA(&hadc1, (uint32_t *)pBuf->rawData(), ConfigAdc::ADC_CHAN_NUM_CHANNELS);

 

 

Anyone have any ideas what I'm seeing and why?  Being able to use hardware oversampling would be just like, the best.

 

Thanks!

Outcomes