cancel
Showing results for 
Search instead for 
Did you mean: 

Nucleo-F439ZI internal temperature sensor

Ramachandran1992
Associate III

HI team,

I am working in NUCLEO-F439ZI board, now I am doing multi-channel ADC, in that I selected ADC 1 for getting the data, in ADC1 select CH3 and CH10 and Internal Temperature sensor. The data from CH3 and 10 work fine, but the internal temperature sensor value was so what different. Check my code where I do the mistake. I attached the code and result of the program for your reference.

/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file           : main.c
  * @brief          : Main program body
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2024 STMicroelectronics.
  * All rights reserved.
  *
  * This software is licensed under terms that can be found in the LICENSE file
  * in the root directory of this software component.
  * If no LICENSE file comes with this software, it is provided AS-IS.
  *
  ******************************************************************************
  */
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "lwip.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "stdio.h"
#include "string.h"
#include "lwip/apps/httpd.h"
#include "stm32f4xx_hal.h"
/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
#define V25  0.76
#define avg_slope  0.0025
#define ref_vlt  3.3
/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */

/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/
ADC_HandleTypeDef hadc1;
DMA_HandleTypeDef hdma_adc1;

UART_HandleTypeDef huart3;

/* USER CODE BEGIN PV */
extern uint16_t ldr=0;
extern uint16_t pot=0;
extern float temperature=0;
uint32_t adc_value[3];
char msg[40];
/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_DMA_Init(void);
static void MX_ADC1_Init(void);
static void MX_USART3_UART_Init(void);
/* USER CODE BEGIN PFP */
extern struct netif gnetif;
/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */


/*uint8_t convCompleted = 0;
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{
convCompleted =1;
}*/
/* USER CODE END 0 */

/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{

  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_DMA_Init();
  MX_ADC1_Init();
  MX_LWIP_Init();
  MX_USART3_UART_Init();
  /* USER CODE BEGIN 2 */
  http_server_init();

  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
	  HAL_ADC_Start_DMA(&hadc1, adc_value, 3);
	  HAL_ADC_PollForConversion(&hadc1, 20);
	  ldr = (uint16_t) adc_value[0];
	  pot = (uint16_t) adc_value[1];
	  temperature = ConvertADCValueToTemperature(adc_value[2]);

	  sprintf (msg,"ldr: %hu \r\t\t",ldr);
	  HAL_UART_Transmit(&huart3, (uint8_t *)msg, strlen(msg), HAL_MAX_DELAY);
	  if (ldr > 1500)
	  {
		  HAL_GPIO_WritePin(GPIOG, GPIO_PIN_2, SET);
	  }
	  else
	  {
		  HAL_GPIO_WritePin(GPIOG, GPIO_PIN_2, RESET);
	  }
	  sprintf (msg,"pot: %d \r\t\t",pot);
	  HAL_UART_Transmit(&huart3, (uint8_t *)msg, strlen(msg), HAL_MAX_DELAY);
	  if (pot > 2000)
	  {
	    HAL_GPIO_WritePin(GPIOG, GPIO_PIN_3, SET);
	  }
	  else
	  {
	    HAL_GPIO_WritePin(GPIOG, GPIO_PIN_3, RESET);
	  }

	  sprintf(msg, "INT_Temp: %2f \r\n", temperature);
	  HAL_UART_Transmit(&huart3, (uint8_t *)msg, strlen(msg), HAL_MAX_DELAY);
	  HAL_Delay(500);
  ethernetif_input(&gnetif);
  sys_check_timeouts();
  }
  
  /* USER CODE END 3 */
}

/* USER CODE begin 4 */
// convert the ADC value 2 Temperature Value
void ConvertADCValueToTemperature(temperature)
{
	float Vsense = (temperature*3.3)/4096;
	temperature = ((Vsense - V25)/avg_slope)+25;
	return temperature;
}

/* USER CODE END 4 */
/**
  * @brief System Clock Configuration
  * @retval None
  */
void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

  /** Configure the main internal regulator output voltage
  */
  __HAL_RCC_PWR_CLK_ENABLE();
  __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);

  /** Initializes the RCC Oscillators according to the specified parameters
  * in the RCC_OscInitTypeDef structure.
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  RCC_OscInitStruct.PLL.PLLM = 4;
  RCC_OscInitStruct.PLL.PLLN = 180;
  RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
  RCC_OscInitStruct.PLL.PLLQ = 7;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }

  /** Activate the Over-Drive mode
  */
  if (HAL_PWREx_EnableOverDrive() != HAL_OK)
  {
    Error_Handler();
  }

  /** Initializes the CPU, AHB and APB buses clocks
  */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5) != HAL_OK)
  {
    Error_Handler();
  }
}

