cancel
Showing results for 
Search instead for 
Did you mean: 

STM32H7 on-chip temperature sensor reading stable on 'Y' revision, but unstable on 'V' revision chip

Jack3
Senior II

using the STM32H753VIT6, I like to monitor the on-chip temperature sensor. The environmental temperature can become about 50 degrees Celsius, and the board is housed is a small plastic (DIN-rail) enclosure. This enclosure is fitted in a metal cabinet.

The measurement worked stable on a revision 'Y' of the STM32H7, but now I finally got the recommended revision 'V' of the MCU, where the reading is very unstable, when reading every second. It may vary more than 15 degrees Celsius between two readings.

The board design did not change.

On the other hand, there are differences between the ADC peripheral registers between the 'Y' and 'V' versions. I have read AN5312 Migration from RevY to RevV for STM32H7xx Value line microcontrollers: https://www.st.com/resource/en/application_note/dm00609692.pdf

And I also checked the errata sheet: https://www.st.com/resource/en/errata_sheet/dm00368411.pdf

Is anybody able to get stable reading from the internal temperature sensor?

My ADC init:

/* ADC3 init function */
void MX_ADC3_Init(void)
{
  ADC_ChannelConfTypeDef sConfig = {0};
 
  /* Common config */
  hadc3.Instance = ADC3;
  hadc3.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV64;
  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 = ENABLE;
  hadc3.Init.NbrOfConversion = 1;
  hadc3.Init.DiscontinuousConvMode = DISABLE;
  hadc3.Init.ExternalTrigConv = ADC_SOFTWARE_START;
  hadc3.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
  hadc3.Init.ConversionDataManagement = ADC_CONVERSIONDATA_DR;
  hadc3.Init.Overrun = ADC_OVR_DATA_PRESERVED;
  hadc3.Init.LeftBitShift = ADC_LEFTBITSHIFT_NONE;
  hadc3.Init.OversamplingMode = DISABLE;
  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_810CYCLES_5;
  sConfig.SingleDiff = ADC_SINGLE_ENDED;
  sConfig.OffsetNumber = ADC_OFFSET_NONE;
  sConfig.Offset = 0;
  if (HAL_ADC_ConfigChannel(&hadc3, &sConfig) != HAL_OK)
  {
    Error_Handler();
  }
}

Initialisation function:

void MCU_TemperatureInit(void)
{
    HAL_ADCEx_Calibration_Start(&hadc3, ADC_CALIB_OFFSET, ADC_SINGLE_ENDED);
 
    HAL_ADC_Start_IT(&hadc3);
}
 

The value is read from the interrupt:

ADC_Value = HAL_ADC_GetValue(&hadc3);

The calculation done on the value:

uint16_t MCU_TemperatureCalculate(uint32_t ts_data)
{
  // 0x1FF1E820 Calibration ADC value at 30 °C = 0x2fc0, 12224
  uint16_t ts_cal1 = *(uint16_t*) (TS_CAL1_REG);
  // 0x1FF1E840 Calibration ADC value at 110 °C = 0x3cb4, 15540
  uint16_t ts_cal2 = *(uint16_t*) (TS_CAL2_REG);
 
  return (80 * (ts_data - ts_cal1)) / (ts_cal2 - ts_cal1) + 30;
}
 

I tried different values for ClockPrescaler and SamplingTime as well as different PLL settings for the ADC, but it did not improve.

What can I do to get stable readings, like on the 'Y' version? Any help would be appreciated.

Heavy filtering seems to work, but I wonder if something could be wrong.

11 REPLIES 11
jakob.brunhart
Associate III

Hello Jack

I am (still) using version Y and can confirm that the measurement is stable. I'm just astonished about the temperature. Namely 165°C. Could that be? How high are the temperatures you are measuring?

The manual says the following: The temperature sensor can measure the junction temperature (TJ) of the device in the -40 to 125 °C temperature range.

Regards

Jakob

Jack3
Senior II

Hi Jakob, did you also call below function to calibrate the ADC?

