Skip to main content
Explorer II
March 14, 2025
Question

Stm32L562 Internal Temperature sensor reading is not right?

  • March 14, 2025
  • 3 replies
  • 639 views
 

 

 

float read_internal_temperature(void)
{
 uint32_t adcValue;
 float temperature;

 // Configure ADC channel for temperature sensor
 ADC_ChannelConfTypeDef sConfig = {0};
 sConfig.Channel = ADC_CHANNEL_TEMPSENSOR;
 sConfig.Rank = ADC_REGULAR_RANK_1;
 sConfig.SamplingTime = ADC_SAMPLETIME_640CYCLES_5;
 HAL_ADC_ConfigChannel(&hadc1, &sConfig);

 // Start conversion and wait for it to complete
 HAL_ADC_Start(&hadc1);
 HAL_ADC_PollForConversion(&hadc1, HAL_MAX_DELAY);

 // Read ADC value
 adcValue = HAL_ADC_GetValue(&hadc1);

 // Retrieve calibration values from system memory
 uint16_t ts_cal1 = TS_CAL1; // Calibration value at 30°C
 uint16_t ts_cal2 = TS_CAL2; // Calibration value at 110°C

 // Calculate the slope between TS_CAL1 and TS_CAL2
 float slope = (float)(ts_cal2 - ts_cal1) / (110.0f - 30.0f);

 // Calculate the temperature
 temperature = 30.0f + ((float)(adcValue - ts_cal1) / slope);

 // Stop ADC to save power
 HAL_ADC_Stop(&hadc1);

 return temperature;
}

 

 

The adcValue returns very low value although I am using a 12 bit resolutio

    This topic has been closed for replies.

    3 replies

    Super User
    March 14, 2025

    Do you calibrate the ADC on startup?

    Does your VREF+ match what was used for TS_CALx? (in datasheet)

    Graduate II
    March 14, 2025

    Isn't TS_CAL1 an address? You need to de-reference it first. Also I would invert the slope calculation so you only need to multiply instead of dividing.
    If your VREF voltage is not the same you need to scale your voltage or the CAL values.

    chsrinivAuthor
    Explorer II
    March 14, 2025

    Thanks all for your help!

    I confirm my Vref match the CAL values in my data sheet.

    Initial ADC calibration

    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_DIV1;
     hadc1.Init.Resolution = ADC_RESOLUTION_12B;
     hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
     hadc1.Init.ScanConvMode = ADC_SCAN_ENABLE; // Enable scan mode for multiple channels
     hadc1.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
     hadc1.Init.LowPowerAutoWait = DISABLE;
     hadc1.Init.ContinuousConvMode = DISABLE;
     hadc1.Init.NbrOfConversion = 2; // Two conversions (Temp sensor and VREFINT)
     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;
     hadc1.Init.DFSDMConfig = ADC_DFSDM_MODE_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();
     }
    
     /** Configure Regular Channel for Temperature Sensor (ADC_CHANNEL_TEMPSENSOR)
     */
     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();
     }
    
     /** Configure Regular Channel for VREFINT (ADC_CHANNEL_VREFINT)
     */
     sConfig.Channel = ADC_CHANNEL_VREFINT;
     sConfig.Rank = ADC_REGULAR_RANK_2; // Second conversion
     sConfig.SamplingTime = ADC_SAMPLETIME_640CYCLES_5;
     if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
     {
     Error_Handler();
     }
    
     /* USER CODE BEGIN ADC1_Init 2 */
    
     /* USER CODE END ADC1_Init 2 */
    }

    My temperature reading code

    float read_internal_temperature(void)
    {
    	uint32_t adc_vref_raw;
    	uint32_t adc_temp_raw;
    
    
    	// Start the ADC conversion
    	HAL_ADC_Start(&hadc1);
    
    	// Wait for conversion to complete for Temperature channel
    	HAL_ADC_PollForConversion(&hadc1, HAL_MAX_DELAY);
    	adc_temp_raw = HAL_ADC_GetValue(&hadc1); // Temperature sensor value
    
    	// Wait for conversion to complete for VREFINT channel
    	HAL_ADC_PollForConversion(&hadc1, HAL_MAX_DELAY); // Ensure the next channel is ready
    	adc_vref_raw = HAL_ADC_GetValue(&hadc1); // VREFINT value
    
    	// Retrieve calibration values for temperature sensor and VREFINT
    	uint16_t ts_cal1 = (*TEMPSENSOR_CAL1_ADDR); // Calibration at 30°C
    	uint16_t ts_cal2 = (*TEMPSENSOR_CAL2_ADDR); // Calibration at 110°C
    	uint16_t vrefint_cal = (*VREFINT_CAL_ADDR); // VREFINT calibration
    
    	// Calculate VDDA (the reference voltage)
    	float vdda = (3.0 * vrefint_cal) / adc_vref_raw;
    
    	// Calculate temperature based on calibration values
    	float slope = (float)(ts_cal2 - ts_cal1) / (110.0f - 30.0f);
    	float temperature = 30.0f + ((float)(adc_temp_raw - ts_cal1) / slope);
    
    	// Stop the ADC conversion
    	HAL_ADC_Stop(&hadc1);
    
    	// You now have the calibrated temperature and VDDA (reference voltage)
    	return temperature;
    }

     Final Output:

    adc_temp_raw = 901 -> again too low
    adc_vref_raw = 1443
    ts_cal1 = 1040
    ts_cal2 = 1384
    vrefint_cal = 1657
    vdda = 3.4V

     

    Graduate II
    March 14, 2025

    You are not calibrating your ADC in MX_ADC1_Init(). A common mistake.
    Use HAL_ADCEx_Calibration_Start() or LL_ADC_StartCalibration().
    Also wait after calibration before starting: https://community.st.com/t5/stm32-mcus-products/adc-register-adrdy-never-sets-when-i-enable-the-adc-so-it-keeps/m-p/106159#M17007