/**
  * @brief ADC1 Initialization Function
  * @PAram None
  * @retval None
  */
static void MX_ADC1_Init(void)
{

  /* USER CODE BEGIN ADC1_Init 0 */

  /* USER CODE END ADC1_Init 0 */

  ADC_ChannelConfTypeDef sConfig = {0};

  /* USER CODE BEGIN ADC1_Init 1 */

  /* USER CODE END ADC1_Init 1 */

  /** 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_DIV4;
  hadc1.Init.Resolution = ADC_RESOLUTION_12B;
  hadc1.Init.ScanConvMode = ENABLE;
  hadc1.Init.ContinuousConvMode = ENABLE;
  hadc1.Init.DiscontinuousConvMode = DISABLE;
  hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
  hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
  hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
  hadc1.Init.NbrOfConversion = 3;
  hadc1.Init.DMAContinuousRequests = ENABLE;
  hadc1.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
  if (HAL_ADC_Init(&hadc1) != HAL_OK)
  {
    Error_Handler();
  }

  /** Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time.
  */
  sConfig.Channel = ADC_CHANNEL_3;
  sConfig.Rank = 1;
  sConfig.SamplingTime = ADC_SAMPLETIME_15CYCLES;
  if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
  {
    Error_Handler();
  }

  /** Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time.
  */
  sConfig.Channel = ADC_CHANNEL_10;
  sConfig.Rank = 2;
  if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
  {
    Error_Handler();
  }

  /** Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time.
  */
  sConfig.Channel = ADC_CHANNEL_TEMPSENSOR;
  sConfig.Rank = 3;
  sConfig.SamplingTime = ADC_SAMPLETIME_480CYCLES;
  if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN ADC1_Init 2 */

  /* USER CODE END ADC1_Init 2 */

}

/**
  * @brief USART3 Initialization Function
  * @PAram None
  * @retval None
  */
