cancel
Showing results for 
Search instead for 
Did you mean: 

calculating temperature for STM32L451 - tried both methods, but don't get correct readings

MFend
Associate III

According to the data sheet, the calibrated values for specific chip (at 30°C and 130°C) are at the following addresses:

#define TEMP30_CAL_ADDR  (*((uint16_t*)0x1FFF75A8))
#define TEMP130_CAL_ADDR (*((uint16_t*)0x1FFF75CA))

0693W00000BabFnQAJ.jpgTherefore the calculation should be :

        fCalTemperature_DegreeCelsius = (((130.0f - 30.0f) / (TEMP130_CAL_ADDR - TEMP30_CAL_ADDR)) * (ADC_TempReading - TEMP30_CAL_ADDR)) + 30.0f;

The problem is that in memory the values don't seem to be correct:

0693W00000BabLqQAJ.jpgI'd appreciate any help.

Thanks,

Mechi

1 ACCEPTED SOLUTION

Accepted Solutions

> Our VREF is 3.3V (factor of 1.1 from 3.0V mentioned).

And then you did not factor it in...

[(130-30) / (1370-1031)] * ((3.3V/3.0V*940 - 1031) + 30 = 30.9

which is a quite reasonable value.

JW

View solution in original post

11 REPLIES 11

The TS_CAL1 and TS_CAL2 values are *halfwords*, so if the above display is the usual little-endian, TS_CAL1 is 0x0407 and TS_CAL2 is 0x055A.

> fCalTemperature_DegreeCelsius = (((130.0f - 30.0f) / (TEMP130_CAL_ADDR - TEMP30_CAL_ADDR)) * (ADC_TempReading - TEMP30_CAL_ADDR)) + 30.0f;

If TEMP130_CAL_ADDR and TEMP30_CAL_ADDR are the *adresses* [EDIT] they are not, see below [/EDIT], then you have to dereference them (i.e. make the compiler to actually *read* from those addresses), i.e. instead of TEMP30_CAL_ADDR use *(uint16_t *)TEMP30_CAL_ADDR and similarly for the other one.

JW

TDK
Guru

Your code should work, despite some misunderstandings in how things are stored.

> #define TEMP30_CAL_ADDR (*((uint16_t*)0x1FFF75A8))

> #define TEMP130_CAL_ADDR (*((uint16_t*)0x1FFF75CA))

These will be evaluated to 0x407 and 0x55A, so they're values not addresses.

What is ADC_TempReading? Also, what is your VREF voltage level? Note that you'll need to adjust the reading if it's not at 3.0V.

It's always useful to say what you actually get vs what you expect instead of just "it doesn't work".

If you feel a post has answered your question, please click "Accept as Solution".

> > #define TEMP30_CAL_ADDR (*((uint16_t*)0x1FFF75A8))

Oh, I overlooked that, sorry. The name of that macro is ... well... not the best chosen one.

And trying to find the source where it came from.. oh, it's Cube... why am I not surprised.

JW

PS. [rant mode on] In a broader scope, this is consequence of ST neglecting maintaining the CMSIS-mandated device headers in a comprehensive and systemic way, here, omitting these addresses from them. Just one more consequence of concentrating on Cube instead of real support. [/rant mode off]

TDK
Guru

> The name of that macro is ... well... not the best chosen one.

> And trying to find the source where it came from.. oh, it's Cube... why am I not surprised.

Not quite. The Cube definitions actually are addresses. They don't match the code in the OP.

#define TEMP30_CAL_ADDR   ((uint16_t*) ((uint32_t)0x1FFF75A8))  /* Internal temperature sensor, parameter TS_CAL1: TS ADC raw data acquired at a temperature of 30 DegC (+-5 DegC) */
#define TEMP110_CAL_ADDR  ((uint16_t*) ((uint32_t)0x1FFF75CA))  /* Internal temperature sensor, parameter TS_CAL2: TS ADC raw data acquired at a temperature of  110 DegC (+-5 DegC) */

If you feel a post has answered your question, please click "Accept as Solution".

Indeed. I didn't look properly again... :blushing:

JW

I'm the one that added in the dereferencing - without changing the name of the macro...

Sorry for the confusion

Piranha
Chief II

Current device header files for F7 series:

#define VREFINT_CAL_ADDR_CMSIS                   ((uint16_t*) (0x1FF0F44A))     /*!<Internal voltage reference, address of parameter VREFINT_CAL: VrefInt ADC raw data acquired at temperature 30 DegC (tolerance: +-5 DegC), Vref+ = 3.3 V (tolerance: +-10 mV).                      */
#define TEMPSENSOR_CAL1_ADDR_CMSIS               ((uint16_t*) (0x1FF0F44C))     /*!<Internal temperature sensor, address of parameter TS_CAL1: On STM32F7, temperature sensor ADC raw data acquired at temperature  30 DegC (tolerance: +-5 DegC), Vref+ = 3.3 V (tolerance: +-10 mV). */
#define TEMPSENSOR_CAL2_ADDR_CMSIS               ((uint16_t*) (0x1FF0F44E))     /*!<Internal temperature sensor, address of parameter TS_CAL2: On STM32F7, temperature sensor ADC raw data acquired at temperature 110 DegC (tolerance: +-5 DegC), Vref+ = 3.3 V (tolerance: +-10 mV). */

@Community member​ , seems they are listening to you - they have added "_CMSIS" to the definition names! :D

Also here is a suggestion for ST - such addresses must be cast to a (const uint16_t *) type. @Imen DAHMEN​ , maybe this can be done... this year? 😉

MFend
Associate III

The data sheet seems to relate to 30°C and 130°C - and not 110°C, as is cited in the code examples.

The ADC readings for temperature are in the range of 935-952 - which makes sense - 940 is lower than 30°C.

Our VREF is 3.3V (factor of 1.1 from 3.0V mentioned).

Without taking the 3.3V into account,

0x407 = 1031 (calibrated at 30°C)

0x55A = 1370 (calibrated at 130°C)

[(130-30) / (1370-1031)] * (940 - 1031) + 30 - I get 3°C.

I'm sitting in a room with 24°C, and the hardware is slightly warm - so this reading doesn't seem correct.

Am I missing something?

Thanks,

Mechi

> Our VREF is 3.3V (factor of 1.1 from 3.0V mentioned).

And then you did not factor it in...

[(130-30) / (1370-1031)] * ((3.3V/3.0V*940 - 1031) + 30 = 30.9

which is a quite reasonable value.

JW