Skip to main content
Visitor II
August 11, 2023
Solved

internal Temperature measurement changes depending on external Signal

  • August 11, 2023
  • 2 replies
  • 1858 views

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);
	}
}

 

    This topic has been closed for replies.
    Best answer by GwenoleB

    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é

    2 replies

    ST Employee
    August 11, 2023

    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é

    Patsch36Author
    Visitor II
    August 11, 2023

    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

    GwenoleBAnswer
    ST Employee
    August 11, 2023

    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é