static void MX_USART3_UART_Init(void)
{

  /* USER CODE BEGIN USART3_Init 0 */

  /* USER CODE END USART3_Init 0 */

  /* USER CODE BEGIN USART3_Init 1 */

  /* USER CODE END USART3_Init 1 */
  huart3.Instance = USART3;
  huart3.Init.BaudRate = 115200;
  huart3.Init.WordLength = UART_WORDLENGTH_8B;
  huart3.Init.StopBits = UART_STOPBITS_1;
  huart3.Init.Parity = UART_PARITY_NONE;
  huart3.Init.Mode = UART_MODE_TX_RX;
  huart3.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  huart3.Init.OverSampling = UART_OVERSAMPLING_16;
  if (HAL_UART_Init(&huart3) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN USART3_Init 2 */

  /* USER CODE END USART3_Init 2 */

}

/**
  * Enable DMA controller clock
  */
static void MX_DMA_Init(void)
{

  /* DMA controller clock enable */
  __HAL_RCC_DMA2_CLK_ENABLE();

  /* DMA interrupt init */
  /* DMA2_Stream0_IRQn interrupt configuration */
  HAL_NVIC_SetPriority(DMA2_Stream0_IRQn, 0, 0);
  HAL_NVIC_EnableIRQ(DMA2_Stream0_IRQn);

}

/**
  * @brief GPIO Initialization Function
  * @PAram None
  * @retval None
  */
static void MX_GPIO_Init(void)
{
  GPIO_InitTypeDef GPIO_InitStruct = {0};
/* USER CODE BEGIN MX_GPIO_Init_1 */
/* USER CODE END MX_GPIO_Init_1 */

  /* GPIO Ports Clock Enable */
  __HAL_RCC_GPIOH_CLK_ENABLE();
  __HAL_RCC_GPIOC_CLK_ENABLE();
  __HAL_RCC_GPIOA_CLK_ENABLE();
  __HAL_RCC_GPIOB_CLK_ENABLE();
  __HAL_RCC_GPIOD_CLK_ENABLE();
  __HAL_RCC_GPIOG_CLK_ENABLE();

  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(GPIOG, GPIO_PIN_2|GPIO_PIN_3, GPIO_PIN_RESET);

  /*Configure GPIO pins : PG2 PG3 */
  GPIO_InitStruct.Pin = GPIO_PIN_2|GPIO_PIN_3;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(GPIOG, &GPIO_InitStruct);

/* USER CODE BEGIN MX_GPIO_Init_2 */
/* USER CODE END MX_GPIO_Init_2 */
}

/* USER CODE BEGIN 4 */

/* USER CODE END 4 */

/**
  * @brief  This function is executed in case of error occurrence.
  * @retval None
  */
void Error_Handler(void)
{
  /* USER CODE BEGIN Error_Handler_Debug */
  /* User can add his own implementation to report the HAL error return state */
  __disable_irq();
  while (1)
  {
  }
  /* USER CODE END Error_Handler_Debug */
}

#ifdef  USE_FULL_ASSERT
/**
  * @brief  Reports the name of the source file and the source line number
  *         where the assert_param error has occurred.
  * @PAram  file: pointer to the source file name
  * @PAram  line: assert_param error line source number
  * @retval None
  */
void assert_failed(uint8_t *file, uint32_t line)
{
  /* USER CODE BEGIN 6 */
  /* User can add his own implementation to report the file name and line number,
     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  /* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */

 The output came was show below, I have doubts in the internal temperature sensor value (INT_Temp)

ldr: 963 pot: 1200 INT_Temp: -103.000000
ldr: 960 pot: 1032 INT_Temp: -103.000000
ldr: 962 pot: 1182 INT_Temp: -103.000000
ldr: 960 pot: 1054 INT_Temp: -104.000000
ldr: 961 pot: 1160 INT_Temp: -100.000000
ldr: 962 pot: 1094 INT_Temp: -101.000000
ldr: 962 pot: 1119 INT_Temp: -105.000000
ldr: 963 pot: 1105 INT_Temp: -104.000000
ldr: 961 pot: 1093 INT_Temp: -105.000000
ldr: 961 pot: 1141 INT_Temp: -103.000000
ldr: 960 pot: 1072 INT_Temp: -103.000000
ldr: 961 pot: 1164 INT_Temp: -104.000000
ldr: 961 pot: 541 INT_Temp: -102.000000
ldr: 1193 pot: 546 INT_Temp: 31.000000
ldr: 1032 pot: 548 INT_Temp: 30.000000
ldr: 549 pot: 548 INT_Temp: 109.000000
ldr: 547 pot: 963 INT_Temp: 49.000000
ldr: 546 pot: 961 INT_Temp: 110.000000
ldr: 546 pot: 963 INT_Temp: 45.000000
ldr: 551 pot: 963 INT_Temp: 112.000000
ldr: 541 pot: 962 INT_Temp: 48.000000
ldr: 557 pot: 963 INT_Temp: 109.000000
ldr: 545 pot: 962 INT_Temp: 53.000000
ldr: 552 pot: 961 INT_Temp: 101.000000
ldr: 541 pot: 962 INT_Temp: 62.000000
ldr: 545 pot: 961 INT_Temp: 89.000000
ldr: 550 pot: 961 INT_Temp: 73.000000
ldr: 548 pot: 959 INT_Temp: 80.000000
ldr: 541 pot: 962 INT_Temp: 82.000000
ldr: 544 pot: 961 INT_Temp: 67.000000
ldr: 545 pot: 961 INT_Temp: 90.000000
ldr: 547 pot: 962 INT_Temp: 62.000000
ldr: 542 pot: 961 INT_Temp: 101.000000
ldr: 552 pot: 962 INT_Temp: 55.000000
ldr: 557 pot: 961 INT_Temp: 111.000000
ldr: 539 pot: 962 INT_Temp: 47.000000
ldr: 550 pot: 962 INT_Temp: 112.000000
ldr: 548 pot: 962 INT_Temp: 48.000000
ldr: 551 pot: 962 INT_Temp: 109.000000
ldr: 546 pot: 961 INT_Temp: 49.000000
ldr: 552 pot: 961 INT_Temp: 106.000000
ldr: 545 pot: 961 INT_Temp: 58.000000
ldr: 550 pot: 963 INT_Temp: 96.000000
ldr: 547 pot: 960 INT_Temp: 69.000000
ldr: 553 pot: 960 INT_Temp: 83.000000
ldr: 546 pot: 962 INT_Temp: 81.000000
ldr: 550 pot: 1088 INT_Temp: -104.000000
ldr: 962 pot: 553 INT_Temp: -103.000000

1 ACCEPTED SOLUTION

Accepted Solutions

Have you enabled the temperature sensor as outlined in RM?

waclawekjan_0-1716902714874.png

I can't judge from source, I don't use Cube. Looking at the ADC registers content reveals the truth.

JW

View solution in original post

1 REPLY 1

Have you enabled the temperature sensor as outlined in RM?

waclawekjan_0-1716902714874.png

I can't judge from source, I don't use Cube. Looking at the ADC registers content reveals the truth.

JW