cancel
Showing results for 
Search instead for 
Did you mean: 

Internal Temperature STM32H7 delivers wrong value

Roni
Associate II

I read the messages in here about wrong temperature values including code examples, but still getting wrong values:

I need to measure the internal CPU temperature sensor from the STM32H743XIH6. I activated the ADC3 using STM32CUBEMX (V. 6.9.2) and selected Temperature Channel.

However the calculated temperatures are far too high (140-170):

ADC input clock is set to 37.5 MHz

read T1_30 - address: 0x1FF1E820 - getting value: 0x3064

T1_110 - address: 0x1FF1E840 - getting value: 0x4023

reading GetValue - HAL_ADC_GetValue: 0x4783, 0x4a04, 0x4c68

it is grater than T1_110, how come?!

Mpu internal Temperature: GetValue=0x4783, T1_110=0x4023, T1_30=0x3064
Mpu internal Temperature: 147.47

Mpu internal Temperature: GetValue=0x4a04, T1_110=0x4023, T1_30=0x3064
Mpu internal Temperature: 160.19

 

Mpu internal Temperature: GetValue=0x4c68, T1_110=0x4023, T1_30=0x3064
Mpu internal Temperature: 172.34

see code below

Any help is very much appreciated!

thanks in advanced

 
static void MX_ADC3_Init(void)
{
 
  /* USER CODE BEGIN ADC3_Init 0 */
 
  /* USER CODE END ADC3_Init 0 */
 
  ADC_ChannelConfTypeDef sConfig = {0};
 
  /* USER CODE BEGIN ADC3_Init 1 */
 
  /* USER CODE END ADC3_Init 1 */
 
  /** Common config
  */
  hadc3.Instance = ADC3;
  hadc3.Init.Resolution = ADC_RESOLUTION_16B;
  hadc3.Init.ScanConvMode = ADC_SCAN_DISABLE;
  hadc3.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
  hadc3.Init.LowPowerAutoWait = DISABLE;
  hadc3.Init.ContinuousConvMode = DISABLE;
  hadc3.Init.NbrOfConversion = 1;
  hadc3.Init.DiscontinuousConvMode = DISABLE;
  hadc3.Init.NbrOfDiscConversion = 1;
  hadc3.Init.ExternalTrigConv = ADC_SOFTWARE_START;
  hadc3.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
  hadc3.Init.ConversionDataManagement = ADC_CONVERSIONDATA_DR;
  hadc3.Init.Overrun = ADC_OVR_DATA_OVERWRITTEN;
  hadc3.Init.LeftBitShift = ADC_LEFTBITSHIFT_NONE;
  hadc3.Init.OversamplingMode = ENABLE;
  hadc3.Init.Oversampling.Ratio = 256;
  hadc3.Init.Oversampling.RightBitShift = ADC_RIGHTBITSHIFT_4;
  hadc3.Init.Oversampling.TriggeredMode = ADC_TRIGGEREDMODE_SINGLE_TRIGGER;
  hadc3.Init.Oversampling.OversamplingStopReset = ADC_REGOVERSAMPLING_CONTINUED_MODE;
  if (HAL_ADC_Init(&hadc3) != HAL_OK)
  {
    Error_Handler();
  }
 
  /** Configure Regular Channel
  */
  sConfig.Channel = ADC_CHANNEL_TEMPSENSOR;
  sConfig.Rank = ADC_REGULAR_RANK_1;
  sConfig.SamplingTime = ADC_SAMPLETIME_387CYCLES_5;
  sConfig.SingleDiff = ADC_SINGLE_ENDED;
  sConfig.OffsetNumber = ADC_OFFSET_NONE;
  sConfig.Offset = 0;
  sConfig.OffsetSignedSaturation = DISABLE;
  if (HAL_ADC_ConfigChannel(&hadc3, &sConfig) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN ADC3_Init 2 */
 
  /* USER CODE END ADC3_Init 2 */
 
}
 
uint16_t ReadSingleA2D(void)
{
ADC_ChannelConfTypeDef sConfig;
HAL_StatusTypeDef err;
 
 
ADC_HandleTypeDef *hadc;
hadc = &hadc3;
 
/** Configure Regular Channel
*/
sConfig.Channel = ADC_CHANNEL_TEMPSENSOR;
sConfig.Rank = ADC_REGULAR_RANK_1;
sConfig.SamplingTime = ADC_SAMPLETIME_387CYCLES_5;
sConfig.SingleDiff = ADC_SINGLE_ENDED;
sConfig.OffsetNumber = ADC_OFFSET_NONE;
sConfig.Offset = 0;
sConfig.OffsetSignedSaturation = DISABLE;
 
 
// The ADC Boost mode can be controlled through the BOOST bit in the ADC_CR register.
// This bit must be set according to the ADC clock setting. Refer to the ADC_CR register description.
LL_ADC_SetBoostMode(hadc->Instance, LL_ADC_BOOST_MODE_50MHZ);
 
if((err=HAL_ADCEx_Calibration_Start(hadc, ADC_CALIB_OFFSET, ADC_SINGLE_ENDED)) != HAL_OK)
{
ErrorHandler(__FUNCTION__, __LINE__, (char *)"ADC Calibration error=%d", err);
}
if ((err=HAL_ADC_ConfigChannel(hadc, &sConfig)) != HAL_OK)
{
ErrorHandler(__FUNCTION__, __LINE__, (char *)"ADC Config Channel error=%d", err);
}
if ((err=HAL_ADC_Start(hadc)) != HAL_OK)
{
ErrorHandler(__FUNCTION__, __LINE__, (char *)"ADC Start error=%d", err);
}
// wait for the end of conversion
if ((err=HAL_ADC_PollForConversion(hadc, 100)) != HAL_OK)
{
ErrorHandler(__FUNCTION__, __LINE__, (char *)"ADC end of Conversion error=%d", err);
}
 
return HAL_ADC_GetValue(hadc);
}
 
void GetMPUTemperature(void)
{
double CelsiusTemperature = 0.0;
uint32_t GetValue = 0;
 
// read the calibation values
uint32_t T1_30 = (uint32_t) *TEMPSENSOR_CAL1_ADDR;
uint32_t T1_110 = (uint32_t) *TEMPSENSOR_CAL2_ADDR;
 
// read the temperature
GetValue = ReadSingleA2D(MPU_INTERNAL_TEMPERATURE);
 
//calculate the temperature in (in °C)
// Analog-to-digital converters (ADC)
// Temperature (in °C) = ((110 °C – 30 °C)/(TS_CAL2 – TS_CAL1))× (TS_DATA – TS_CAL1) + 30 °C
CelsiusTemperature = ( (((double)(110 - 30))/((double)(T1_110 - T1_30))) * ((double)(GetValue - T1_30)) ) + ((double)30);
 
ErrorHandler(__FUNCTION__, __LINE__,(char *) "Mpu internal Temperature: GetValue=0x%x, T1_110=0x%x, T1_30=0x%x", GetValue, T1_110, T1_30);
ErrorHandler(__FUNCTION__, __LINE__,(char *) "Mpu internal Temperature: %.2f", CelsiusTemperature);
}
 

 

6 REPLIES 6
liaifat85
Senior II

You can Use HAL_ADC_GetState to check the ADC state during different stages of your code execution. This can help identify where the issue might be occurring.

it seems the state is 0x0201 all the time:

#define HAL_ADC_STATE_REG_EOC           (0x00000200UL)   /*!< Conversion data available on group regular */

#define HAL_ADC_STATE_READY             (0x00000001UL)   /*!< ADC peripheral ready for use */

but the case after I call HAL_ADC_Start:

the state is 0x0100:

#define HAL_ADC_STATE_REG_BUSY          (0x00000100UL)   /*!< A conversion on ADC group regular is ongoing or can occur (either by continuous mode, external trigger, low power auto power-on (if feature available), multimode ADC master control (if feature available)) */

 

looks O.K

TDK
Guru

What board is this? What is VREF+ on your board?

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

The TS_CAL2 values are different between rev Y and rev V devices.  See the Data Sheet Sections 6 and 7.

Roni
Associate II

I disabled the OversamplingMode and now reading GetValue - HAL_ADC_GetValue: 0x351a, 3527

which is Mpu internal Temperature: 53-54 degrees

is this make sense?

KDJEM.1
ST Employee

Hi @Roni and welcome to the community 🙂,

For the Oversampling Mode issue, this is a known issue, already reported in STM32H723 ADC Oversampling code generation bug - STMicroelectronics Community.

This code line in generation code is wrong: 

 

  hadc3.Init.Oversampling.Ratio = 256;

 

  and should be 

 

hadc3.Init.Oversampling.Ratio = ADC3_OVERSAMPLING_RATIO_256;

 

 

Internal ticket number: 163742 (This is an internal tracking number and is not accessible or usable by customers).

Thank you.

Kaouthar

 

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.