I'm using Nucleo-32 board with STM32F031K6 MCU. I have some weird problem with ADC measurement. When ADC pin (PA4 in my case) is connected directly to VREF or 3V3 the value is always in range of 4031-4032 instead if 4095... For measuring low voltages, the ADC value has higher offset from the correct one (20% lower then it should be for 0.5V measuring).

Could anybody please explain this behavior?

ADC configuration:

  ADC_ChannelConfTypeDef sConfig;

    /**Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion) 
  hadc.Instance = ADC1;
  hadc.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV1;
  hadc.Init.Resolution = ADC_RESOLUTION_12B;
  hadc.Init.DataAlign = ADC_DATAALIGN_RIGHT;
  hadc.Init.ScanConvMode = DISABLE;
  hadc.Init.EOCSelection = ADC_EOC_SEQ_CONV;
  hadc.Init.LowPowerAutoWait = DISABLE;
  hadc.Init.LowPowerAutoPowerOff = DISABLE;
  hadc.Init.ContinuousConvMode = DISABLE;
  hadc.Init.DiscontinuousConvMode = DISABLE;
  hadc.Init.ExternalTrigConv = ADC_SOFTWARE_START;
  hadc.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
  hadc.Init.DMAContinuousRequests = DISABLE;
  hadc.Init.Overrun = ADC_OVR_DATA_PRESERVED;

  if (HAL_ADC_Init(&hadc) != HAL_OK)


  /**Configure for the selected ADC regular channel to be converted. 
  sConfig.Channel = ADC_CHANNEL_4;
  sConfig.SamplingTime = ADC_SAMPLETIME_239CYCLES_5;
  if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)

Pin configuration:


GPIO_InitStruct.Pin = GPIO_PIN_4;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
  • \$\begingroup\$ Did you measure vref with a multimeter? How do you supply the board? \$\endgroup\$ Commented Aug 25, 2016 at 9:02
  • \$\begingroup\$ The Voltages that you are supplying to the ADC pin might not be the same. For example : 3.3V onboard will be ~3.2-3.3V(loading). \$\endgroup\$
    – ammar.cma
    Commented Aug 25, 2016 at 11:09
  • \$\begingroup\$ Board is powered by USB. Nothing external is connected ot it. ADC pin is connected directly to VREF pin!!! Multimeter shows exactly 3.3V for VREF and 3V3 \$\endgroup\$
    – maff91
    Commented Aug 25, 2016 at 14:57

2 Answers 2


Thank everyone for help. Finally I found solution myself

This function call after ADC initialization makes all the magic to solve the issue


A couple of thoughts:

  1. I wonder if your VDDA or VREF voltage has an offset. I took a look at the Nucleo-32 board schematic here and saw these pins connected to a bead which could have some DC resistance that matters if you are drawing a lot of current from that node which sometimes is used on ADCs for measurement reference.

Maybe try measuring the voltage at pin 5 of the MCU (VDDA/VREF+)?

  1. How much time are you allowing for settling? It seems that the ADCs are 5Msps? It should be pretty fast but you might have some capacitance slowing your signal down more than you think.

  2. Do you see the same problem on another analog input (e.g. PA1)? If so, this may indicate a VREF issue as well.

  • \$\begingroup\$ ADC is connected to VDDA/VREF+. Anyway measurements are the same for 3V3, either. I measure voltage each 0,5 sec with the longest conversion time. PA5 acts the same \$\endgroup\$
    – maff91
    Commented Aug 25, 2016 at 15:00
  • \$\begingroup\$ I ran into this electronics.stackexchange.com/questions/52894/… post about checking the correct ADC settings. Hopefully you have already done that. So it seems you are off by ~50 codes at the full scale. Is this offset constant over the whole range?... this may be expected. Do you have a link to the ADC specs? I couldn't find one using a quick search. \$\endgroup\$
    – Daniel V
    Commented Aug 25, 2016 at 16:42

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.