2023-11-22 05:11 AM
Hello colleagues,
I'm trying to read out the MCU temperature on my Nucoleo-32 board and all I get are weird values...
I am using ADC1 and I have activated "Temperature Sensor Channel". My MCU is running at 144 MHz. ADC runs at 36MHz.
Here is my ADC Init function:
static void MX_ADC1_Init(void)
{
/* USER CODE BEGIN ADC1_Init 0 */
/* USER CODE END ADC1_Init 0 */
ADC_MultiModeTypeDef multimode = {0};
ADC_ChannelConfTypeDef sConfig = {0};
/* USER CODE BEGIN ADC1_Init 1 */
/* USER CODE END ADC1_Init 1 */
/** Common config
*/
hadc1.Instance = ADC1;
hadc1.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV4;
hadc1.Init.Resolution = ADC_RESOLUTION_12B;
hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
hadc1.Init.GainCompensation = 0;
hadc1.Init.ScanConvMode = ADC_SCAN_ENABLE;
hadc1.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
hadc1.Init.LowPowerAutoWait = DISABLE;
hadc1.Init.ContinuousConvMode = ENABLE;
hadc1.Init.NbrOfConversion = 5;
hadc1.Init.DiscontinuousConvMode = DISABLE;
hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
hadc1.Init.DMAContinuousRequests = ENABLE;
hadc1.Init.Overrun = ADC_OVR_DATA_PRESERVED;
hadc1.Init.OversamplingMode = DISABLE;
if (HAL_ADC_Init(&hadc1) != HAL_OK)
{
Error_Handler();
}
/** Configure the ADC multi-mode
*/
multimode.Mode = ADC_MODE_INDEPENDENT;
if (HAL_ADCEx_MultiModeConfigChannel(&hadc1, &multimode) != HAL_OK)
{
Error_Handler();
}
/** Configure Regular Channel
*/
sConfig.Channel = ADC_CHANNEL_1;
sConfig.Rank = ADC_REGULAR_RANK_1;
sConfig.SamplingTime = ADC_SAMPLETIME_24CYCLES_5;
sConfig.SingleDiff = ADC_SINGLE_ENDED;
sConfig.OffsetNumber = ADC_OFFSET_NONE;
sConfig.Offset = 0;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
Error_Handler();
}
/** Configure Regular Channel
*/
sConfig.Channel = ADC_CHANNEL_2;
sConfig.Rank = ADC_REGULAR_RANK_2;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
Error_Handler();
}
/** Configure Regular Channel
*/
sConfig.Channel = ADC_CHANNEL_3;
sConfig.Rank = ADC_REGULAR_RANK_3;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
Error_Handler();
}
/** Configure Regular Channel
*/
sConfig.Channel = ADC_CHANNEL_TEMPSENSOR_ADC1;
sConfig.Rank = ADC_REGULAR_RANK_4;
sConfig.SamplingTime = ADC_SAMPLETIME_47CYCLES_5;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
Error_Handler();
}
/** Configure Regular Channel
*/
sConfig.Channel = ADC_CHANNEL_VREFINT;
sConfig.Rank = ADC_REGULAR_RANK_5;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN ADC1_Init 2 */
/* USER CODE END ADC1_Init 2 */
}
And here is the temperature calculation:
static int16_t calc_temperature (int32_t data)
{
/*
* Formula:
* temp in °C = ((TS_CAL2_TEMP - TS_CAL1_TEMP) / (TS_CAL2 - TS_CAL1)) * (TS_DATA - TS_CAL1) + 30°C
*
* TS_DATA is value from ADC
*
*/
float first = (float)(TEMPSENSOR_CAL2_TEMP - TEMPSENSOR_CAL1_TEMP)/(float)(*TEMPSENSOR_CAL2_ADDR - *TEMPSENSOR_CAL1_ADDR);
float second = (float)(data - *TEMPSENSOR_CAL1_ADDR);
float third = first * second + (float)30;
return (int16_t)(third * 100);
}
The value of "data" (value from ADC) is i.e. 940 and then after the calculation is the value of the variable third is 0.67448.....
What am I doing wrong?
Regards,
Heinrich
Solved! Go to Solution.
2023-11-22 07:43 AM
Also note that the ADC must be calibrated before being used.
2023-11-22 06:43 AM
47.5 cycles at 36 MHz is not enough time to read the temperature sensor per the datasheet. Increase sampling time to max, or at least a value that satisfies the > 5us requirement.
2023-11-22 06:56 AM - edited 2023-11-22 06:56 AM
I've changed the sampling time to 640.5 cycles for the themperature sensor... Clock prescaler is still set to "Synchronous clock mode divided by 4".
The ADC value is 909.
Regards,
Heinrich
2023-11-22 07:31 AM
Your board runs off of 3.3V (per the user manual), while the calibration values were taken at 3.0V (per the datasheet).
You can adjust for this by scaling your ADC value by 3.3/3, so use 1000 instead of 909.
If that's not it, please provide the values of:
TEMPSENSOR_CAL1_TEMP
TEMPSENSOR_CAL2_TEMP
*TEMPSENSOR_CAL1_ADDR
*TEMPSENSOR_CAL2_ADDR
2023-11-22 07:43 AM
Also note that the ADC must be calibrated before being used.
2023-11-22 08:02 AM
Okay, with scaling by 3.3/3 I get the temperatures around 17-18°C. Room temperature is 24°C.
The calibration values are:
Regards,
Heinrich
2023-11-22 08:14 AM - edited 2023-11-22 08:16 AM
While TDK already said probably all relevant things (did you calibrate ADC before use as he told above?), here is a generic checklist .There was a 'G4-specific documentation issue, too, so maybe check that one too.
JW
2023-11-22 08:29 AM - edited 2023-11-22 08:31 AM
Calibration was the essential hint... !
After a simple
HAL_ADCEx_Calibration_Start(&hadc1, ADC_SINGLE_ENDED);
it looks much better, now I get the mcu temperatures around 37°C and the other voltages aber more accurate (I'm reading two more voltages from potis).