HAL_ADCEx_Calibration_Start(&hadc3, ADC_CALIB_OFFSET, ADC_SINGLE_ENDED);

I don't know if your calculation is correct.

Assuming you read 16-bit values (and ADC in 16-bit mode), you could instead also map the measured ADC value to the stored values for 30 and 110 degrees Celsius.

uint16_t MCU_MapValue(uint16_t in_value, uint16_t in_min, uint16_t in_max, uint16_t out_min, uint16_t out_max)
{
  return (in_value - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}
 
uint16_t MCU_TemperatureCalculate(uint16_t ts_data)
{
  /* 0x1FF1E820 Calibration ADC value at 30 °C = 0x2fc0, 12224 */
  uint16_t ts_cal1 = *(uint16_t*) (TS_CAL1_REG);
  /* 0x1FF1E840 Calibration ADC value at 110 °C = 0x3cb4, 15540 */
  uint16_t ts_cal2 = *(uint16_t*) (TS_CAL2_REG);
 
//  return (80 * (ts_data - ts_cal1)) / (ts_cal2 - ts_cal1) + 30;
 
  return MCU_MapValue(ts_data, ts_cal1, ts_cal2, 30, 110);
}

Does that help?

jakob.brunhart
Associate III

Hello Jack

Thank you for your fast response.

  • Yes I call the calibration function once.
  • ADC resolution is set to 16Bit.

I don't understand the difference between the function MCU_MapValue() and the commented return value in MCU_MapValue(). Is it not the same?

(in_value - in_min) => ts_data - ts_cal1;

(out_max - out_min) => 80;

(in_max - in_min) => (ts_cal2 - ts_cal1)

out_min => 30;

For the calibration values I got the following:

TS_CAL1: 12168

TS_CAL2: 15379

The adcValue is: 17661

And the calculation:

temperature = (int16_t)( ( 110UL - 30UL ) * ( adcValue - TS_CAL1 ) / ( TS_CAL2 - TS_CAL1 ) + 30UL ) ;

This results in 166

Any idea?

Thank you

Jakob

Hi Jakob

from your values:

For the calibration values I got the following:

TS_CAL1: 12168 /* for 30 degrees Celsius */

TS_CAL2: 15379 /* for 110 degrees Celsius */

With a reading of the adcValue is: 17661, I can see your calculation is right, and this means you read indeed 166 degrees Celsius.

Are your clock dividers for the ADC correct (also check SystemClock_Config)? It may be too fast or the conversion is not ready when reading the value.

  

You may check it best in STM32CubeMX, I think. My board uses a 25MHz crystal.

/**
  * @brief System Clock Configuration
  * @retval None
  */
void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
  RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};
 
  /* Supply configuration update enable */
  HAL_PWREx_ConfigSupply(PWR_LDO_SUPPLY);
  /* Configure the main internal regulator output voltage */
  __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
 
  while(!__HAL_PWR_GET_FLAG(PWR_FLAG_VOSRDY)) {}
 
  /* Macro to configure the PLL clock source */
  __HAL_RCC_PLL_PLLSOURCE_CONFIG(RCC_PLLSOURCE_HSE);
 
  /* Initializes the CPU, AHB and APB busses clocks */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI48 | RCC_OSCILLATORTYPE_LSI | RCC_OSCILLATORTYPE_HSE;
  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  RCC_OscInitStruct.LSIState = RCC_LSI_ON;
  RCC_OscInitStruct.HSI48State = RCC_HSI48_ON;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  RCC_OscInitStruct.PLL.PLLM = 4;   /* 25MHz / 4 = 6.25MHz */
  RCC_OscInitStruct.PLL.PLLN = 128; /* 6.25MHz * 128 = 800MHz */
  RCC_OscInitStruct.PLL.PLLP = 2;   /* 800MHz / 2 = 400MHz */
  RCC_OscInitStruct.PLL.PLLQ = 8;   /* 800MHz / 8 = 100MHz, 2 - 64 SDMMC1 8 = 100MHz SDMMC1 (Fastest), Highest 128 */
  RCC_OscInitStruct.PLL.PLLR = 2;
  RCC_OscInitStruct.PLL.PLLRGE = RCC_PLL1VCIRANGE_2;
  RCC_OscInitStruct.PLL.PLLVCOSEL = RCC_PLL1VCOWIDE;
  RCC_OscInitStruct.PLL.PLLFRACN = 0;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }
  /* Initializes the CPU, AHB and APB busses clocks */
  RCC_ClkInitStruct.ClockType =
      RCC_CLOCKTYPE_HCLK |
      RCC_CLOCKTYPE_SYSCLK |
      RCC_CLOCKTYPE_PCLK1 |
      RCC_CLOCKTYPE_PCLK2 |
      RCC_CLOCKTYPE_D3PCLK1 |
      RCC_CLOCKTYPE_D1PCLK1;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.SYSCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_HCLK_DIV2;
  RCC_ClkInitStruct.APB3CLKDivider = RCC_APB3_DIV2;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_APB1_DIV2;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_APB2_DIV2;
  RCC_ClkInitStruct.APB4CLKDivider = RCC_APB4_DIV2;
  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
  {
    Error_Handler();
  }
 
  PeriphClkInitStruct.PeriphClockSelection =
      RCC_PERIPHCLK_RTC |
      RCC_PERIPHCLK_USART2 |
      RCC_PERIPHCLK_UART7 |
      RCC_PERIPHCLK_FDCAN |
      RCC_PERIPHCLK_RNG |
      RCC_PERIPHCLK_SPI4 |
      RCC_PERIPHCLK_SPI1 |
      RCC_PERIPHCLK_SDMMC |
      RCC_PERIPHCLK_ADC |
      RCC_PERIPHCLK_I2C4 |
      RCC_PERIPHCLK_USB |
      RCC_PERIPHCLK_QSPI;
  PeriphClkInitStruct.PLL2.PLL2M = 4;
  PeriphClkInitStruct.PLL2.PLL2N = 128;
  PeriphClkInitStruct.PLL2.PLL2P = 2;
  PeriphClkInitStruct.PLL2.PLL2Q = 80;  /* fdcan_ker_ck = 10 MHz, FDCAN: 800MHz / 80 = 10MHz */
  PeriphClkInitStruct.PLL2.PLL2R = 2;
  PeriphClkInitStruct.PLL2.PLL2RGE = RCC_PLL2VCIRANGE_2;
  PeriphClkInitStruct.PLL2.PLL2VCOSEL = RCC_PLL2VCOWIDE;
  PeriphClkInitStruct.PLL2.PLL2FRACN = 0;
 
  PeriphClkInitStruct.PLL3.PLL3M = 4;
  PeriphClkInitStruct.PLL3.PLL3N = 128;
  PeriphClkInitStruct.PLL3.PLL3P = 2;
  PeriphClkInitStruct.PLL3.PLL3Q = 2;
  PeriphClkInitStruct.PLL3.PLL3R = 32;  /* ADC: 8 @ 100MHz, 32 @ 25MHz */
  PeriphClkInitStruct.PLL3.PLL3RGE = RCC_PLL3VCIRANGE_2;
  PeriphClkInitStruct.PLL3.PLL3VCOSEL = RCC_PLL3VCOWIDE;
  PeriphClkInitStruct.PLL3.PLL3FRACN = 0;
 
  PeriphClkInitStruct.QspiClockSelection = RCC_QSPICLKSOURCE_D1HCLK;
  PeriphClkInitStruct.SdmmcClockSelection = RCC_SDMMCCLKSOURCE_PLL;
  PeriphClkInitStruct.Spi123ClockSelection = RCC_SPI123CLKSOURCE_PLL;
  PeriphClkInitStruct.Spi45ClockSelection = RCC_SPI45CLKSOURCE_D2PCLK1;
  PeriphClkInitStruct.FdcanClockSelection = RCC_FDCANCLKSOURCE_PLL2; /* Before RCC_FDCANCLKSOURCE_PLL */
  PeriphClkInitStruct.Usart234578ClockSelection = RCC_USART234578CLKSOURCE_D2PCLK1;
  PeriphClkInitStruct.RngClockSelection = RCC_RNGCLKSOURCE_HSI48;
  PeriphClkInitStruct.UsbClockSelection = RCC_USBCLKSOURCE_HSI48;
  PeriphClkInitStruct.I2c4ClockSelection = RCC_I2C4CLKSOURCE_D3PCLK1;
  PeriphClkInitStruct.AdcClockSelection = RCC_ADCCLKSOURCE_PLL3;
  PeriphClkInitStruct.RTCClockSelection = RCC_RTCCLKSOURCE_LSI;
  if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)
  {
    Error_Handler();
  }
 
  /* Enable USB Voltage detector */
  HAL_PWREx_EnableUSBVoltageDetector();
}

