Skip to main content
Visitor II
November 22, 2023
Question

Internal Temperature STM32H7 delivers wrong value

  • November 22, 2023
  • 5 replies
  • 2823 views

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);
}
 

 

    This topic has been closed for replies.

    5 replies

    Visitor II
    November 22, 2023

    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.

    RoniAuthor
    Visitor II
    November 22, 2023

    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

    Super User
    November 22, 2023

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

    Graduate II
    November 22, 2023

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

    RoniAuthor
    Visitor II
    November 23, 2023

    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?

    Technical Moderator
    December 6, 2023

    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: 176763 (This is an internal tracking number and is not accessible or usable by customers).

    Thank you.

    Kaouthar