cancel
Showing results for 
Search instead for 
Did you mean: 

internal Temperature measurement changes depending on external Signal

Patsch36
Associate II

Hello,

I'm measuring Channel AN11 (Pin PB10) and the internal Temperature of the CPU of my STM32G071RB Nucleoboard via DMA. DMA is necessary, because later on the project will scale a lot. I really hope, someone has a good solution for this. 

When changing the voltage on AN11, the internal Temperature Value also changes. Here Some Examples:

Raw Value of AN11Converted Temperature of CPU in °C
70-104
74-106
819-25
144923
192447
217034
328831
4001/ 409530

Patsch36_0-1691743390407.png

My Configuration is this:

 

 

/*
 * ADC.c
 *
 *  Created on: 10.08.2023
 *      Author: scheichpa
 */

#include <CubeMX_ADC.h>

ADC_HandleTypeDef hadc1;
DMA_HandleTypeDef hdma_adc1;


/**
  * @brief ADC1 Initialization Function
  *  None
  * @retval None
  */

void MX_ADC1_Init(void)
{
  ADC_ChannelConfTypeDef sConfig = {0};

  /** Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion)
  */
  hadc1.Instance = ADC1;
  hadc1.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV2;
  hadc1.Init.Resolution = ADC_RESOLUTION_12B;
  hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
  hadc1.Init.ScanConvMode = ADC_SCAN_DISABLE;
  hadc1.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
  hadc1.Init.LowPowerAutoWait = DISABLE;
  hadc1.Init.LowPowerAutoPowerOff = DISABLE;
  hadc1.Init.ContinuousConvMode = ENABLE; // Enable continuous conversion mode
  hadc1.Init.NbrOfConversion = 2; // Number of conversions in continuous mode
  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.SamplingTimeCommon1 = ADC_SAMPLETIME_1CYCLE_5;
  hadc1.Init.SamplingTimeCommon2 = ADC_SAMPLETIME_1CYCLE_5;
  hadc1.Init.OversamplingMode = DISABLE;
  hadc1.Init.TriggerFrequencyMode = ADC_TRIGGER_FREQ_HIGH;
  if (HAL_ADC_Init(&hadc1) != HAL_OK)
  {
//    Error_Handler();
  }

  /** Configure Regular Channels
  */
//  sConfig.Channel = ADC_CHANNEL_0;
//  sConfig.Rank = ADC_REGULAR_RANK_1;
//  sConfig.SamplingTime = ADC_SAMPLINGTIME_COMMON_1;
//  if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
//  {
////    Error_Handler();
//  }

  sConfig.Channel = ADC_CHANNEL_11;
  sConfig.Rank = ADC_REGULAR_RANK_1;
  sConfig.SamplingTime = ADC_SAMPLINGTIME_COMMON_1;
  if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
  {
	  //      Error_Handler();
  }

  sConfig.Channel = ADC_CHANNEL_TEMPSENSOR;
  sConfig.Rank = ADC_REGULAR_RANK_2; // Set the rank for the second conversion
  sConfig.SamplingTime = ADC_SAMPLINGTIME_COMMON_1;
  if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
  {
  //    Error_Handler();
  }

  HAL_ADC_MspInit(&hadc1);
}


/**
* @brief ADC MSP Initialization
* This function configures the hardware resources used in this example
*  hadc: ADC handle pointer
* @retval None
*/
void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc)
{
  GPIO_InitTypeDef GPIO_InitStruct = {0};
  RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
  if(hadc->Instance==ADC1)
  {

  /** Initializes the peripherals clocks
  */
    PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_ADC;
    PeriphClkInit.AdcClockSelection = RCC_ADCCLKSOURCE_SYSCLK;
    if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
    {
//      Error_Handler();
    }

    /* Peripheral clock enable */
    __HAL_RCC_ADC_CLK_ENABLE();

    __HAL_RCC_GPIOA_CLK_ENABLE();
    /**ADC1 GPIO Configuration
    PA0     ------> ADC1_IN0
    */
    GPIO_InitStruct.Pin = GPIO_PIN_0;
    GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

    /* ADC1 DMA Init */
    /* ADC1 Init */
    hdma_adc1.Instance = DMA1_Channel1;
    hdma_adc1.Init.Request = DMA_REQUEST_ADC1;
    hdma_adc1.Init.Direction = DMA_PERIPH_TO_MEMORY;
    hdma_adc1.Init.PeriphInc = DMA_PINC_DISABLE;
    hdma_adc1.Init.MemInc = DMA_MINC_ENABLE;
    hdma_adc1.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
    hdma_adc1.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;
    hdma_adc1.Init.Mode = DMA_CIRCULAR;
    hdma_adc1.Init.Priority = DMA_PRIORITY_LOW;
    if (HAL_DMA_Init(&hdma_adc1) != HAL_OK)
    {
//      Error_Handler();
    }
    __HAL_LINKDMA(hadc,DMA_Handle,hdma_adc1);
  }
}

/**
* @brief ADC MSP De-Initialization
* This function freeze the hardware resources used in this example
*  hadc: ADC handle pointer
* @retval None
*/
void HAL_ADC_MspDeInit(ADC_HandleTypeDef* hadc)
{
  if(hadc->Instance==ADC1)
  {
    /* Peripheral clock disable */
    __HAL_RCC_ADC_CLK_DISABLE();

    /**ADC1 GPIO Configuration
    PA0     ------> ADC1_IN0
    */
    HAL_GPIO_DeInit(GPIOA, GPIO_PIN_0);

    /* ADC1 DMA DeInit */
    HAL_DMA_DeInit(hadc->DMA_Handle);
  }

}

 

My Application Code is:

void FDI::run()
{
	char val_string[32] = {};

	while (1)
	{
		uint32_t val = this->adc->getData(1);
	  	this->temperature =  __HAL_ADC_CALC_TEMPERATURE(3300, val, ADC_RESOLUTION_12B);
		sprintf(val_string, "A0: %d, Temp: %i\n", this->adc->getData(0), temperature);
		uart->send((uint8_t*)val_string, sizeof(val_string));

		MEF_SPIMessage mes = MEF_SPIMessage();
		mes.DevieID = 0;
		mes.TX_Data = (uint8_t*)val_string;
		mes.TX_DataLength = sizeof(val_string);
		this->spi->Send(mes);
		HAL_Delay(1000);
	}
}

 

1 ACCEPTED SOLUTION

Accepted Solutions
GwenoleB
ST Employee

The sampling time of the internal temperature sensor is probably too short! 
You must wait at least a minimum of 5µs. Can you please verify this point?

Best Regards,
Gwénolé

View solution in original post

3 REPLIES 3
GwenoleB
ST Employee

Dear @Patsch36,

Considering the variation of CPU temperature and your external measurements, it seems that you are using the external conversion result to compute the internal CPU temperature.
Can you please check by converting the internal TEMP_SENSOR only while keeping variation on your external sensor?

Best Regards,
Gwénolé

That's what I do. I convert the second value of the dma and send the first value only as reference (Take a look at the last code lines I provided). When turning my potentiometer from left to right, the value of AN0 changes from about 10 to 4095. I think that's the right value, so the other one must be the temperature value.

I also tried different pins for the external signal but all of them have the same result. I hardly doubt that my CPU has a temperature of -100°C :D

GwenoleB
ST Employee

The sampling time of the internal temperature sensor is probably too short! 
You must wait at least a minimum of 5µs. Can you please verify this point?

Best Regards,
Gwénolé