Note

PeriphClkInitStruct.AdcClockSelection = RCC_ADCCLKSOURCE_PLL3;
  PeriphClkInitStruct.PLL3.PLL3R = 32;  /* ADC: 8 @ 100MHz, 32 @ 25MHz */

jakob.brunhart
Associate III

Hi Jack

Here is the configruation of ADC3. I use 5 channels in regular mode to measrue some voltages (3V3, 5V0, 7V0, ... ). The temperature channel is set to injected mode. The Clock prescaler is set to 10. The sample time is set to 387.5 cycles.

/* ADC3 init function */
void MX_ADC3_Init(void)
{
  ADC_InjectionConfTypeDef sConfigInjected = {0};
  ADC_ChannelConfTypeDef sConfig = {0};
 
  /** Common config 
  */
  hadc3.Instance = ADC3;
  hadc3.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV10;
  hadc3.Init.Resolution = ADC_RESOLUTION_16B;
  hadc3.Init.ScanConvMode = ADC_SCAN_ENABLE;
  hadc3.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
  hadc3.Init.LowPowerAutoWait = DISABLE;
  hadc3.Init.ContinuousConvMode = DISABLE;
  hadc3.Init.NbrOfConversion = 5;
  hadc3.Init.DiscontinuousConvMode = DISABLE;
  hadc3.Init.ExternalTrigConv = ADC_SOFTWARE_START;
  hadc3.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
  hadc3.Init.ConversionDataManagement = ADC_CONVERSIONDATA_DMA_ONESHOT;
  hadc3.Init.Overrun = ADC_OVR_DATA_PRESERVED;
  hadc3.Init.LeftBitShift = ADC_LEFTBITSHIFT_NONE;
  hadc3.Init.OversamplingMode = DISABLE;
  if (HAL_ADC_Init(&hadc3) != HAL_OK)
  {
    Error_Handler();
  }
  /** Disable Injected Queue 
  */
  HAL_ADCEx_DisableInjectedQueue(&hadc3);
  /** Configure Injected Channel 
  */
  sConfigInjected.InjectedChannel = ADC_CHANNEL_TEMPSENSOR;
  sConfigInjected.InjectedRank = ADC_INJECTED_RANK_1;
  sConfigInjected.InjectedSamplingTime = ADC_SAMPLETIME_387CYCLES_5;
  sConfigInjected.InjectedSingleDiff = ADC_SINGLE_ENDED;
  sConfigInjected.InjectedOffsetNumber = ADC_OFFSET_NONE;
  sConfigInjected.InjectedOffset = 0;
  sConfigInjected.InjectedLeftBitShift = ADC_LEFTBITSHIFT_NONE;
  sConfigInjected.InjectedNbrOfConversion = 1;
  sConfigInjected.InjectedDiscontinuousConvMode = DISABLE;
  sConfigInjected.AutoInjectedConv = DISABLE;
  sConfigInjected.QueueInjectedContext = DISABLE;
  sConfigInjected.ExternalTrigInjecConv = ADC_INJECTED_SOFTWARE_START;
  sConfigInjected.ExternalTrigInjecConvEdge = ADC_EXTERNALTRIGINJECCONV_EDGE_NONE;
  sConfigInjected.InjecOversamplingMode = DISABLE;
  if (HAL_ADCEx_InjectedConfigChannel(&hadc3, &sConfigInjected) != HAL_OK)
  {
    Error_Handler();
  }
  /** Configure Regular Channel 
  */
  sConfig.Channel = ADC_CHANNEL_1;
  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;
  if (HAL_ADC_ConfigChannel(&hadc3, &sConfig) != HAL_OK)
  {
    Error_Handler();
  }
  /** Configure Regular Channel 
  */
  sConfig.Channel = ADC_CHANNEL_0;
  sConfig.Rank = ADC_REGULAR_RANK_2;
  if (HAL_ADC_ConfigChannel(&hadc3, &sConfig) != HAL_OK)
  {
    Error_Handler();
  }
  /** Configure Regular Channel 
  */
  sConfig.Channel = ADC_CHANNEL_10;
  sConfig.Rank = ADC_REGULAR_RANK_3;
  if (HAL_ADC_ConfigChannel(&hadc3, &sConfig) != HAL_OK)
  {
    Error_Handler();
  }
  /** Configure Regular Channel 
  */
  sConfig.Channel = ADC_CHANNEL_4;
  sConfig.Rank = ADC_REGULAR_RANK_4;
  if (HAL_ADC_ConfigChannel(&hadc3, &sConfig) != HAL_OK)
  {
    Error_Handler();
  }
  /** Configure Regular Channel 
  */
  sConfig.Channel = ADC_CHANNEL_9;
  sConfig.Rank = ADC_REGULAR_RANK_5;
  if (HAL_ADC_ConfigChannel(&hadc3, &sConfig) != HAL_OK)
  {
    Error_Handler();
  }
 
}

