main.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487
  1. /* USER CODE BEGIN Header */
  2. /**
  3. ******************************************************************************
  4. * @file : main.c
  5. * @brief : Main program body
  6. ******************************************************************************
  7. * @attention
  8. *
  9. * Copyright (c) 2024 STMicroelectronics.
  10. * All rights reserved.
  11. *
  12. * This software is licensed under terms that can be found in the LICENSE file
  13. * in the root directory of this software component.
  14. * If no LICENSE file comes with this software, it is provided AS-IS.
  15. *
  16. ******************************************************************************
  17. */
  18. /* USER CODE END Header */
  19. /* Includes ------------------------------------------------------------------*/
  20. #include "main.h"
  21. #include "adc.h"
  22. #include "dma.h"
  23. #include "usart.h"
  24. #include "rtc.h"
  25. #include "gpio.h"
  26. /* Private includes ----------------------------------------------------------*/
  27. /* USER CODE BEGIN Includes */
  28. #include <string.h>
  29. #include "stdio.h"
  30. #include "iic.h"
  31. #include "SC7A20.h"
  32. /* USER CODE END Includes */
  33. /* Private typedef -----------------------------------------------------------*/
  34. /* USER CODE BEGIN PTD */
  35. /* USER CODE END PTD */
  36. /* Private define ------------------------------------------------------------*/
  37. /* USER CODE BEGIN PD */
  38. #define BUFFER_SIZE 4
  39. uint8_t dataReceive1[BUFFER_SIZE];
  40. uint8_t dataReceiveLPUART1[BUFFER_SIZE];
  41. volatile uint8_t rtcReady = 0;
  42. volatile uint8_t uart1DataReady = 0;
  43. volatile uint8_t lpuart1DataReady = 0;
  44. volatile uint8_t rtc_wakeup = 0;
  45. volatile uint8_t lpuart1_wakeup = 0 ;
  46. volatile uint8_t Hallvalue ;
  47. volatile uint32_t uintadcv;
  48. volatile uint16_t uintadc_vol;
  49. volatile uint8_t Accelerationvalue;
  50. /* USER CODE END PD */
  51. /* Private macro -------------------------------------------------------------*/
  52. /* USER CODE BEGIN PM */
  53. /* USER CODE END PM */
  54. /* Private variables ---------------------------------------------------------*/
  55. /* USER CODE BEGIN PV */
  56. /* USER CODE END PV */
  57. /* Private function prototypes -----------------------------------------------*/
  58. void SystemClock_Config(void);
  59. /* USER CODE BEGIN PFP */
  60. /* USER CODE END PFP */
  61. /* Private user code ---------------------------------------------------------*/
  62. /* USER CODE BEGIN 0 */
  63. uint16_t CalculateCRC(uint8_t *data, uint16_t length)
  64. {
  65. uint16_t crc = 0xFFFF;
  66. for (uint16_t i = 0; i < length; i++)
  67. {
  68. crc ^= data[i];
  69. for (uint16_t j = 0; j < 8; j++)
  70. {
  71. if (crc & 0x0001)
  72. {
  73. crc = (crc >> 1) ^ 0xA001;
  74. }
  75. else
  76. {
  77. crc >>= 1;
  78. }
  79. }
  80. }
  81. return crc;
  82. }
  83. /* USER CODE END 0 */
  84. /**
  85. * @brief The application entry point.
  86. * @retval int
  87. */
  88. int main(void)
  89. {
  90. /* USER CODE BEGIN 1 */
  91. /* USER CODE END 1 */
  92. /* MCU Configuration--------------------------------------------------------*/
  93. /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  94. HAL_Init();
  95. /* USER CODE BEGIN Init */
  96. /* USER CODE END Init */
  97. /* Configure the system clock */
  98. SystemClock_Config();
  99. /* USER CODE BEGIN SysInit */
  100. /* USER CODE END SysInit */
  101. /* Initialize all configured peripherals */
  102. MX_GPIO_Init();
  103. MX_DMA_Init();
  104. MX_USART1_UART_Init();
  105. // MX_RTC_Init();
  106. MX_LPUART1_UART_Init();
  107. MX_ADC1_Init();
  108. /* USER CODE BEGIN 2 */
  109. SC7A20_Init();
  110. // HAL_GPIO_WritePin(GPIOB, GPIO_PIN_12, GPIO_PIN_SET);
  111. memset(dataReceiveLPUART1, 0, sizeof(dataReceiveLPUART1));
  112. __HAL_UART_ENABLE_IT(&hlpuart1, UART_IT_IDLE);
  113. HAL_UART_Receive_DMA(&hlpuart1, dataReceiveLPUART1, BUFFER_SIZE); // �动LPUART1的DMA接收
  114. HAL_GPIO_WritePin(GPIOB, GPIO_PIN_10, GPIO_PIN_RESET);//拉低500ms����
  115. HAL_Delay(500);
  116. HAL_GPIO_WritePin(GPIOB, GPIO_PIN_10, GPIO_PIN_SET);//拉低��拉回
  117. printf("lp_V45\n");
  118. HAL_UART_Transmit_DMA(&hlpuart1, (uint8_t *)"AT+TRANMD=1", strlen("AT+TRANMD=1"));
  119. HAL_Delay(3000);
  120. HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_SET);//拉高�眠
  121. /* USER CODE END 2 */
  122. /* Infinite loop */
  123. /* USER CODE BEGIN WHILE */
  124. while (1)
  125. {
  126. /* USER CODE END WHILE */
  127. /* USER CODE BEGIN 3 */
  128. Enter_LPStop2Mode();//低功耗Stop2模�
  129. if (lpuart1DataReady)
  130. {
  131. lpuart1DataReady = 0;
  132. if (dataReceiveLPUART1[0] == 0x03 && dataReceiveLPUART1[1] == 0x01)//读��尔ADC
  133. {
  134. uint16_t crcReceived = (dataReceiveLPUART1[3] << 8) | dataReceiveLPUART1[2];
  135. uint16_t crcCalculated = CalculateCRC(dataReceiveLPUART1, 2);
  136. if (crcReceived == crcCalculated)
  137. {
  138. HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_RESET);//拉低唤醒
  139. Hallvalue = ReadHallSensor();
  140. uintadcv = ReadADCValue();
  141. uintadc_vol = CalculateBatteryLevel(uintadcv);
  142. uint8_t response[6];
  143. response[0] = 0xF1;
  144. response[1] = Hallvalue;
  145. response[2] = 0xF2;
  146. response[3] = uintadc_vol & 0xFF;
  147. uint16_t responseCrc = CalculateCRC(response, 4);
  148. response[4] = responseCrc & 0xFF;
  149. response[5] = (responseCrc >> 8) & 0xFF;
  150. HAL_UART_Transmit_DMA(&hlpuart1, response, sizeof(response));
  151. }
  152. }
  153. if (dataReceiveLPUART1[0] == 0x03 && dataReceiveLPUART1[1] == 0x02)//读�加速度
  154. {
  155. uint16_t crcReceived = (dataReceiveLPUART1[3] << 8) | dataReceiveLPUART1[2];
  156. uint16_t crcCalculated = CalculateCRC(dataReceiveLPUART1, 2);
  157. if (crcReceived == crcCalculated)
  158. {
  159. HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_RESET);//拉低唤醒
  160. Accelerationvalue = ReadSC7A20Sensor();
  161. uint8_t response[4];
  162. response[0] = 0xF3;
  163. response[1] = Accelerationvalue;
  164. uint16_t responseCrc = CalculateCRC(response, 2);
  165. response[2] = responseCrc & 0xFF;
  166. response[3] = (responseCrc >> 8) & 0xFF;
  167. HAL_UART_Transmit_DMA(&hlpuart1, response, sizeof(response));
  168. HAL_Delay(100);
  169. Enter_LPStop2Mode();//低功耗Stop2模�
  170. }
  171. }
  172. HAL_UART_Receive_DMA(&hlpuart1, dataReceiveLPUART1, BUFFER_SIZE); // �动LPUART1的DMA接收
  173. HAL_Delay(10);
  174. HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_SET);//拉高�眠
  175. HAL_Delay(10);
  176. }
  177. }
  178. /* USER CODE END 3 */
  179. }
  180. /**
  181. * @brief System Clock Configuration
  182. * @retval None
  183. */
  184. void SystemClock_Config(void)
  185. {
  186. RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  187. RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
  188. /** Configure the main internal regulator output voltage
  189. */
  190. if (HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1) != HAL_OK)
  191. {
  192. Error_Handler();
  193. }
  194. /** Configure LSE Drive Capability
  195. */
  196. HAL_PWR_EnableBkUpAccess();
  197. __HAL_RCC_LSEDRIVE_CONFIG(RCC_LSEDRIVE_LOW);
  198. /** Initializes the RCC Oscillators according to the specified parameters
  199. * in the RCC_OscInitTypeDef structure.
  200. */
  201. RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSE|RCC_OSCILLATORTYPE_MSI;
  202. RCC_OscInitStruct.LSEState = RCC_LSE_ON;
  203. RCC_OscInitStruct.MSIState = RCC_MSI_ON;
  204. RCC_OscInitStruct.MSICalibrationValue = 0;
  205. RCC_OscInitStruct.MSIClockRange = RCC_MSIRANGE_8;
  206. RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
  207. if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  208. {
  209. Error_Handler();
  210. }
  211. /** Initializes the CPU, AHB and APB buses clocks
  212. */
  213. RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
  214. |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  215. RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_MSI;
  216. RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  217. RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
  218. RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
  219. if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK)
  220. {
  221. Error_Handler();
  222. }
  223. /** Enable MSI Auto calibration
  224. */
  225. HAL_RCCEx_EnableMSIPLLMode();
  226. }
  227. /* USER CODE BEGIN 4 */
  228. /**
  229. PB9
  230. * @brief 读��尔传感器忿
  231. * @retval �尔传感器忼�0000�0001�
  232. */
  233. uint8_t ReadHallSensor(void)
  234. {
  235. uint8_t hallValue = 0x00;
  236. hallValue = (HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_9) == GPIO_PIN_RESET) ? 0x00 : 0x01;
  237. return hallValue;
  238. }
  239. /**
  240. PA1
  241. * @brief 读�电池电�
  242. * @retval 电池电�(范围:0000�0064�
  243. */
  244. uint32_t ReadADCValue(void)
  245. {
  246. uint32_t adcValue = 0;
  247. const int numSamples = 10; // 样本数�
  248. uint32_t totalAdcValue = 0;
  249. for (int i = 0; i < numSamples; i++)
  250. {
  251. HAL_ADC_Start(&hadc1);
  252. if (HAL_ADC_PollForConversion(&hadc1, HAL_MAX_DELAY) == HAL_OK)
  253. {
  254. totalAdcValue += HAL_ADC_GetValue(&hadc1);
  255. }
  256. HAL_ADC_Stop(&hadc1);
  257. }
  258. adcValue = totalAdcValue / numSamples;
  259. return adcValue;
  260. }
  261. uint16_t CalculateBatteryLevel(uint32_t adcValue)
  262. {
  263. float batteryVoltage = 0.0f;
  264. const float ADC_MAX_VALUE = 4095.0f;
  265. const float VREF = 3.78f; // ADC�迃电县
  266. const float MIN_BATTERY_VOLTAGE = 2.75f; // 电池完全放电电压
  267. const float MAX_BATTERY_VOLTAGE = 4.2f; // 电池完全充电电压
  268. // 将ADC值转�为电压�
  269. batteryVoltage = ((float)adcValue / ADC_MAX_VALUE) * VREF/0.474f;
  270. // 将电压忼转�为百分毿
  271. if (batteryVoltage <= MIN_BATTERY_VOLTAGE)
  272. {
  273. return 0; // 电池电�低于或等于完全放电电压时,电�为0%
  274. }
  275. else if (batteryVoltage >= MAX_BATTERY_VOLTAGE)
  276. {
  277. return 100; // 电池电�高于或等于完全充电电压时,电�为100%
  278. }
  279. else
  280. {
  281. // 计算电池电�百分�
  282. return (uint16_t)(((batteryVoltage - MIN_BATTERY_VOLTAGE) / (MAX_BATTERY_VOLTAGE - MIN_BATTERY_VOLTAGE)) * 100);
  283. }
  284. }
  285. /*读�加鿟度数� */
  286. uint8_t ReadSC7A20Sensor(void)
  287. {
  288. int16_t x1, y1, z1;
  289. int16_t x2, y2, z2;
  290. uint8_t output = 0x00;
  291. // 第一次读�,直到读到有效�
  292. do {
  293. SC7A20_ReadXYZ(&x1, &y1, &z1);
  294. // printf("X1: %d, Y1: %d, Z1: %d\r\n", x1, y1, z1);
  295. } while (x1 == 1693 && y1 == 48 && z1 == 952);
  296. // 第二次读�,直到读到有效�
  297. do {
  298. SC7A20_ReadXYZ(&x2, &y2, &z2);
  299. // printf("X2: %d, Y2: %d, Z2: %d\r\n", x2, y2, z2);
  300. } while (x2 == 1693 && y2 == 48 && z2 == 952);
  301. if ((x2 - x1) > 16 || (x1 - x2) > 16 || (z2 - z1) > 15 || (z1 - z2) > 15) {
  302. output = 0x01;
  303. }
  304. // printf("SC7A20Output: 0x%02X\r\n", output);
  305. return output;
  306. }
  307. void Configure_GPIOs_For_LowPower(void)
  308. {
  309. GPIO_InitTypeDef GPIO_InitStruct = {0};
  310. // �用�� GPIO 端�的时�
  311. // __HAL_RCC_GPIOA_CLK_ENABLE();
  312. __HAL_RCC_GPIOB_CLK_ENABLE();
  313. __HAL_RCC_GPIOC_CLK_ENABLE();
  314. __HAL_RCC_GPIOH_CLK_ENABLE();
  315. // __HAL_RCC_ADC_CLK_ENABLE();
  316. __HAL_RCC_USART1_CLK_ENABLE();
  317. GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;// �置为模拟模�,�用上拉/下拉
  318. GPIO_InitStruct.Pull = GPIO_NOPULL;
  319. GPIO_InitStruct.Pin = GPIO_PIN_All & ~(GPIO_PIN_0|GPIO_PIN_2|GPIO_PIN_3);
  320. HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);// �置 GPIOA
  321. GPIO_InitStruct.Pin = GPIO_PIN_All;// �置 GPIOB
  322. HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
  323. GPIO_InitStruct.Pin = GPIO_PIN_All;// �置 GPIOC
  324. HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
  325. GPIO_InitStruct.Pin = GPIO_PIN_All; // �置 GPIOH
  326. HAL_GPIO_Init(GPIOH, &GPIO_InitStruct);
  327. // 关闭�� GPIO 端�的时�
  328. // __HAL_RCC_GPIOA_CLK_DISABLE();
  329. __HAL_RCC_GPIOB_CLK_DISABLE();
  330. __HAL_RCC_GPIOC_CLK_DISABLE();
  331. __HAL_RCC_GPIOH_CLK_DISABLE();
  332. // 关闭外设时钟
  333. __HAL_RCC_ADC_CLK_DISABLE();
  334. __HAL_RCC_USART1_CLK_DISABLE();
  335. }
  336. void Enter_LPStop2Mode(void)
  337. {
  338. // printf("Entering Stop2\n");
  339. Configure_GPIOs_For_LowPower();
  340. SysTick->CTRL &= (~SysTick_CTRL_TICKINT_Msk); // 暂�SYSTICK中断,以�影�STOP进入
  341. SysTick->CTRL &= (~SysTick_CTRL_ENABLE_Msk); // 暂�SYSTICK计数,以�影�STOP进入
  342. __HAL_RCC_PWR_CLK_ENABLE();
  343. __HAL_RCC_WAKEUPSTOP_CLK_CONFIG(RCC_STOP_WAKEUPCLOCK_MSI); // �置唤醒时钟�为MSI
  344. UART_WakeUpTypeDef UART_WakeUpStruct = {0}; // �始化UART唤醒类型结构使
  345. UART_WakeUpStruct.WakeUpEvent = UART_WAKEUP_ON_STARTBIT; // 设置为接收开始�时唤醿
  346. // �置 LPUART1 使能唤醒功能
  347. HAL_UARTEx_StopModeWakeUpSourceConfig(&hlpuart1, UART_WakeUpStruct); // LPUART1�样使用接收弿始�唤醒
  348. __HAL_UART_ENABLE_IT(&hlpuart1, UART_IT_IDLE); // 弿�LPUART1 IDLE中断
  349. __HAL_RCC_LPUART1_CONFIG(RCC_LPUART1CLKSOURCE_LSE); // 使用LSE作为LPUART1时钟溿
  350. HAL_UARTEx_EnableClockStopMode(&hlpuart1); // �用LPUART1时钟�止模�
  351. HAL_UARTEx_EnableStopMode(&hlpuart1); // �用LPUART1�止模�
  352. hlpuart1.Instance->CR1 |= USART_CR1_UESM; // 使能LPUART1在STOP模�下的唤醒功能
  353. hlpuart1.Instance->CR3 |= USART_CR3_WUFIE; // 使能仿 STOP 模�唤醒的中斿
  354. // HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE2); // �置调压器为低功耗模弿
  355. HAL_PWREx_EnterSTOP2Mode(PWR_STOPENTRY_WFI); // 进入STOP2模�
  356. // HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1); // �置调压器为正常模�
  357. SysTick->CTRL |=(~SysTick_CTRL_TICKINT_Msk);//唤醒���SYSTICK中断的使�
  358. SysTick->CTRL |=(~SysTick_CTRL_ENABLE_Msk);//唤醒���SYSTICK中断的使�
  359. HAL_Delay(10);
  360. SystemClock_Config();
  361. MX_GPIO_Init();
  362. HAL_ADC_DeInit(&hadc1);
  363. MX_ADC1_Init();
  364. // HAL_UART_DeInit(&huart1);
  365. HAL_UART_DeInit(&hlpuart1);
  366. // MX_USART1_UART_Init();
  367. MX_LPUART1_UART_Init();
  368. // printf("Stop2 wakeup\n");
  369. }
  370. /* USER CODE END 4 */
  371. /**
  372. * @brief This function is executed in case of error occurrence.
  373. * @retval None
  374. */
  375. void Error_Handler(void)
  376. {
  377. /* USER CODE BEGIN Error_Handler_Debug */
  378. /* User can add his own implementation to report the HAL error return state */
  379. __disable_irq();
  380. while (1)
  381. {
  382. }
  383. /* USER CODE END Error_Handler_Debug */
  384. }
  385. #ifdef USE_FULL_ASSERT
  386. /**
  387. * @brief Reports the name of the source file and the source line number
  388. * where the assert_param error has occurred.
  389. * @param file: pointer to the source file name
  390. * @param line: assert_param error line source number
  391. * @retval None
  392. */
  393. void assert_failed(uint8_t *file, uint32_t line)
  394. {
  395. /* USER CODE BEGIN 6 */
  396. /* User can add his own implementation to report the file name and line number,
  397. ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  398. /* USER CODE END 6 */
  399. }
  400. #endif /* USE_FULL_ASSERT */