Core Internal Temperature Sensor

Page 20 of the STM32 data sheet references a temperature sensor. Does anyone know of a way to utilize that? I know it’s not good for sensing ambient temperature, but if it’s an available data point, it might be somewhat interesting to monitor it.


Trying to see where this data goes… :smile:

Seems like we have to read from the ADC12_IN16 channel…

More information at page 226:

In the core-common code there’s a function to set the bit TSVREFE!

I can’t go any further than this and sure @mohit can help with all the information gathered above.

Looking at the analogread code and i believe some code there can be used to read this particular channel…

1 Like

I copied this example:

I’m getting around 42C on one core and 47C on another.

I am looking at using this value, together with the RSSI Signal strength, as a core ‘health’ indicator.

const uint16_t V25 = 1750;// when V25=1.41V at ref 3.3V
const uint16_t Avg_Slope = 5; //when avg_slope=4.3mV/C at ref 3.3V
//VCC and VREF = 3.3V; ADC_value = 4096
//V25 = 1.41V; ADC_Value=1750 (calculated = (1.41/3.3)*4096)
//Avg_Slope = 4.3mV ADC_value=5 (calculated = (0.0043/3.3)*4096)

void CpuTempInit()
    //enable ADC1 clock
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
    ADC_InitTypeDef ADC_InitStructure;
    //ADC1 configuration
    //select independent conversion mode (single)
    ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
    //We will convert single channel only
    ADC_InitStructure.ADC_ScanConvMode = DISABLE;
    //we will convert one time
    ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;
    //select no external triggering
    ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
    //right 12-bit data alignment in ADC data register
    ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
    //single channel conversion
    ADC_InitStructure.ADC_NbrOfChannel = 1;
    //load structure values to control and status registers
    ADC_Init(ADC1, &ADC_InitStructure);
    //wake up temperature sensor
    //ADC1 channel16 configuration
    //we select 41.5 cycles conversion for channel16
    //and rank=1 which doesn't matter in single mode
    ADC_RegularChannelConfig(ADC1, ADC_Channel_16, 1, ADC_SampleTime_41Cycles5);
    //Enable ADC1
    ADC_Cmd(ADC1, ENABLE);
    //Enable ADC1 reset calibration register
    //Check the end of ADC1 reset calibration register
    //Start ADC1 calibration
    //Check the end of ADC1 calibration

void setup() {


void loop() {

    //Start ADC1 Software Conversion
    ADC_SoftwareStartConvCmd(ADC1, ENABLE);
    //wait for conversion complete
    while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC)){}
    //read ADC value
    uint16_t AD_value=ADC_GetConversionValue(ADC1);
    //clear EOC flag
    ADC_ClearFlag(ADC1, ADC_FLAG_EOC);
    //printf("\r\n ADC value: %d \r\n", AD_value);
    uint16_t IntTemp = (uint16_t)((V25-AD_value)/Avg_Slope+25);    
    Delay (2000);


Those two temperatures strike me as being about right–just above body temp. The TI CC3000 on the other side of the board runs in that range and the regulator under the USB connector adds to the head load too. All that heat spreads around the board so you might get different readings using 3.3V supply instead of the regulator for instance.

If you wanted to double check, you would have to get another temperature sensor in under the core where the SMT32 is and measure there. You would then have to add a bit for the package thermal resistance, but it should be with a couple of degrees C.