cancel
Showing results for 
Search instead for 
Did you mean: 

STM32WB55RG Nucleo board Internal temperature not working

Sonu_1231
Associate II

 

/* Private function prototypes -----------------------------------------------*/

void SystemClock_Config(void);

void PeriphCommonClock_Config(void);

static void MX_GPIO_Init(void);

static void MX_ADC1_Init(void);

static void MX_USART1_UART_Init(void);

/* USER CODE BEGIN PFP */

#define VREFINT_CAL_ADDR ((uint16_t*)0x1FFF75AA)

#define TS_CAL1_ADDR ((uint16_t*)0x1FFF75A8) // TS_CAL1 @ 30C

#define TS_CAL2_ADDR ((uint16_t*)0x1FFF75CA) // TS_CAL2 @ 130C

#define VDDA_CALIB 3.0f // Reference VDDA voltage in volts

 

/* USER CODE END PFP */

 

/* Private user code ---------------------------------------------------------*/

/* USER CODE BEGIN 0 */

int _write(int file, char *ptr, int len) {

HAL_UART_Transmit(&huart1, (uint8_t*)ptr, len, HAL_MAX_DELAY);

return len;

}

 

 

uint32_t Read_ADC_Channel(uint32_t channel) {

ADC_ChannelConfTypeDef sConfig = {0};

sConfig.Channel = channel;

sConfig.Rank = ADC_REGULAR_RANK_1;

sConfig.SamplingTime = ADC_SAMPLETIME_640CYCLES_5; // Long sampling time for accuracy

HAL_ADC_ConfigChannel(&hadc1, &sConfig);

 

HAL_ADC_Start(&hadc1);

HAL_ADC_PollForConversion(&hadc1, HAL_MAX_DELAY);

uint32_t adc_value = HAL_ADC_GetValue(&hadc1);

HAL_ADC_Stop(&hadc1);

printf("adc_value : %ld \r\n",adc_value);

return adc_value;

}

 

float Read_Temperature(void) {

uint32_t vref_adc = Read_ADC_Channel(ADC_CHANNEL_VREFINT);//1432

uint32_t temp_adc = Read_ADC_Channel(ADC_CHANNEL_TEMPSENSOR);//882

 

 

uint16_t ts_cal1 = *TS_CAL1_ADDR;//1037

uint16_t ts_cal2 = *TS_CAL2_ADDR;//1373

uint16_t vrefint_cal = *VREFINT_CAL_ADDR; //1374

 

printf("VREF_ADC: %lu, TEMP_ADC: %lu\r\n", vref_adc, temp_adc); //1491 946

 

if (vref_adc == 0) return -100.0f; // Avoid division by zero

 

float vdda = (float)vrefint_cal * VDDA_CALIB / vref_adc;//3.16634059

vdda = 3.1;

float temp = 30.0f + ((temp_adc * vdda / VDDA_CALIB) - ts_cal1) *

(110.0f - 30.0f) / (ts_cal2 - ts_cal1);//15.0000

 

 

 

return temp;

}

/* 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();

 

/* Configure the peripherals common clocks */

PeriphCommonClock_Config();

 

/* USER CODE BEGIN SysInit */

 

/* USER CODE END SysInit */

 

/* Initialize all configured peripherals */

MX_GPIO_Init();

MX_ADC1_Init();

MX_USART1_UART_Init();

/* USER CODE BEGIN 2 */

 

/* USER CODE END 2 */

 

/* Infinite loop */

/* USER CODE BEGIN WHILE */

while (1)

{

printf("Reading temperature...\r\n");

float temperature = Read_Temperature();

printf("Temperature: %f\r\n", temperature);

HAL_Delay(1000);

/* USER CODE END WHILE */

 

/* USER CODE BEGIN 3 */

}

/* USER CODE END 3 */

}

 

/**

* @brief System Clock Configuration

* @retval None

*/

void SystemClock_Config(void)

{

RCC_OscInitTypeDef RCC_OscInitStruct = {0};

RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

 

/** Macro to configure the PLL multiplication factor

*/

__HAL_RCC_PLL_PLLM_CONFIG(RCC_PLLM_DIV1);

 

/** Macro to configure the PLL clock source

*/

__HAL_RCC_PLL_PLLSOURCE_CONFIG(RCC_PLLSOURCE_MSI);

 

/** Configure the main internal regulator output voltage

*/

__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_HSI|RCC_OSCILLATORTYPE_HSE

|RCC_OSCILLATORTYPE_MSI;

RCC_OscInitStruct.HSEState = RCC_HSE_ON;

RCC_OscInitStruct.HSIState = RCC_HSI_ON;

RCC_OscInitStruct.MSIState = RCC_MSI_ON;

RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;

RCC_OscInitStruct.MSICalibrationValue = RCC_MSICALIBRATION_DEFAULT;

RCC_OscInitStruct.MSIClockRange = RCC_MSIRANGE_6;

RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;

if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)

{

Error_Handler();

}

 

/** Configure the SYSCLKSource, HCLK, PCLK1 and PCLK2 clocks dividers

*/

RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK4|RCC_CLOCKTYPE_HCLK2

|RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK

|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;

RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_MSI;

RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;

RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;

RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

RCC_ClkInitStruct.AHBCLK2Divider = RCC_SYSCLK_DIV1;

