cancel
Showing results for 
Search instead for 
Did you mean: 

Nucleo-32 (STM32G431KB), weird mcu temperature...

Heinrich
Associate III

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

 

1 ACCEPTED SOLUTION

Accepted Solutions
TDK
Guru

Also note that the ADC must be calibrated before being used.

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

View solution in original post

7 REPLIES 7
TDK
Guru

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.

 

TDK_0-1700664176689.png

 

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

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

TDK
Guru

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

If you feel a post has answered your question, please click "Accept as Solution".
TDK
Guru

Also note that the ADC must be calibrated before being used.

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

Okay, with scaling by 3.3/3 I get the temperatures around 17-18°C. Room temperature is 24°C.

The calibration values are:

  • TEMPSENSOR_CAL1_TEMP = 30
  • TEMPSENSOR_CAL2_TEMP = 130
  • *TEMPSENSOR_CAL1_ADDR = 1040
  • *TEMPSENSOR_CAL2_ADDR = 1381

Regards,
Heinrich

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

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).