2026-02-18 2:27 AM
I'm using STM32F429 and trying to read the internal temperature sensor and convert it to a degree C value. Absolute accuracy is not important right now, I just want to make sure a reasonable representation of temperature is being produced. The ADC is running continuously with DMA dropping the result into a uint16_t variable which I'm monitoring. The variable gives a raw value around 1220 (decimal) at room temperature, and feeding this value into the __LL_ADC_CALC_TEMPERATURE_TYP_PARAMS macro gives an output of around 21C. So far so good.
Warming up the micro gently with a hairdryer shows the ADC value increasing, as I believe it should. However, the calculated output from the macro falls, and reviewing the content of the macro this is not surprising:
#define __LL_ADC_CALC_TEMPERATURE_TYP_PARAMS(__TEMPSENSOR_TYP_AVGSLOPE__,\
__TEMPSENSOR_TYP_CALX_V__,\
__TEMPSENSOR_CALX_TEMP__,\
__VREFANALOG_VOLTAGE__,\
__TEMPSENSOR_ADC_DATA__,\
__ADC_RESOLUTION__) \
((( ( \
(int32_t)(((__TEMPSENSOR_TYP_CALX_V__)) \
* 1000) \
- \
(int32_t)((((__TEMPSENSOR_ADC_DATA__) * (__VREFANALOG_VOLTAGE__)) \
/ __LL_ADC_DIGITAL_SCALE(__ADC_RESOLUTION__)) \
* 1000) \
) \
) / (__TEMPSENSOR_TYP_AVGSLOPE__) \
) + (__TEMPSENSOR_CALX_TEMP__) \
)The value calculated from __TEMPSENSOR_ADC_DATA__ is subtracted from the CALX value (see the minus at line 10 of the listing), so an increasing ADC value is always going to give a reduced value at the end of the calculation. It looks to me like the macro is wrong, which is hard to believe considering the file (stm32f4xx_ll_adc.h) was created in 2017.
Rather than tinker with the macro, I inserted replacement step-by-step code to replicate it in my code, and swapped the positions of the CALX_V and ADC_DATA sections, i.e. CALX_V is now subtracted from ADC_DAT rather than the other way round, and the resulting degree C value now increases as the micro is warmed up.
#define __TEMPSENSOR_TYP_AVGSLOPE__ 2500
#define __TEMPSENSOR_TYP_CALX_V__ 760
#define __TEMPSENSOR_CALX_TEMP__ 25
#define __VREFANALOG_VOLTAGE__ 2500
#define __ADC_RESOLUTION__ LL_ADC_RESOLUTION_12B
int32_t newtemp;
newtemp = ((int32_t)(__TEMPSENSOR_ADC_DATA__ * __VREFANALOG_VOLTAGE__) / __LL_ADC_DIGITAL_SCALE(__ADC_RESOLUTION__)) * 1000;
newtemp -= (int32_t)(((__TEMPSENSOR_TYP_CALX_V__)) * 1000);
newtemp /= __TEMPSENSOR_TYP_AVGSLOPE__;
newtemp += __TEMPSENSOR_CALX_TEMP__;So, could the implementation of the __LL_ADC_CALC_TEMPERATURE_TYP_PARAMS be incorrect, or am I missing something?
2026-02-18 6:39 AM
It sure looks incorrect to me. I also find it hard to believe that it wasn't caught in 7 years, but there it is. The output definitely goes down as the ADC value increases, which is not the correct correlation.
It's even used in one example:
If nobody else replies I can ask that it gets looked at in a few days. I hope we're missing something though.
2026-02-18 8:29 AM
TDK, thanks for the sanity check. I'll await further feedback or comments with interest.
Andy
2026-02-23 12:38 AM
Hello @AGayn,
Indeed there is an error in the formula, the current one corresponds to a legacy version of temperature sensor (used on some other STM32 series).
However, we recommend using the other helper macro: __LL_ADC_CALC_TEMPERATURE().
It is based on calibration parameters measured in production for each device and stored in internal Flash memory of each device: therefore, more accurate.
Note: Macro __LL_ADC_CALC_TEMPERATURE_TYP_PARAMS() is available to compute temperature from slope and offset generic data mentioned in datasheet. Macro less used, this probably explain why issue remained undetected.
I hope this information helps. When your question is resolved, please mark this topic as the accepted solution, as it will help others find the information more easily.
Thanks for your contribution.
Dor_RH
2026-02-23 12:55 AM
Unfortunately, according to the header of __LL_ADC_CALC_TEMPERATURE() within file 'stm32f4xx_ll_adc.h' the macro is not available to me on the F429 and is excluded by conditional build:
/* Note: On device STM32F4x9, calibration parameter TS_CAL2 is not available. */
/* Therefore, helper macro __LL_ADC_CALC_TEMPERATURE() is not available.*/
/* Use helper macro @ref __LL_ADC_CALC_TEMPERATURE_TYP_PARAMS(). */
#if !defined(STM32F469) && !defined(STM32F479xx) && !defined(STM32F429xx) && !defined(STM32F439xx)
....So for this sub-family of F4 micros, have they been updated to include TS_CAL2 or am I still forced to use the (incorrect) __LL_ADC_CALC_TEMPERATURE_TYP_PARAMS() macro? Either way, the file stm32f4xx_ll_adc.h needs correcting, to remove the conditional build or to correct the TYP_PARAMS macro.