Skip to main content
JBend.6
Associate III
June 6, 2023
Question

Getting temperature from STM32G491x internal temperature sensor ADC

  • June 6, 2023
  • 10 replies
  • 7901 views

How to get temperature (degC) from the STM32G491x internal temperature sensor?

I have my ADC working and producing raw count values. Eg: 303.

So assuming a working voltage of 3V3 and maximum count value of 4095 then I assume that I must multiply the raw count value by (3.3 / 4095).

But then what? I cannot find any reference to a gain value.

Also, I understand that calibration is required. I used pointers to dereference the TC_CAL1 and TC_CAL2 addresses given in the DS13122 Rev 3 datasheet. (0x1FFF 75A8 - 0x1FFF 75A9).

	uint8_t * TC_CAL1;
	uint8_t * TC_CAL2;
 
	TC_CAL1 = 0x1FFF75A9;
	TC_CAL2 = 0x1FFF75A8;
 
	Calibration1 = *TC_CAL1;
	Calibration2 = *TC_CAL2;

Although the documentation does not say, I assume that these are the high and low values of a 16-bit value?

Then question is how to apply the calibration value? Should I add or subtract it from the final value derived from the raw value?

Please help.

This topic has been closed for replies.

10 replies

Peter BENSCH
ST Technical Moderator
June 6, 2023

Welcome, @JB.16​, to the community!

First of all, a small correction: you have not interpreted the addresses of the two calibration values correctly. DS13122, Table 5 lists the 16-bit values:

  • TS_CAL1 = 0x1FFF 75A8...0x1FFF 75A9
  • TS_CAL2 = 0x1FFF 75CA...0x1FFF 75CB

Secondly, there is a detailed description in RM0440, section 21.4.31 on how to read the internal temperature sensor.

Note: please do not forget to calibrate it when you start the programme so that you get the maximum possible accuracy.

Hope that helps?

Regards

/Peter

In order to give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.
JBend.6
JBend.6Author
Associate III
June 7, 2023

Thank you Peter.

So I can get the calibration values as follows:

	int16_t TC_CAL1 = *(int16_t *)0x1FFF75A8;
	int16_t TC_CAL2 = *(int16_t *)0x1FFF75CA;

I had forgotten about the description in RM0440 on how to use the temperature sensor. The only issue being the formula which contains TS_CAL1_TEMP and TS_CAL2_TEMP in addition to TS_CAL1 and TS_CAL2.

Am I correct that these refer to the temperature at which the calibrations were made (as given in Table 5 of DS13122 Rev 3)?

Thanks again.

Peter BENSCH
ST Technical Moderator
June 7, 2023

This is also mentioned at the very bottom of RM0440, section 21.4.31:

  • TS_CAL2 is the temperature sensor calibration value acquired at TS_CAL2_TEMP.
  • TS_CAL1 is the temperature sensor calibration value acquired at TS_CAL1_TEMP

So yes, TS_CALx_TEMP refer to the temperature at which the calibrations were made and which is given in table 5 of the data sheet.

Regards

/Peter

In order to give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.
CVan.18
Associate
September 20, 2023

Datasheet temperature slope values don't match calibration values stored in part.  My STM32L072CZT6 is reading the calibration values stored in TS_CAL1&2 as 675mV (@30°C) and 911mV (@130°C).  Using these values gives me a slope of 2.36mV/°C.  The datasheet shows a nominal slope of 1.61mV/°C.  

I have a problem with my readings, too.  When I set my VDD to 3.0V (calibration conditions) and adjust my MCU temperature to 30°C, I get 604mV from the temperature sensor reading.  The stored calibration value for this condition reads as 675mV.  Can you help me resolve these differences?

Thanks,
Carl

JBend.6
JBend.6Author
Associate III
June 7, 2023

Thank you for the confirmation Peter.

One last question...

The documentation instructs us to "wake" the temperature sensor by setting the VSENSESEL bit in the ADCx_CCR register. Since I am using ADC channel #5 I assume this means ADC345_CCR:VSENSESEL (bit-23).

Is there a HAL function that I should use to do this?