The ADC clock selction is set to pll2 and 150MHz.

void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
  RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};
 
  /** Supply configuration update enable 
  */
  HAL_PWREx_ConfigSupply(PWR_LDO_SUPPLY);
  /** Configure the main internal regulator output voltage 
  */
  __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
 
  while(!__HAL_PWR_GET_FLAG(PWR_FLAG_VOSRDY)) {}
  /** Configure LSE Drive Capability 
  */
  HAL_PWR_EnableBkUpAccess();
  __HAL_RCC_LSEDRIVE_CONFIG(RCC_LSEDRIVE_LOW);
  /** Macro to configure the PLL clock source 
  */
  __HAL_RCC_PLL_PLLSOURCE_CONFIG(RCC_PLLSOURCE_HSE);
  /** Initializes the CPU, AHB and APB busses clocks 
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSI|RCC_OSCILLATORTYPE_HSE
                              |RCC_OSCILLATORTYPE_LSE;
  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  RCC_OscInitStruct.LSEState = RCC_LSE_ON;
  RCC_OscInitStruct.LSIState = RCC_LSI_ON;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  RCC_OscInitStruct.PLL.PLLM = 1;
  RCC_OscInitStruct.PLL.PLLN = 50;
  RCC_OscInitStruct.PLL.PLLP = 2;
  RCC_OscInitStruct.PLL.PLLQ = 2;
  RCC_OscInitStruct.PLL.PLLR = 2;
  RCC_OscInitStruct.PLL.PLLRGE = RCC_PLL1VCIRANGE_3;
  RCC_OscInitStruct.PLL.PLLVCOSEL = RCC_PLL1VCOWIDE;
  RCC_OscInitStruct.PLL.PLLFRACN = 0;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }
  /** Initializes the CPU, AHB and APB busses clocks 
  */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2
                              |RCC_CLOCKTYPE_D3PCLK1|RCC_CLOCKTYPE_D1PCLK1;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.SYSCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_HCLK_DIV2;
  RCC_ClkInitStruct.APB3CLKDivider = RCC_APB3_DIV2;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_APB1_DIV2;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_APB2_DIV2;
  RCC_ClkInitStruct.APB4CLKDivider = RCC_APB4_DIV2;
 
  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
  {
    Error_Handler();
  }
  PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_RTC|RCC_PERIPHCLK_UART4
                              |RCC_PERIPHCLK_USART1|RCC_PERIPHCLK_UART8
                              |RCC_PERIPHCLK_UART5|RCC_PERIPHCLK_SPI5
                              |RCC_PERIPHCLK_SPI2|RCC_PERIPHCLK_SDMMC
                              |RCC_PERIPHCLK_I2C2|RCC_PERIPHCLK_ADC
                              |RCC_PERIPHCLK_I2C1;
  PeriphClkInitStruct.PLL2.PLL2M = 1;
  PeriphClkInitStruct.PLL2.PLL2N = 9;
  PeriphClkInitStruct.PLL2.PLL2P = 1;
  PeriphClkInitStruct.PLL2.PLL2Q = 2;
  PeriphClkInitStruct.PLL2.PLL2R = 2;
  PeriphClkInitStruct.PLL2.PLL2RGE = RCC_PLL2VCIRANGE_3;
  PeriphClkInitStruct.PLL2.PLL2VCOSEL = RCC_PLL2VCOMEDIUM;
  PeriphClkInitStruct.PLL2.PLL2FRACN = 3072;
  PeriphClkInitStruct.SdmmcClockSelection = RCC_SDMMCCLKSOURCE_PLL;
  PeriphClkInitStruct.Spi123ClockSelection = RCC_SPI123CLKSOURCE_PLL2;
  PeriphClkInitStruct.Spi45ClockSelection = RCC_SPI45CLKSOURCE_D2PCLK1;
  PeriphClkInitStruct.Usart234578ClockSelection = RCC_USART234578CLKSOURCE_D2PCLK1;
  PeriphClkInitStruct.Usart16ClockSelection = RCC_USART16CLKSOURCE_D2PCLK2;
  PeriphClkInitStruct.I2c123ClockSelection = RCC_I2C123CLKSOURCE_D2PCLK1;
  PeriphClkInitStruct.AdcClockSelection = RCC_ADCCLKSOURCE_PLL2;
  PeriphClkInitStruct.RTCClockSelection = RCC_RTCCLKSOURCE_LSE;
  if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)
  {
    Error_Handler();
  }
}