RCC_ClkInitStruct.AHBCLK4Divider = RCC_SYSCLK_DIV1;

 

if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK)

{

Error_Handler();

}

}

 

/**

* @brief Peripherals Common Clock Configuration

* @retval None

*/

void PeriphCommonClock_Config(void)

{

RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};

 

/** Initializes the peripherals clock

*/

PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_SMPS;

PeriphClkInitStruct.SmpsClockSelection = RCC_SMPSCLKSOURCE_HSI;

PeriphClkInitStruct.SmpsDivSelection = RCC_SMPSCLKDIV_RANGE1;

 

if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)

{

Error_Handler();

}

/* USER CODE BEGIN Smps */

 

/* USER CODE END Smps */

}

 

/**

* @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 */

 

/** Common config

*/

hadc1.Instance = ADC1;

hadc1.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV4;

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.ContinuousConvMode = DISABLE;

hadc1.Init.NbrOfConversion = 1;

hadc1.Init.DiscontinuousConvMode = DISABLE;

hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;

hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;

hadc1.Init.DMAContinuousRequests = DISABLE;

hadc1.Init.Overrun = ADC_OVR_DATA_PRESERVED;

hadc1.Init.OversamplingMode = DISABLE;

if (HAL_ADC_Init(&hadc1) != HAL_OK)

{

Error_Handler();

}

 

/** Configure Regular Channel

*/

sConfig.Channel = ADC_CHANNEL_TEMPSENSOR;

sConfig.Rank = ADC_REGULAR_RANK_1;

sConfig.SamplingTime = ADC_SAMPLETIME_640CYCLES_5;

sConfig.SingleDiff = ADC_SINGLE_ENDED;

sConfig.OffsetNumber = ADC_OFFSET_NONE;

sConfig.Offset = 0;

if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)

{

Error_Handler();

}

/* USER CODE BEGIN ADC1_Init 2 */

HAL_ADCEx_Calibration_Start(&hadc1, ADC_SINGLE_ENDED);

 

/* USER CODE END ADC1_Init 2 */

 

}

 

/**

* @brief USART1 Initialization Function

* @param None

* @retval None

*/

static void MX_USART1_UART_Init(void)

{

 

/* USER CODE BEGIN USART1_Init 0 */

 

/* USER CODE END USART1_Init 0 */

 

/* USER CODE BEGIN USART1_Init 1 */

 

/* USER CODE END USART1_Init 1 */

huart1.Instance = USART1;

huart1.Init.BaudRate = 115200;

huart1.Init.WordLength = UART_WORDLENGTH_8B;

huart1.Init.StopBits = UART_STOPBITS_1;

huart1.Init.Parity = UART_PARITY_NONE;

huart1.Init.Mode = UART_MODE_TX_RX;

huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;

huart1.Init.OverSampling = UART_OVERSAMPLING_16;

huart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;

huart1.Init.ClockPrescaler = UART_PRESCALER_DIV1;

huart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;

if (HAL_UART_Init(&huart1) != HAL_OK)

{

Error_Handler();

}

if (HAL_UARTEx_SetTxFifoThreshold(&huart1, UART_TXFIFO_THRESHOLD_1_8) != HAL_OK)

{

Error_Handler();

}

if (HAL_UARTEx_SetRxFifoThreshold(&huart1, UART_RXFIFO_THRESHOLD_1_8) != HAL_OK)

{

Error_Handler();

}

if (HAL_UARTEx_DisableFifoMode(&huart1) != HAL_OK)

{

Error_Handler();

}

/* USER CODE BEGIN USART1_Init 2 */

 

/* USER CODE END USART1_Init 2 */

 

}

 

/**

* @brief GPIO Initialization Function

* @param None

* @retval None

*/

static void MX_GPIO_Init(void)

{

/* USER CODE BEGIN MX_GPIO_Init_1 */

/* USER CODE END MX_GPIO_Init_1 */

 

/* GPIO Ports Clock Enable */

__HAL_RCC_GPIOC_CLK_ENABLE();

__HAL_RCC_GPIOA_CLK_ENABLE();

__HAL_RCC_GPIOB_CLK_ENABLE();

 

/* 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 */

 

2 REPLIES 2
Sonu_1231
Associate II

Temperature: 15.841253
Reading temperature...
adc_value : 1491
adc_value : 947
VREF_ADC: 1491, TEMP_ADC: 947
Temperature: 16.087297   
Getting incorrect values

TDK
Guru

Your math isn't checking out:

> #define VDDA_CALIB 3.0f // Reference VDDA voltage in volts
> uint16_t vrefint_cal = *VREFINT_CAL_ADDR; //1374
> printf("VREF_ADC: %lu, TEMP_ADC: %lu\r\n", vref_adc, temp_adc); //1491 946

> float vdda = (float)vrefint_cal * VDDA_CALIB / vref_adc;//3.16634059

But if I use the values you state in the comments, I get this:

vdda = 1374 * 3.0 / 1491 = 2.76

 

Datasheet says it was taken at 3.6V, so:

vdda = 1374 * 3.6 / 1491 = 3.31

 

which seems more reasonable. I believe VDDA is 3.3V on that board. If you use that value, you get a reasonable temperature (> 30) with your calculations.

 

*The datasheet may have a typo here. It was probably read at 3.0 V, not 3.6 V.

TDK_0-1740752942125.png

 

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