Must I enable VSENSESEL for each time I trigger a temperature sensor read?

Thank you.

Peter BENSCH
ST Technical Moderator
June 7, 2023

Well, you can switch the temperature sensor on and off directly with the VSENSESEL bit, e.g. with

  • LL_ADC_SetCommonPathInternalChAdd() or
  • LL_ADC_SetCommonPathInternalChRem(),

which are defined in stm32g4xx_ll_adc.h.

This makes sense, among other things, because the sensor requires significant power in this ultra-low power design. In this respect, you should switch it off again after the measurement process if you have to pay attention to the power consumption.

If the problem is solved, please mark this thread as answered by selecting Select as best, as also explained here. This will help other users find that answer faster.

Good luck!

/Peter

In order to give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.
JBend.6
JBend.6Author
Associate III
June 7, 2023

Following your information I am now executing the following code every 1-second:

LL_ADC_SetCommonPathInternalChAdd(ADC345_COMMON_BASE, LL_ADC_PATH_INTERNAL_TEMPSENSOR);
HAL_ADC_Start_IT(&hadc5);

As far as I can determine this should wake the temperature sensor and trigger an ADC read. Read completion then triggers an IRQ where:

HAL_ADC_GetValue(&hadc5)

Returns zero.

Piranha
Principal III
June 7, 2023

> multiply the raw count value by (3.3 / 4095)

It has to be divided by the number of steps (4096), not the maximum value.

JBend.6
JBend.6Author
Associate III
June 8, 2023

Thank you, Piranha.

The issue is that I am not getting any raw values because I don't understand how to enable the Temperature sensor.

The documentation instructs us to "wake" the temperature sensor by setting the VSENSESEL bit in the ADCx_CCR register. Since I am using ADC channel #5 I assume this means ADC345_CCR:VSENSESEL (bit-23).

waclawek.jan
Super User
June 8, 2023

The temperature sensor is not at channel #5. If you mean ADC5, temperature sensor is at channel 4:

Strangely, in RM, this information is *not* in the Temperature sensor subchapter in ADC chapter as one normally would expect (@Peter BENSCH​ , can't folks responsible please be told that this is ehm not optimal?); nonetheless, Channel selection subchapter says this:

The internal temperature sensor (VTS) is connected to ADC1_INP16 and ADC5_INP4

JW

Peter BENSCH
ST Technical Moderator
June 8, 2023

@Community member​ Good point, in fact I hadn't noticed that before and it should definitely be corrected.

Thanks

/Peter

@Imen DAHMEN​ 

In order to give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.
ST Technical Moderator
June 8, 2023

Hello All,

Thank you for rising this up.

Internal ticket (ID 154420) is submitted for correction.

Thanks

Imen

In order to give better visibility on the answered topics, please click on 'Best answer' on the reply which solved your issue or answered your question. Thanks
JBend.6
JBend.6Author
Associate III
June 8, 2023

Sorry for the confusion.

Yes, I am trying to use Temperature Sensor Channel with ADC5.

However, the issue is how to enable the VSENSESEL bit? Trawling through documentation the only reference I could find was LL call as follows:

LL_ADC_SetCommonPathInternalChAdd(ADCxy_COMMON *, LL_ADC_PATH_INTERNAL_TEMPSENSOR);
HAL_ADC_Start_IT(&hadc5);

Assuming this is the correct approach to enabling the VSENSESEL bit and thus waking the Temperature Sensor...

What value am I supposed to provide for "ADCxy_COMMON *".

I find many references to this "ADC_Common_TypeDef" but no explanation.

Help!.

JBend.6
JBend.6Author
Associate III
June 9, 2023

So after days trying to get this to work, it seems that ADC5 cannot be used for on-board Temperature Sensor on the STM32G474RETx.

It is working fine on ADC1.

waclawek.jan
Super User
June 9, 2023

> on the STM32G474RETx.

So, STM32G491x or STM32G474RETx.?

> it seems that ADC5 cannot be used for on-board Temperature Sensor

On which channel did you try to read?

Read out and check/post content of ADC registers.

JW