adc.c 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233
  1. /* USER CODE BEGIN Header */
  2. /**
  3. ******************************************************************************
  4. * @file adc.c
  5. * @brief This file provides code for the configuration
  6. * of the ADC instances.
  7. ******************************************************************************
  8. * @attention
  9. *
  10. * Copyright (c) 2023 STMicroelectronics.
  11. * All rights reserved.
  12. *
  13. * This software is licensed under terms that can be found in the LICENSE file
  14. * in the root directory of this software component.
  15. * If no LICENSE file comes with this software, it is provided AS-IS.
  16. *
  17. ******************************************************************************
  18. */
  19. /* USER CODE END Header */
  20. /* Includes ------------------------------------------------------------------*/
  21. #include "adc.h"
  22. /* USER CODE BEGIN 0 */
  23. float CalculateTemperature(uint16_t adc_value, float vref);
  24. /* USER CODE END 0 */
  25. ADC_HandleTypeDef hadc1;
  26. /* ADC1 init function */
  27. void MX_ADC1_Init(void)
  28. {
  29. /* USER CODE BEGIN ADC1_Init 0 */
  30. /* USER CODE END ADC1_Init 0 */
  31. ADC_ChannelConfTypeDef sConfig = {0};
  32. /* USER CODE BEGIN ADC1_Init 1 */
  33. /* USER CODE END ADC1_Init 1 */
  34. /** Common config
  35. */
  36. hadc1.Instance = ADC1;
  37. hadc1.Init.ScanConvMode = ADC_SCAN_ENABLE;
  38. hadc1.Init.ContinuousConvMode = DISABLE;
  39. hadc1.Init.DiscontinuousConvMode = ENABLE;
  40. hadc1.Init.NbrOfDiscConversion = 1;
  41. hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
  42. hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
  43. hadc1.Init.NbrOfConversion = 3;
  44. if (HAL_ADC_Init(&hadc1) != HAL_OK)
  45. {
  46. Error_Handler();
  47. }
  48. /** Configure Regular Channel
  49. */
  50. sConfig.Channel = ADC_CHANNEL_10;
  51. sConfig.Rank = ADC_REGULAR_RANK_1;
  52. sConfig.SamplingTime = ADC_SAMPLETIME_239CYCLES_5;
  53. if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
  54. {
  55. Error_Handler();
  56. }
  57. /** Configure Regular Channel
  58. */
  59. sConfig.Channel = ADC_CHANNEL_11;
  60. sConfig.Rank = ADC_REGULAR_RANK_2;
  61. if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
  62. {
  63. Error_Handler();
  64. }
  65. /** Configure Regular Channel
  66. */
  67. sConfig.Channel = ADC_CHANNEL_12;
  68. sConfig.Rank = ADC_REGULAR_RANK_3;
  69. if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
  70. {
  71. Error_Handler();
  72. }
  73. /* USER CODE BEGIN ADC1_Init 2 */
  74. /* USER CODE END ADC1_Init 2 */
  75. }
  76. void HAL_ADC_MspInit(ADC_HandleTypeDef* adcHandle)
  77. {
  78. GPIO_InitTypeDef GPIO_InitStruct = {0};
  79. if(adcHandle->Instance==ADC1)
  80. {
  81. /* USER CODE BEGIN ADC1_MspInit 0 */
  82. /* USER CODE END ADC1_MspInit 0 */
  83. /* ADC1 clock enable */
  84. __HAL_RCC_ADC1_CLK_ENABLE();
  85. __HAL_RCC_GPIOC_CLK_ENABLE();
  86. /**ADC1 GPIO Configuration
  87. PC0 ------> ADC1_IN10
  88. PC1 ------> ADC1_IN11
  89. PC2 ------> ADC1_IN12
  90. */
  91. GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2;
  92. GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
  93. HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
  94. /* USER CODE BEGIN ADC1_MspInit 1 */
  95. /* USER CODE END ADC1_MspInit 1 */
  96. }
  97. }
  98. void HAL_ADC_MspDeInit(ADC_HandleTypeDef* adcHandle)
  99. {
  100. if(adcHandle->Instance==ADC1)
  101. {
  102. /* USER CODE BEGIN ADC1_MspDeInit 0 */
  103. /* USER CODE END ADC1_MspDeInit 0 */
  104. /* Peripheral clock disable */
  105. __HAL_RCC_ADC1_CLK_DISABLE();
  106. /**ADC1 GPIO Configuration
  107. PC0 ------> ADC1_IN10
  108. PC1 ------> ADC1_IN11
  109. PC2 ------> ADC1_IN12
  110. */
  111. HAL_GPIO_DeInit(GPIOC, GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2);
  112. /* USER CODE BEGIN ADC1_MspDeInit 1 */
  113. /* USER CODE END ADC1_MspDeInit 1 */
  114. }
  115. }
  116. /* USER CODE BEGIN 1 */
  117. uint8_t adc1_byte1 = 0;
  118. uint8_t adc2_byte1 = 0; // 定义一个字节变量用于存储转换结果
  119. uint8_t adc3_byte1 = 0;
  120. uint8_t adc1_byte2 = 0;
  121. uint8_t adc2_byte2 = 0; // 定义一个字节变量用于存储转换结果
  122. uint8_t adc3_byte2 = 0;
  123. uint16_t Value_old_addr2;
  124. uint16_t Value_old_addr3;
  125. uint16_t adc1_filtered = 0;
  126. uint16_t adc2_filtered = 0;
  127. uint16_t adc3_filtered = 0;
  128. uint16_t adc1_raw_buffer[FILTER_LENGTH] = {0};
  129. uint16_t adc2_raw_buffer[FILTER_LENGTH] = {0};
  130. uint16_t adc3_raw_buffer[FILTER_LENGTH] = {0};
  131. uint8_t adc1_raw_buffer_index = 0;
  132. uint8_t adc2_raw_buffer_index = 0;
  133. uint8_t adc3_raw_buffer_index = 0;
  134. uint16_t adc2_rawValue = 0;
  135. uint16_t adc3_rawValue = 0;
  136. void AdcCalibration_init(void)
  137. {
  138. Value_old_addr2 = read_flash_16(ADDR_FLASH_PAGE_64);
  139. Value_old_addr3 = read_flash_16(ADDR_FLASH_PAGE_65);
  140. Adc2_CalibrationValue = Value_old_addr2 != 0xFFFF ? Value_old_addr2 : Adc2_CalibrationValue;
  141. Adc3_CalibrationValue = Value_old_addr3 != 0xFFFF ? Value_old_addr3 : Adc3_CalibrationValue;
  142. Adc2_CalibrationValue &= 0x7FFF;
  143. Adc3_CalibrationValue &= 0x7FFF;
  144. }
  145. void ApplyFilter(uint16_t raw_data, uint16_t* filtered_data, uint16_t* raw_data_buffer, uint8_t* buffer_index)
  146. {
  147. raw_data_buffer[*buffer_index] = raw_data;
  148. uint32_t sum = 0;
  149. for (uint8_t i = 0; i < FILTER_LENGTH; i++) {
  150. sum += raw_data_buffer[i];
  151. }
  152. *filtered_data = (uint16_t)(sum / FILTER_LENGTH);
  153. *buffer_index = (*buffer_index + 1) % FILTER_LENGTH; //指向最旧的
  154. }
  155. void GetADCResults(ADC_HandleTypeDef* hadc)
  156. {
  157. HAL_ADC_Start(&hadc1);
  158. HAL_ADC_PollForConversion(&hadc1, 100);
  159. uint16_t adc1_raw = HAL_ADC_GetValue(&hadc1);
  160. float temperature = CalculateTemperature(adc1_raw, 3.3) * 10 + 10;
  161. ApplyFilter((uint16_t)temperature, &adc1_filtered, adc1_raw_buffer, &adc1_raw_buffer_index);
  162. HAL_ADC_Start(&hadc1);
  163. HAL_ADC_PollForConversion(&hadc1, 100);
  164. uint16_t adc2_raw = HAL_ADC_GetValue(&hadc1);
  165. adc2_rawValue = adc2_raw;
  166. if (adc2_raw != 0) {
  167. adc2_raw += (Value_old_addr2 & 0x8000) ? Adc2_CalibrationValue : -Adc2_CalibrationValue;
  168. }
  169. ApplyFilter(adc2_raw, &adc2_filtered, adc2_raw_buffer, &adc2_raw_buffer_index);
  170. HAL_ADC_Start(&hadc1);
  171. HAL_ADC_PollForConversion(&hadc1, 100);
  172. uint16_t adc3_raw = HAL_ADC_GetValue(&hadc1);
  173. adc3_rawValue = adc3_raw;
  174. if (adc3_raw != 0) {
  175. adc3_raw += (Value_old_addr3 & 0x8000) ? Adc3_CalibrationValue : -Adc3_CalibrationValue;
  176. }
  177. ApplyFilter(adc3_raw, &adc3_filtered, adc3_raw_buffer, &adc3_raw_buffer_index);
  178. adc1_byte1 = (uint8_t)(adc1_filtered >> 8);
  179. adc1_byte2 = (uint8_t)(adc1_filtered);
  180. adc2_byte1 = (uint8_t)(adc2_filtered >> 8);
  181. adc2_byte2 = (uint8_t)(adc2_filtered);
  182. adc3_byte1 = (uint8_t)(adc3_filtered >> 8);
  183. adc3_byte2 = (uint8_t)(adc3_filtered);
  184. }
  185. #define R_NOMINAL 10000.0f // 注册时NTC热敏电阻的阻值
  186. #define T_NOMINAL 298.15f // 注册时NTC热敏电阻的温度值,转化为开尔文温标
  187. #define B_FACTOR 3950.0f // NTC热敏电阻的B参数
  188. float CalculateTemperature(uint16_t adc_value, float vref)
  189. {
  190. float voltage = adc_value * vref / 4095.0f; // 根据ADC值计算输入电压
  191. float resistance = R_NOMINAL * (voltage / (vref - voltage)); // 根据电压计算NTC热敏电阻阻值
  192. float steinhart = log(resistance / R_NOMINAL) / B_FACTOR + 1.0f / T_NOMINAL; // 根据瑞利恒式计算温度
  193. return 1.0f / steinhart - 273.15f; // 转换为摄氏温度并返回
  194. }
  195. /* USER CODE END 1 */