I've been trying to measure the MCU's (STM32F103RB) temperature as part of a FreeRTOS application. I've tried initializing the ADC both with the low and the high-level HAL functions, but whenever I try to get data, the variable storing them has a value of about 68 (when normally it should be ~1500 - 1600 in room temperature). Any ideas?

Code follows here: TempMsr.c - HAL

#include "Peripherals/TempMsr.h"

volatile int32_t sensorData = 0;
volatile int32_t temp = 0;
ADC_HandleTypeDef adc1_config;
ADC_ChannelConfTypeDef adc1_channel;

int32_t getTemp()
    sensorData = HAL_ADC_GetValue(&adc1_config);
    temp = (int32_t)( ( (10 * V25 - 8 * sensorData) / (AVGSLOPE * 10) ) + 25 + BIAS);
    //manufacturer's formula for determining the temperature in Celsius, adjusted for unit
    //compliance and for minimizing errors due to possible floating-point operations
    return sensorData;

void ADC_TempMsr_Init()
    HAL_ADC_ConfigChannel(&adc1_config, &adc1_channel);

void ADC_Config()
    adc1_config.Instance = ADC1;
    adc1_config.Init.ScanConvMode = ADC_SCAN_DISABLE;
    adc1_config.Init.ContinuousConvMode = ENABLE;
    adc1_config.Init.DiscontinuousConvMode = DISABLE;
    adc1_config.Init.ExternalTrigConv = ADC_SOFTWARE_START;
    adc1_config.Init.DataAlign = ADC_DATAALIGN_RIGHT;
    adc1_config.Init.NbrOfConversion = 1;

    adc1_channel.Channel = ADC_CHANNEL_TEMPSENSOR;
    adc1_channel.Rank = ADC_REGULAR_RANK_1;
    adc1_channel.SamplingTime = ADC_SAMPLETIME_239CYCLES_5;  //~17 us, manufacturer-suggested time for temp sampling

TempMsr.c - Low-level:

void ADC_TempMsr_Init()



void ADC_Config()
    LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_ADC1);  //enable the clock for ADC1

    uint32_t wait_loop_index = 80;  //CPU cycles which correspond to ~10 us, suggested stabilization time for temp.sensor stabilization

    while(wait_loop_index != 0)

    /* Set ADC group regular trigger source */

    /* Set ADC group regular continuous mode */

    /* Set ADC group regular sequencer length and scan direction */

    /* Set ADC group regular sequence: channel on the selected sequence rank. */


The corresponding header file (TempMsr.h):

#ifndef INC_TEMPMSR_H_
#define INC_TEMPMSR_H_

#include "stm32f1xx_hal.h"
//#include "stm32f1xx_ll_adc.h"
//#include "stm32f1xx_ll_bus.h"

#define AVGSLOPE 4.3
//average slope of T-V chart according to datasheet pg 79
//(min is 4 mV/C, max 4.6, default (4.3): typical)

#define V25 1430
//voltage of temperature sensor at 25C according to datasheet pg 79 (in mV)
//(min is 1340, max is 1520, default(1430): typical)

#define BIAS 20
//according to the manual (pg 235), due to mfg processes
//there is an offset in the V(T) plot different
//to every chip (up to +-45oC) that needs to be found.
//(default is 0 so it MUST be calculated before any meaningful measurements
//are made)

int32_t getTemp();  //returns current MCU temp. in Celsius
void ADC_TempMsr_Init();  //initializes the ADC, this needs to be run in prvHardwareSetup()
void ADC_Config();

Finally, the FreeRTOS task:

void vTempTask(void *pvParameters)
        xSensorData.temp = getTemp();  //continually update the appropriate variable inside the sensor data struct
        vTaskDelay(pdMS_TO_TICKS(1000));   //1 second per measurement is enough

Thanks in advance.

  • 3
    \$\begingroup\$ You are setting the sampling time wrong. You have to use a predefined value not a multiple of ADC_SAMPLETIME_1CYCLE_5. There are only a few bits to set the sampling time and 91*ADC_SAMPLETIME_1CYCLE_5 probably results in the sampling time still being just 1.5 cycles, which is too fast. \$\endgroup\$
    – Arsenal
    Commented Oct 30, 2018 at 16:13
  • \$\begingroup\$ Fixed that, unfortunately it didn't change anything :( It's still stuck at 68. \$\endgroup\$ Commented Oct 30, 2018 at 16:26

1 Answer 1


I'm not 100% sure about HAL but I think you only read the value from the registers - it doesn't start the conversion. Software trigger means that you need to manually start the conversion. Look for a function which does that in HAL.

  • \$\begingroup\$ It worked! Many thanks. Lesson learned: always remember to activate the conversion when grabbing values from an ADC. \$\endgroup\$ Commented Oct 30, 2018 at 16:44
  • \$\begingroup\$ @lightspot21 glad to help \$\endgroup\$
    – jaskij
    Commented Oct 30, 2018 at 16:46
  • \$\begingroup\$ @lightspot21 also don't be surprised if the value is strange. From my experience they never really match environment temperature. \$\endgroup\$
    – jaskij
    Commented Oct 30, 2018 at 17:05
  • \$\begingroup\$ Actually I think I read somewhere in the manual that these have a max bias of 45 degreees over or under the correct temperature. I think it's good enough for measuring core temperature though. \$\endgroup\$ Commented Oct 30, 2018 at 17:11
  • \$\begingroup\$ @lightspot21 there are calibration values stored which makes it accurate to about +- 6 K, see here: electronics.stackexchange.com/questions/324321/… \$\endgroup\$
    – Arsenal
    Commented Oct 30, 2018 at 20:51

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.