2026-03-16 7:42 AM
Dear ST Community,
I am currently migrating my Firmware from STM32H723VG to STM32H563VI. I have problem with Internal Temp Sensor. Based on Reference Manual on both MCU reading temperature is the same, but it doesn't work as it should.
When on STM32H7 I got about 750 (24 degree Celsius) on reading ADC from TEMP Sens, on STM32H5 I have around 100.
I tried both with and without cache (ICache and DCache), with Bare Metal and Zephyr RTOS code. In every configuration it is not working. I tried also on different MCUs, so it shouldn't be part itself.
It worked with Nucleo H563ZI, but doesn't with H563VI.
What else can I do?
Solved! Go to Solution.
2026-03-16 7:51 AM - edited 2026-03-17 6:32 AM
Hello @adakPal and welcome to the ST community,
@adakPal wrote:
It worked with Nucleo H563ZI, but doesn't with H563VI.
You didn't mention what board are you using for that STM32H563VI device. What about the VREF pins? did you connect it to a reference voltage?
If it works on H563ZI it should work on H563VI.
2026-03-16 7:50 AM
Calibrate the ADC before using.
Use longest sampling time for internal temperature sensor.
Use the correct voltage reference.
Show you code.
2026-03-16 7:51 AM - edited 2026-03-17 6:32 AM
Hello @adakPal and welcome to the ST community,
@adakPal wrote:
It worked with Nucleo H563ZI, but doesn't with H563VI.
You didn't mention what board are you using for that STM32H563VI device. What about the VREF pins? did you connect it to a reference voltage?
If it works on H563ZI it should work on H563VI.
2026-03-17 12:00 AM
ADC_SAMPLETIME_640CYCLES_5My code:
ADC:
static void MX_ADC1_Init(void)
{
/* USER CODE BEGIN ADC1_Init 0 */
/* USER CODE END ADC1_Init 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.SamplingMode = ADC_SAMPLING_MODE_NORMAL;
hadc1.Init.Overrun = ADC_OVR_DATA_PRESERVED;
hadc1.Init.OversamplingMode = DISABLE;
if (HAL_ADC_Init(&hadc1) != HAL_OK)
{
Error_Handler();
}
/** Configure Regular Channel
*/
sConfig.Channel = ADC_CHANNEL_TEMPSENSOR;
sConfig.Rank = ADC_REGULAR_RANK_1;
sConfig.SamplingTime = ADC_SAMPLETIME_640CYCLES_5;
sConfig.SingleDiff = ADC_SINGLE_ENDED;
sConfig.OffsetNumber = ADC_OFFSET_NONE;
sConfig.Offset = 0;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN ADC1_Init 2 */
/* USER CODE END ADC1_Init 2 */
}main():
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* MPU Configuration--------------------------------------------------------*/
MPU_Config();
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_ADC1_Init();
MX_ICACHE_Init();
/* USER CODE BEGIN 2 */
if (HAL_ADCEx_Calibration_Start(&hadc1, ADC_SINGLE_ENDED) != HAL_OK)
{
Error_Handler();
}
HAL_Delay(2);
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
HAL_StatusTypeDef st;
st = HAL_ADC_Start(&hadc1);
if (st != HAL_OK)
{
return st;
}
/* Rank 1: TEMPSENSOR */
st = HAL_ADC_PollForConversion(&hadc1, 100);
if (st != HAL_OK)
{
HAL_ADC_Stop(&hadc1);
return st;
}
uint32_t temp_raw_out = HAL_ADC_GetValue(&hadc1);
uint32_t temp = (uint32_t)((float)(TEMPSENSOR_CAL2_TEMP - TEMPSENSOR_CAL1_TEMP) /
(float)(*TEMPSENSOR_CAL2_ADDR - *TEMPSENSOR_CAL1_ADDR) *
(float)((uint16_t)(temp_raw_out) -
*TEMPSENSOR_CAL1_ADDR) +
(float)TEMPSENSOR_CAL1_TEMP);
HAL_Delay(100);
}
}And temp_raw_out is always around 470-520
2026-03-17 6:10 AM
> on STM32H5 I have around 100.
> And temp_raw_out is always around 470-520
Which of these is true?
The ADC value shouldn't necessarily match between two series. Ignore whatever you get on the H7. What does the temperature calculation on the H5 turn up?
What are the values of *TEMPSENSOR_CALx_ADDR and *TEMPSENSOR_CAL1_TEMP?
Can you show your schematic? Is there a capacitor next to VREF+ pin?
2026-03-17 6:27 AM
I'm sorry, but after consulting with an electronics engineer, it appears there is an issue with the hardware VREF- connection.
Thank you for your guidance!
2026-03-17 12:44 PM
Consider using the __LL_ADC_CALC_TEMPERATURE macro provided in the HAL
Helper macro to calculate the temperature (unit: degree Celsius)
* from ADC conversion data of internal temperature sensor.
* @note Computation is using temperature sensor calibration values
* stored in system memory for each device during production.
I don't think your code will work for negative temperatures.