cancel
Showing results for 
Search instead for 
Did you mean: 

STM32H747 Internal Temperature Measurement and Calculation

yhplx
Associate II

Hello, Friends,

I am using ADC(16 bit) to measure the STM32H747 Internal Temperature and VrefInt based on external reference voltage (VDDA 3.3V, Vref+ 2.5V). The VrefInt result is 1.221V, which looks good. However, the temperature result is 150C, which seems not correct.

From the STM32H747xl/G datasheet, there are temperature sensor calibration values TS_CAL1(30C) and TS_CAL2(130C). The formular to get real temperature is (130-30)*(myADCValue-TS_CAL1)/(TS_CAL2-TS_CAL1)+30.

Here are my questions: 1) Is the formular correct? 2)Which reference voltage value is used when TS_CAL2/TS_CAL1 values are read during the calibration? I am using 2.5V external voltage in my design. 

 

Regards,

YH

 

 

 

 

 

1 ACCEPTED SOLUTION

Accepted Solutions

> (100 * ((ts_data*33/25) - ts_cal1)) / (ts_cal2 - ts_cal1) + 30 = 291 C

Should be

(100 * ((ts_data*25/33) - ts_cal1)) / (ts_cal2 - ts_cal1) + 30 = 45 C

 

45 C seems right.

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

View solution in original post

7 REPLIES 7
Rob Ashworth
Senior

This is my function...

Read the parameters stored at the calibration address to get the offsets, and then calculate the slope.

GET_TEMPERATURE is the ADC value.

Don't forget to configure the ADC channel for internal temperature also.

 

 

float InternalTemperature(void)
{
	float Temp;
	s16 Offset;
	s16 dT,dx;
    s16 NewADCTemp;

	dx=T2-T1;
	dT=TEMPSENSOR_CAL2_TEMP-TEMPSENSOR_CAL1_TEMP;
	Offset=TEMPSENSOR_CAL1_TEMP;
	NewADCTemp=GET_TEMPERATURE();//The Raw value
	Temp=(dT*(T2-NewADCTemp))/dx+Offset;//DegC - Nearest Integer
    return Temp;
}

 

 

ADC config:

 

 

	hadc1.Instance = ADC1;
	hadc1.Init.ClockPrescaler        = ADC_CLOCKPRESCALER_PCLK_DIV4;
	hadc1.Init.Resolution            = ADC_RESOLUTION_12B;
	hadc1.Init.ScanConvMode          = DISABLE;
	hadc1.Init.ContinuousConvMode    = ENABLE;
	hadc1.Init.DiscontinuousConvMode = DISABLE;
	hadc1.Init.NbrOfDiscConversion   = 0;
	hadc1.Init.ExternalTrigConvEdge  = ADC_EXTERNALTRIGCONVEDGE_NONE;
	hadc1.Init.ExternalTrigConv      = ADC_SOFTWARE_START;//ADC_EXTERNALTRIGCONV_T1_CC1;
	hadc1.Init.DataAlign             = ADC_DATAALIGN_RIGHT;
	hadc1.Init.NbrOfConversion       = 1;
	hadc1.Init.DMAContinuousRequests = DISABLE;
	hadc1.Init.EOCSelection          = DISABLE;


	if (HAL_ADC_Init(&hadc1) != HAL_OK)
	{
		//Error_Handler();
	}

	/**Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time.
	*/

	  sConfig.Channel = ADC_CHANNEL_TEMPSENSOR;
	  sConfig.Rank = 1;
	  sConfig.SamplingTime = ADC_SAMPLETIME_480CYCLES;//was 480
	  sConfig.Offset = 0;
	  if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
	  {
//	    Error_Handler();
	  }

	  if(HAL_ADC_Start(&hadc1) != HAL_OK)
	    {
	      /* Start Conversation Error */
//	      Error_Handler();
	    }

	  HAL_ADC_PollForConversion(&hadc1, 10);


	    T1=*((uint16_t*)0x1FFF7A2EU);//@30C
	    T2=*((uint16_t*)0x1FFF7A2CU);//@110C

 

 

Hi Rob, 

Thank you for the reply. I am pretty sure my ADC set up is OK because it gets correct VrefInt  values(1.221V) now. My main concerns are those temperature calibration values from the data sheet. Are they based on some internal reference voltages (2.5/2.048/1.8/1.5) during the calibration measurement?  My ADC design is using 2.5V external voltage(VREFBUF_CSR setting is 0x02, HIZ =1, ENVR = 0). I am guessing the ADC reference voltage makes the difference. 

yhplx_0-1722269106756.png

 

Hmm, yes you are right I think - if Vref is not 3.3V, then you will most likely need to do some scaling.

When I did it, I'm pretty sure I had Vref tied to 3V3.

RM0433  Page 992 of the manual is a little vague to say the least, but TS_CAL1/2 are measured with Vref at 3V3 as far as I can tell.

Have to admit it is a while since I did it, but I did write the values down by hand to do a sanity check on the maths I didn't have my 12 or 16-bit shifts incorrect, and the register values made sense.

I would start by simply factoring the CAL values e.g.

TS_Cal1_New=TSCal_1*Vref/3V3.

There could of course be an offset to apply as well...

 

 

 

TDK
Guru

It should be stated better, but they're taken with VREF+ = VDDA. The specification on VDDA is 3.3 V +/- 10 mV per the datasheet.

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

Hi Rob,

Thank you for the reply. I am using 2.5/3.3 factoring into the calculation temperature

ADC3 read ts_data = 17237

ts_cal1 = 12464 (30 C)

ts_cal2 = 16403 (130 C)

(100 * ((ts_data*33/25) - ts_cal1)) / (ts_cal2 - ts_cal1) + 30 = 291 C

Is this temperature correct? It seems to be too high.

I am using DMA transfer the 4 ranks ADC data. One of the rank is connected to internal Vrefint. It's result is correct because it is close to Vref calibration data from the flash. Hence, I am pretty sure the data reading from ADC channels should be good.

ADC3 read Vrefint = 32025

Vrefint *2500/(0xffff-1) = 1221 mV

Calibration data from flash vr_cal = 24193

vr_cal*3300/(0xffff-1)) = 1218 mV

 

 

 

 

 

 

> (100 * ((ts_data*33/25) - ts_cal1)) / (ts_cal2 - ts_cal1) + 30 = 291 C

Should be

(100 * ((ts_data*25/33) - ts_cal1)) / (ts_cal2 - ts_cal1) + 30 = 45 C

 

45 C seems right.

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

Hi TDK,

Thank you for the reply.