__LL_ADC_CALC_TEMPERATURE_TYP_PARAMS macro, is it faulty?
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?
