/* 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 = adc0_Pin|adc1_Pin|adc2_Pin; GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); /* ADC1 interrupt Init */ HAL_NVIC_SetPriority(ADC1_2_IRQn, 5, 0); HAL_NVIC_EnableIRQ(ADC1_2_IRQn); /* 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, adc0_Pin|adc1_Pin|adc2_Pin); /* ADC1 interrupt Deinit */ HAL_NVIC_DisableIRQ(ADC1_2_IRQn); /* USER CODE BEGIN ADC1_MspDeInit 1 */ /* USER CODE END ADC1_MspDeInit 1 */ } } /* USER CODE BEGIN 1 */ 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; uint16_t Adc2_CalibrationValue ; uint16_t Adc3_CalibrationValue ; void AdcCalibration_init(void) { Value_old_addr2 = read_flash_16(ADC1_FLASH_ADDR); Value_old_addr3 = read_flash_16(ADC2_FLASH_ADDR); 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; //指向最旧的 } float array1[] = {-40, -39, -38, -37, -36, -35, -34, -33, -32, -31, -30, -29, -28, -27, -26, -25, -24, -23, -22, -21, -20, -19, -18, -17, -16, -15, -14, -13, -12, -11, -10, -9, -8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105}; float array2[] = {340.9281f, 318.8772f, 298.3978f, 279.3683f, 261.6769f, 245.2212f, 229.9072f, 215.6488f, 202.3666f, 189.9878f, 178.4456f, 167.6783f, 157.6292f, 148.2460f, 139.4807f, 131.2888f, 123.6294f, 116.4648f, 109.7600f, 103.4829f, 97.6037f, 92.0947f, 86.9305f, 82.0877f, 77.5442f, 73.2798f, 69.2759f, 65.5149f, 61.9809f, 58.6587f, 55.5345f, 52.5954f, 49.8294f, 47.2253f, 44.7727f, 42.4620f, 40.2841f, 38.2307f, 36.2940f, 34.4668f, 32.7421f, 31.1138f, 29.5759f, 28.1229f, 26.7496f, 25.4513f, 24.2234f, 23.0618f, 21.9625f, 20.9218f, 19.9364f, 19.0029f, 18.1184f, 17.2800f, 16.4852f, 15.7313f, 15.0161f, 14.3375f, 13.6932f, 13.0815f, 12.5005f, 11.9485f, 11.4239f, 10.9252f, 10.4510f, 10.0000f, 9.5709f, 9.1626f, 8.7738f, 8.4037f, 8.0512f, 7.7154f, 7.3954f, 7.0904f, 6.7996f, 6.5223f, 6.2577f, 6.0053f, 5.7645f, 5.5345f, 5.3150f, 5.1053f, 4.9050f, 4.7136f, 4.5307f, 4.3558f, 4.1887f, 4.0287f, 3.8758f, 3.7294f, 3.5893f, 3.4553f, 3.3269f, 3.2039f, 3.0862f, 2.9733f, 2.8652f, 2.7616f, 2.6622f, 2.5669f, 2.4755f, 2.3879f, 2.3038f, 2.2231f, 2.1456f, 2.0712f, 1.9998f, 1.9312f, 1.8653f, 1.8019f, 1.7411f, 1.6826f, 1.6264f, 1.5723f, 1.5203f, 1.4703f, 1.4222f, 1.3759f, 1.3313f, 1.2884f, 1.2471f, 1.2073f, 1.1690f, 1.1321f, 1.0965f, 1.0623f, 1.0293f, 0.9974f, 0.9667f, 0.9372f, 0.9086f, 0.8811f, 0.8545f, 0.8289f, 0.8042f, 0.7803f, 0.7572f, 0.7350f, 0.7135f, 0.6927f, 0.6727f, 0.6533f, 0.6346f, 0.6165f, 0.5990f, 0.5821f}; uint16_t max_adc1; uint16_t max_adc2; uint16_t temperature1 = 0; void findIndexAndTemp(float resistance, float array1[], float array2[], int index2, int index1, int arrLen){ uint16_t temp = 0; const float resRange = (array2[index2] - array2[index2+1]) / 10.0f; float resArr[arrLen]; for(int i = 0; i < arrLen; i++){ resArr[i] = array2[index2+1] + i * resRange; } int index = -1; float minDiff = 1000.0f; for(int i = 0; i < arrLen; i++){ float diff = fabs(resistance - resArr[i]); index = (diff < minDiff) ? i : index; minDiff = (diff < minDiff) ? diff : minDiff; } const float tempRange = 0.1f; float tempArr[arrLen]; for(int i = 0; i < arrLen; i++){ tempArr[i] = array1[index1] + i * tempRange; } if(resArr[index] > 340.9821f){ //-40 temperature1 = 0x8190; } else if(resArr[index] > 32.7421f && resArr[index] <= 340.9821f){ //负数 temp = fabs(tempArr[index]) * 10; temp |= 0x8000; temperature1 = temp; } else if(resArr[index] >= 0.5821f && resArr[index] <= 32.7421f){ //正数 temperature1 = tempArr[index] * 10; } else if(resArr[index] < 0.5821f){ //105度 temperature1 = 0x041A; } else { temperature1 = 0x0000; } temp = 0; } #define R_NOMINAL 10.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 / 4096.0f; // 根据ADC值计算输入电压 float resistance = R_NOMINAL * (voltage / (vref - voltage)); // 根据电压计算NTC热敏电阻阻值 // printf("%.3f\r\n",resistance); // HAL_Delay(500); // printf("%.4f\n",array2[0]); // printf("%.4f\n",array2[0]); for (int i = 0; i < sizeof(array2) - 1; i++) { if (resistance >= array2[i+1] && resistance < array2[i]) { findIndexAndTemp(resistance, array1, array2, i, i, 10); break; } } // printf("%d\r\n",temperature1);//十进制 // printf("%4x\r\n\n",temperature1);//十六进制 return temperature1; } void GetADCResults(ADC_HandleTypeDef* hadc) { HAL_ADC_Start(&hadc1); HAL_ADC_PollForConversion(&hadc1, 100); uint16_t adc1_raw = HAL_ADC_GetValue(&hadc1); uint16_t temperature = CalculateTemperature(adc1_raw, 3.3); 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; max_adc1 = (3*4096)/3.3; if(adc2_raw >= max_adc1){ adc2_raw = max_adc1; } } 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; max_adc2 = (3*4096)/3.3; if(adc3_raw >= max_adc2){ adc3_raw = max_adc2; } } 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); HAL_ADC_Stop(&hadc1); //关闭ADC以降低功耗 } /* USER CODE END 1 */