cancel
Showing results for 
Search instead for 
Did you mean: 

STM32L412KB ADC Oversampling - Question to right bitshift

ledi001
Senior

Hello,

i am using ADC with DMA. In my initialization code i did the ADC calibration procedure like that:

  HAL_ADCEx_Calibration_Start(&hadc1, ADC_SINGLE_ENDED);	// ADC calibration
  VrefintCalValue = (*VREFINT_CAL_ADDR);					// read out the calibration value of VREFINT
 
  HAL_ADC_Start_DMA(&hadc1, (uint32_t*)adc_buffer, 3);		// Start ADC for 3 conversions and transfer data over DMA inside the memory

After ADC conversion complete, i calculate the battery voltage (vdd) as follows:

		  adc_value_VREFINT = (double)(3 * VrefintCalValue) / 4095;
		  vdd = 3000 * ((double)VrefintCalValue / (adc_buffer[2] >> 4));	// why not (adc_buffer[2] >> 3)?

The calculation works fine, but i don't understand the 4x bitshift. In my opinion it must be 3x bit-shift.

Here is a part of my ADC init:

  hadc1.Init.OversamplingMode = ENABLE;
  hadc1.Init.Oversampling.Ratio = ADC_OVERSAMPLING_RATIO_128;
  hadc1.Init.Oversampling.RightBitShift = ADC_RIGHTBITSHIFT_3;
  hadc1.Init.Oversampling.TriggeredMode = ADC_TRIGGEREDMODE_SINGLE_TRIGGER;
  hadc1.Init.Oversampling.OversamplingStopReset = ADC_REGOVERSAMPLING_CONTINUED_MODE;

Can someone explain to me why a 3x right bit-shift is wrong in that case?

1 ACCEPTED SOLUTION

Accepted Solutions

I don't use Cube, but you appear to have set the ADC to oversample 128x, i.e. add up 128 samples to one result presented. If you want to have the result in the original range, i.e. 0-4095, you have to divide it by 128, which is equivalent to right shift by 7 (128 = 2 ^ 7).

You also set ADC to shift the result to the right by 3, so then you manually shift it by 7 - 3 = 4.

You can set the ADC to shift by 7 and then don't need to shift manually at all.

JW

View solution in original post

1 REPLY 1

I don't use Cube, but you appear to have set the ADC to oversample 128x, i.e. add up 128 samples to one result presented. If you want to have the result in the original range, i.e. 0-4095, you have to divide it by 128, which is equivalent to right shift by 7 (128 = 2 ^ 7).

You also set ADC to shift the result to the right by 3, so then you manually shift it by 7 - 3 = 4.

You can set the ADC to shift by 7 and then don't need to shift manually at all.

JW