cancel
Showing results for 
Search instead for 
Did you mean: 

Getting temperature from STM32G491x internal temperature sensor ADC

JBend.6
Associate III

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.

1 ACCEPTED SOLUTION

Accepted Solutions
JBend.6
Associate III

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.

View solution in original post

16 REPLIES 16
Peter BENSCH
ST Employee

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
Associate III

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.

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.
JBend.6
Associate III

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.

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
Associate III

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
Chief II

> 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
Associate III

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).

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