STM32L475 ADC seems to use an effective reference of 2.62 V while VDDA/VREF+ is connected to 2.50 V
Hello,
I am working with an STM32L475RET and have encountered an unexpected behavior with the ADC reference voltage.
My hardware configuration is the following:
- VDDA and VREF+ are tied together and supplied with a precise 2.5V reference.
- The ADC is configured for 12-bit conversions.
- The 2.5V reference has been verified with a multimeter and is stable.
- ADC clock source is set to 48MHz
When measuring several analog input voltages, the ADC results consistently do not match the expected values assuming a 2.5V reference. I found that the measured ADC values correspond much more closely to an effective reference voltage of approximately 2.62V rather than 2.5V. To further investigate, I measured the internal VREFINT channel and compared the ADC result against the value expected from the datasheet, and assuming a 2.5V reference, the VREFINT result (1.167V) does not match the expected value:

Using this initial config for the ADC:
/**
* @brief ADC1 Initialization Function
* @param None
* @retval None
*/
static void MX_ADC1_Init(void)
{
/* USER CODE BEGIN ADC1_Init 0 */
/* USER CODE END ADC1_Init 0 */
ADC_MultiModeTypeDef multimode = {0};
ADC_ChannelConfTypeDef sConfig = {0};
/* USER CODE BEGIN ADC1_Init 1 */
/* USER CODE END ADC1_Init 1 */
/** Common config
*/
hadc1.Instance = ADC1;
hadc1.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV4;
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.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)
{
Error_Handler();
}
/** Configure the ADC multi-mode
*/
multimode.Mode = ADC_MODE_INDEPENDENT;
if (HAL_ADCEx_MultiModeConfigChannel(&hadc1, &multimode) != HAL_OK)
{
Error_Handler();
}
} And this config for a channel reading:
ADC_ChannelConfTypeDef stConfigAdc = {0};
stConfigAdc.Channel = ulAdcGetChannel(eChannelType); // 28V, 12V, 5V, 3.3V Channels
stConfigAdc.Rank = ADC_REGULAR_RANK_1;
stConfigAdc.SamplingTime = ulAdcGetSamplingTime(eRate); // Using hight sampling like 640.5 cycles
stConfigAdc.SingleDiff = ADC_SINGLE_ENDED;Besides, we are using this HAL method at startup, to calibrate the external reference with VREFINT:
HAL_ADCEx_Calibration_Start(pstImuAdcHandle, ADC_DIFFERENTIAL_ENDED);
At this point i’m wondering if there any known condition under which the STM32L475 ADC could use a different reference than the voltage applied to VDDA/VREF+?

