/* USER CODE BEGIN Header */ /** ****************************************************************************** * @file adc.c * @brief This file provides code for the configuration * of the ADC instances. ****************************************************************************** * @attention * * Copyright (c) 2023 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 "adc.h" /* USER CODE BEGIN 0 */ float CalculateTemperature(uint16_t adc_value, float vref); /* USER CODE END 0 */ ADC_HandleTypeDef hadc1; /* ADC1 init function */ 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.ScanConvMode = ADC_SCAN_ENABLE; hadc1.Init.ContinuousConvMode = DISABLE; hadc1.Init.DiscontinuousConvMode = ENABLE; hadc1.Init.NbrOfDiscConversion = 1; hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START; hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT; hadc1.Init.NbrOfConversion = 3; if (HAL_ADC_Init(&hadc1) != HAL_OK) { Error_Handler(); } /** Configure Regular Channel */ sConfig.Channel = ADC_CHANNEL_10; sConfig.Rank = ADC_REGULAR_RANK_1; sConfig.SamplingTime = ADC_SAMPLETIME_239CYCLES_5; if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK) { Error_Handler(); } /** Configure Regular Channel */ sConfig.Channel = ADC_CHANNEL_11; sConfig.Rank = ADC_REGULAR_RANK_2; if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK) { Error_Handler(); } /** Configure Regular Channel */ sConfig.Channel = ADC_CHANNEL_12; sConfig.Rank = ADC_REGULAR_RANK_3; if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK) { Error_Handler(); } /* USER CODE BEGIN ADC1_Init 2 */ /* USER CODE END ADC1_Init 2 */ } void HAL_ADC_MspInit(ADC_HandleTypeDef* adcHandle) { GPIO_InitTypeDef GPIO_InitStruct = {0}; if(adcHandle->Instance==ADC1) { /* USER CODE BEGIN ADC1_MspInit 0 */ /* USER CODE END ADC1_MspInit 0 */ /* ADC1 clock enable */ __HAL_RCC_ADC1_CLK_ENABLE(); __HAL_RCC_GPIOC_CLK_ENABLE(); /**ADC1 GPIO Configuration PC0 ------> ADC1_IN10 PC1 ------> ADC1_IN11 PC2 ------> ADC1_IN12 */ GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2; GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); /* USER CODE BEGIN ADC1_MspInit 1 */ /* USER CODE END ADC1_MspInit 1 */ } } void HAL_ADC_MspDeInit(ADC_HandleTypeDef* adcHandle) { if(adcHandle->Instance==ADC1) { /* USER CODE BEGIN ADC1_MspDeInit 0 */ /* USER CODE END ADC1_MspDeInit 0 */ /* Peripheral clock disable */ __HAL_RCC_ADC1_CLK_DISABLE(); /**ADC1 GPIO Configuration PC0 ------> ADC1_IN10 PC1 ------> ADC1_IN11 PC2 ------> ADC1_IN12 */ HAL_GPIO_DeInit(GPIOC, GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2); /* USER CODE BEGIN ADC1_MspDeInit 1 */ /* USER CODE END ADC1_MspDeInit 1 */ } } /* USER CODE BEGIN 1 */ uint8_t adc1_byte1 = 0; uint8_t adc2_byte1 = 0; // 定义一个字节变量用于存储转换结果 uint8_t adc3_byte1 = 0; uint8_t adc1_byte2 = 0; uint8_t adc2_byte2 = 0; // 定义一个字节变量用于存储转换结果 uint8_t adc3_byte2 = 0; uint16_t Value_old_addr2; uint16_t Value_old_addr3; uint16_t adc1_filtered = 0; uint16_t adc2_filtered = 0; uint16_t adc3_filtered = 0; uint16_t adc1_raw_buffer[FILTER_LENGTH] = {0}; uint16_t adc2_raw_buffer[FILTER_LENGTH] = {0}; uint16_t adc3_raw_buffer[FILTER_LENGTH] = {0}; uint8_t adc1_raw_buffer_index = 0; uint8_t adc2_raw_buffer_index = 0; uint8_t adc3_raw_buffer_index = 0; uint16_t adc2_rawValue = 0; uint16_t adc3_rawValue = 0; void AdcCalibration_init(void) { Value_old_addr2 = read_flash_16(ADDR_FLASH_PAGE_64); Value_old_addr3 = read_flash_16(ADDR_FLASH_PAGE_65); Adc2_CalibrationValue = Value_old_addr2 != 0xFFFF ? Value_old_addr2 : Adc2_CalibrationValue; Adc3_CalibrationValue = Value_old_addr3 != 0xFFFF ? Value_old_addr3 : Adc3_CalibrationValue; Adc2_CalibrationValue &= 0x7FFF; Adc3_CalibrationValue &= 0x7FFF; } void ApplyFilter(uint16_t raw_data, uint16_t* filtered_data, uint16_t* raw_data_buffer, uint8_t* buffer_index) { raw_data_buffer[*buffer_index] = raw_data; uint32_t sum = 0; for (uint8_t i = 0; i < FILTER_LENGTH; i++) { sum += raw_data_buffer[i]; } *filtered_data = (uint16_t)(sum / FILTER_LENGTH); *buffer_index = (*buffer_index + 1) % FILTER_LENGTH; //指向最旧的 } void GetADCResults(ADC_HandleTypeDef* hadc) { HAL_ADC_Start(&hadc1); HAL_ADC_PollForConversion(&hadc1, 100); uint16_t adc1_raw = HAL_ADC_GetValue(&hadc1); float temperature = CalculateTemperature(adc1_raw, 3.3) * 10 - 40; ApplyFilter((uint16_t)temperature, &adc1_filtered, adc1_raw_buffer, &adc1_raw_buffer_index); HAL_ADC_Start(&hadc1); HAL_ADC_PollForConversion(&hadc1, 100); uint16_t adc2_raw = HAL_ADC_GetValue(&hadc1); adc2_rawValue = adc2_raw; if (adc2_raw != 0) { adc2_raw += (Value_old_addr2 & 0x8000) ? Adc2_CalibrationValue : -Adc2_CalibrationValue; } ApplyFilter(adc2_raw, &adc2_filtered, adc2_raw_buffer, &adc2_raw_buffer_index); HAL_ADC_Start(&hadc1); HAL_ADC_PollForConversion(&hadc1, 100); uint16_t adc3_raw = HAL_ADC_GetValue(&hadc1); adc3_rawValue = adc3_raw; if (adc3_raw != 0) { adc3_raw += (Value_old_addr3 & 0x8000) ? Adc3_CalibrationValue : -Adc3_CalibrationValue; } ApplyFilter(adc3_raw, &adc3_filtered, adc3_raw_buffer, &adc3_raw_buffer_index); adc1_byte1 = (uint8_t)(adc1_filtered >> 8); adc1_byte2 = (uint8_t)(adc1_filtered); adc2_byte1 = (uint8_t)(adc2_filtered >> 8); adc2_byte2 = (uint8_t)(adc2_filtered); adc3_byte1 = (uint8_t)(adc3_filtered >> 8); adc3_byte2 = (uint8_t)(adc3_filtered); } #define R_NOMINAL 10000.0f // 注册时NTC热敏电阻的阻值 #define T_NOMINAL 298.15f // 注册时NTC热敏电阻的温度值,转化为开尔文温标 #define B_FACTOR 3950.0f // NTC热敏电阻的B参数 float CalculateTemperature(uint16_t adc_value, float vref) { float voltage = adc_value * vref / 4095.0f; // 根据ADC值计算输入电压 float resistance = R_NOMINAL * (voltage / (vref - voltage)); // 根据电压计算NTC热敏电阻阻值 float steinhart = log(resistance / R_NOMINAL) / B_FACTOR + 1.0f / T_NOMINAL; // 根据瑞利恒式计算温度 return 1.0f / steinhart - 273.15f; // 转换为摄氏温度并返回 } /* USER CODE END 1 */