Internal Temperature Sensor On STM32

Preface

The STM32 microcontroller has an internal temperature sensor. The sensor is very rough (±1.5 °C) and is connected internally to one of the ADC channels, making it possible to easily obtain device temperature without the need for any additional components. However, please note that this temperature is a relative temperature, not an absolute temperature, and there are temperature limits that cannot fully replace general sensors.

Internal Calculation Method

Here we use the STM32WB35 as the main reference (it supports the temperature range of –40 to 125 °C). This part can refer to the reference manual of each series. The uncalibrated internal temperature sensor is more suitable for detecting temperature changes in applications rather than absolute temperature.

Key points for numerical values:

Here, TS_CAL1/TS_CAL2 refers to the corresponding Flash position values that need to be extracted from the Datasheet. TS_CAL1_TEMP and TS_CAL2_TEMP correspond to 30 and 130, respectively.

The calculation formula and correction are as follows:

 temperature = (int32_t)(((TS_CAL2_TEMP - TS_CAL1_TEMP) / ((float)(*TS_CAL2) - (float)(*TS_CAL1))) *
	                 (adc_buffer[0] - (float)(*TS_CAL1)) + 30.0);

STM32CubeMX Setting


We need to enable the Temperature Sensor Channel and Vrefint Channel in the ADC section. Enabling Vrefint Channel is optional and can improve accuracy by determining the actual internal Vref voltage.

STM32CubeIDE Code

There are two ways to choose from here. One is to directly write the formula in the code area as shown below, and the other is to use the official function provided by STM.

/* USER CODE BEGIN WHILE */
  while (1)
  {
if (Flg.ADCCMPLT) /* Conversion completed, do calculations */
{
/* Temperature Sensor ADC-value, Reference Voltage ADC-value (if use) */
Adc.IntSensTmp = TMPSENSOR_getTemperature(Adc.Raw[1], Adc.Raw[0]);
#if(DBG_UART) /* Send data with UART2 */
UART_Printf_Dbg("Reference: Adc.Raw[0] = %u\r\n", Adc.Raw[0]);
UART_Printf_Dbg("Sensor: Adc.Raw[1] = %u\r\n", Adc.Raw[1]);
UART_Printf_Dbg("Temperature: Adc.IntSensTmp = %.2f℃\r\n", Adc.IntSensTmp);
#endif
#if(DBG_UART) /* Delay */
HAL_Delay(250);
#endif
Flg.ADCCMPLT = 0; /* Nullify flag */
}/* USER CODE END WHILE */

Here, you can refer to the network example of TMPSENSOR_getTemperature, and adjust the formula based on the obtained values.

#include "tmpsensor.h"

double TMPSENSOR_getTemperature(uint16_t adc_sensor, uint16_t adc_intref){

#if(TMPSENSOR_USE_INTREF)

	double intref_vol = (TMPSENSOR_ADCMAX*TMPSENSOR_ADCVREFINT)/adc_intref;

#else
	double intref_vol = TMPSENSOR_ADCREFVOL;
#endif

	double sensor_vol = adc_sensor * intref_vol/TMPSENSOR_ADCMAX;

	double sensor_tmp = (sensor_vol - TMPSENSOR_V25) *1000.0/TMPSENSOR_AVGSLOPE + 25.0;

	return sensor_tmp;
}

Leave a Comment

Your email address will not be published. Required fields are marked *

Shopping Cart