I'm using the ADCs on an STM32L412, but it seems that they never reach their full value - the power is 3.3V and the reference is 3V, but they only ever fill to 3863 and not 4095. Why might this be? I measured the voltage on the input pin as 2.992V and the Vref pin as 3.001V

Is it possible the ADC is using 3.3V as a ref and not 3V? how can I change this?

This is the setup:

static void MX_ADC1_Init(void)
  ADC_MultiModeTypeDef multimode = {0};
  ADC_ChannelConfTypeDef sConfig = {0};

  /** Common config 
  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_DISABLE;
  hadc1.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
  hadc1.Init.LowPowerAutoWait = DISABLE;
  hadc1.Init.ContinuousConvMode = DISABLE;
  hadc1.Init.NbrOfConversion = 1;
  hadc1.Init.DiscontinuousConvMode = DISABLE;
  hadc1.Init.NbrOfDiscConversion = 1;
  hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
  hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
  hadc1.Init.DMAContinuousRequests = DISABLE;
  hadc1.Init.Overrun = ADC_OVR_DATA_PRESERVED;
  hadc1.Init.OversamplingMode = DISABLE;
  if (HAL_ADC_Init(&hadc1) != HAL_OK)
  /** Configure the ADC multi-mode 
  multimode.Mode = ADC_MODE_INDEPENDENT;
  if (HAL_ADCEx_MultiModeConfigChannel(&hadc1, &multimode) != HAL_OK)
  /** Configure Regular Channel 
  sConfig.Channel = ADC_CHANNEL_11;
  sConfig.Rank = ADC_REGULAR_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)
  • 2
    \$\begingroup\$ Investigate your ADC configuration code, and edit it into your question. Also try a lower voltage; maybe grab a flashlight battery or rig a stiff voltage divider. What's your source impedance? Some of these ADCs can present a substantial load at faster conversion clocks. \$\endgroup\$ Commented Dec 22, 2020 at 16:09
  • 4
    \$\begingroup\$ measure the internal reference channel so you get a clue of what kind of Vref ADC is using. \$\endgroup\$ Commented Dec 22, 2020 at 16:24
  • \$\begingroup\$ It could also depend on what you're measuring. Depending on the type of ADC used you may need to take the input impedance of the input pin into account. If you're measuring a voltage divider for example, your bottom resistor is actually in parallel with a 5-9k resistor during sampling. \$\endgroup\$
    – Stiddily
    Commented Dec 22, 2020 at 17:43
  • \$\begingroup\$ OK thanks, a few things - i edited the question to include the ADC setup. I haven't changed the Vref to see if it makes a difference yet, but it's driven directly from an op-amp so pretty low impedance. The measurement pin is also driven from a op-amp through a 1k resistor and diode to ground. How do i measure the reference channel? \$\endgroup\$
    – prune
    Commented Dec 22, 2020 at 18:29
  • 1
    \$\begingroup\$ Doesn't the STM32 have some nasty way that Vref actually is an analog input that is used to calibrate Vrefint (internal reference), then all conversions are related to Vrefint? \$\endgroup\$ Commented Dec 22, 2020 at 23:32

1 Answer 1


try to calibrate your ADC , maybe the problem comes from this issue


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.