With a ADC Clock of 150MHz, a prescaler of 10, and a cycle time of 387.5 cycles the time is

150Mhz / 10 = 15MHz => T = 1/15Mhz = 66.67ns

Cycle time = 387.5 * 66.67ns = 25.83us

The datasheet defines a minimum sampling time of 9us for the temperature sensor.

No idea what I'm doing wrong.

Regards

Jakob

jakob.brunhart
Associate III

Hi Jack

Can you please tell me your calibration values (TS_CAL1 and TS_CAL2).

Regards

Jakob

Hi Jakob,

====> ts_cal1 = 0x3072

====> ts_cal2 = 0x4089

Consecutive readings vary widely and are noisy on the 'V' version chip. The 'Y' version has much more stable readings, and indicate about 10 degrees Celsius higher, with the same application.

====> Temp_value = 0x3300

====> Temp_value = 0x3735

I do not trust the temperature sensor readings of the STM32H7 'V' vsersions, as the chip feels much more hot than 50 degrees Celsius.

In the end, I didn't find solutions, but extreme filtering, but still the readings seem off too much.

I think STM may need to check it, and document it to the errata list.

Hi @Jack​ ,

Please use offset and linear as calibration mode:

HAL_ADCEx_Calibration_Start(&hadc3, ADC_CALIB_OFFSET_LINEARITY, ADC_SINGLE_ENDED);

Let me know if this works for you with rev V to get more stable results.

-Amel

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.

SF??r
Associate III

Have no problems with temperature reading at the V rev.

Try to use the HAL Macro to calc the temperature:

temp_value = __HAL_ADC_CALC_TEMPERATURE(MB_ANALOGTEMP_REF_VOLT_MV, raw_adc_value, ADC_RESOLUTION_16B);

If you use the DAC, disable it to test with the ADC reading is more stable (we have still some issues here)