2019-09-06 06:58 AM
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.
2019-09-11 02:03 AM
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
2019-09-11 02:17 AM
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?
2019-09-11 02:54 AM
Hello Jack
Thank you for your fast response.
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
2019-09-11 03:26 AM
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 */
2019-09-11 03:57 AM
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
2019-09-11 06:01 AM
Hi Jack
Can you please tell me your calibration values (TS_CAL1 and TS_CAL2).
Regards
Jakob
2019-09-17 10:52 PM
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.
2019-09-24 02:47 AM
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.
2019-09-25 11:09 PM
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)