123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487 |
- /* USER CODE BEGIN Header */
- /**
- ******************************************************************************
- * @file : main.c
- * @brief : Main program body
- ******************************************************************************
- * @attention
- *
- * Copyright (c) 2024 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 "main.h"
- #include "adc.h"
- #include "dma.h"
- #include "usart.h"
- #include "rtc.h"
- #include "gpio.h"
- /* Private includes ----------------------------------------------------------*/
- /* USER CODE BEGIN Includes */
- #include <string.h>
- #include "stdio.h"
- #include "iic.h"
- #include "SC7A20.h"
- /* USER CODE END Includes */
- /* Private typedef -----------------------------------------------------------*/
- /* USER CODE BEGIN PTD */
- /* USER CODE END PTD */
- /* Private define ------------------------------------------------------------*/
- /* USER CODE BEGIN PD */
- #define BUFFER_SIZE 4
- uint8_t dataReceive1[BUFFER_SIZE];
- uint8_t dataReceiveLPUART1[BUFFER_SIZE];
- volatile uint8_t rtcReady = 0;
- volatile uint8_t uart1DataReady = 0;
- volatile uint8_t lpuart1DataReady = 0;
- volatile uint8_t rtc_wakeup = 0;
- volatile uint8_t lpuart1_wakeup = 0 ;
- volatile uint8_t Hallvalue ;
- volatile uint32_t uintadcv;
- volatile uint16_t uintadc_vol;
- volatile uint8_t Accelerationvalue;
- /* USER CODE END PD */
- /* Private macro -------------------------------------------------------------*/
- /* USER CODE BEGIN PM */
- /* USER CODE END PM */
- /* Private variables ---------------------------------------------------------*/
- /* USER CODE BEGIN PV */
- /* USER CODE END PV */
- /* Private function prototypes -----------------------------------------------*/
- void SystemClock_Config(void);
- /* USER CODE BEGIN PFP */
- /* USER CODE END PFP */
- /* Private user code ---------------------------------------------------------*/
- /* USER CODE BEGIN 0 */
- uint16_t CalculateCRC(uint8_t *data, uint16_t length)
- {
- uint16_t crc = 0xFFFF;
- for (uint16_t i = 0; i < length; i++)
- {
- crc ^= data[i];
- for (uint16_t j = 0; j < 8; j++)
- {
- if (crc & 0x0001)
- {
- crc = (crc >> 1) ^ 0xA001;
- }
- else
- {
- crc >>= 1;
- }
- }
- }
- return crc;
- }
- /* 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();
- /* USER CODE BEGIN SysInit */
- /* USER CODE END SysInit */
- /* Initialize all configured peripherals */
- MX_GPIO_Init();
- MX_DMA_Init();
- MX_USART1_UART_Init();
- // MX_RTC_Init();
- MX_LPUART1_UART_Init();
- MX_ADC1_Init();
- /* USER CODE BEGIN 2 */
- SC7A20_Init();
-
- // HAL_GPIO_WritePin(GPIOB, GPIO_PIN_12, GPIO_PIN_SET);
- memset(dataReceiveLPUART1, 0, sizeof(dataReceiveLPUART1));
- __HAL_UART_ENABLE_IT(&hlpuart1, UART_IT_IDLE);
- HAL_UART_Receive_DMA(&hlpuart1, dataReceiveLPUART1, BUFFER_SIZE); // �动LPUART1的DMA接收
-
- HAL_GPIO_WritePin(GPIOB, GPIO_PIN_10, GPIO_PIN_RESET);//拉低500ms����
- HAL_Delay(500);
- HAL_GPIO_WritePin(GPIOB, GPIO_PIN_10, GPIO_PIN_SET);//拉低��拉回
- printf("lp_V45\n");
- HAL_UART_Transmit_DMA(&hlpuart1, (uint8_t *)"AT+TRANMD=1", strlen("AT+TRANMD=1"));
- HAL_Delay(3000);
- HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_SET);//拉高ç�¡çœ
- /* USER CODE END 2 */
- /* Infinite loop */
- /* USER CODE BEGIN WHILE */
- while (1)
- {
- /* USER CODE END WHILE */
- /* USER CODE BEGIN 3 */
-
- Enter_LPStop2Mode();//低功耗Stop2模�
- if (lpuart1DataReady)
- {
- lpuart1DataReady = 0;
- if (dataReceiveLPUART1[0] == 0x03 && dataReceiveLPUART1[1] == 0x01)//读��尔ADC
- {
- uint16_t crcReceived = (dataReceiveLPUART1[3] << 8) | dataReceiveLPUART1[2];
- uint16_t crcCalculated = CalculateCRC(dataReceiveLPUART1, 2);
- if (crcReceived == crcCalculated)
- {
- HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_RESET);//拉低唤醒
- Hallvalue = ReadHallSensor();
- uintadcv = ReadADCValue();
- uintadc_vol = CalculateBatteryLevel(uintadcv);
- uint8_t response[6];
- response[0] = 0xF1;
- response[1] = Hallvalue;
- response[2] = 0xF2;
- response[3] = uintadc_vol & 0xFF;
- uint16_t responseCrc = CalculateCRC(response, 4);
- response[4] = responseCrc & 0xFF;
- response[5] = (responseCrc >> 8) & 0xFF;
- HAL_UART_Transmit_DMA(&hlpuart1, response, sizeof(response));
- }
- }
- if (dataReceiveLPUART1[0] == 0x03 && dataReceiveLPUART1[1] == 0x02)//读å�–åŠ é€Ÿåº¦
- {
- uint16_t crcReceived = (dataReceiveLPUART1[3] << 8) | dataReceiveLPUART1[2];
- uint16_t crcCalculated = CalculateCRC(dataReceiveLPUART1, 2);
- if (crcReceived == crcCalculated)
- {
- HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_RESET);//拉低唤醒
- Accelerationvalue = ReadSC7A20Sensor();
- uint8_t response[4];
- response[0] = 0xF3;
- response[1] = Accelerationvalue;
- uint16_t responseCrc = CalculateCRC(response, 2);
- response[2] = responseCrc & 0xFF;
- response[3] = (responseCrc >> 8) & 0xFF;
- HAL_UART_Transmit_DMA(&hlpuart1, response, sizeof(response));
- HAL_Delay(100);
- Enter_LPStop2Mode();//低功耗Stop2模�
- }
- }
- HAL_UART_Receive_DMA(&hlpuart1, dataReceiveLPUART1, BUFFER_SIZE); // �动LPUART1的DMA接收
- HAL_Delay(10);
- HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_SET);//拉高ç�¡çœ
- HAL_Delay(10);
- }
-
- }
- /* USER CODE END 3 */
- }
- /**
- * @brief System Clock Configuration
- * @retval None
- */
- void SystemClock_Config(void)
- {
- RCC_OscInitTypeDef RCC_OscInitStruct = {0};
- RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
- /** Configure the main internal regulator output voltage
- */
- if (HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1) != HAL_OK)
- {
- Error_Handler();
- }
- /** Configure LSE Drive Capability
- */
- HAL_PWR_EnableBkUpAccess();
- __HAL_RCC_LSEDRIVE_CONFIG(RCC_LSEDRIVE_LOW);
- /** Initializes the RCC Oscillators according to the specified parameters
- * in the RCC_OscInitTypeDef structure.
- */
- RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSE|RCC_OSCILLATORTYPE_MSI;
- RCC_OscInitStruct.LSEState = RCC_LSE_ON;
- RCC_OscInitStruct.MSIState = RCC_MSI_ON;
- RCC_OscInitStruct.MSICalibrationValue = 0;
- RCC_OscInitStruct.MSIClockRange = RCC_MSIRANGE_8;
- RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
- if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
- {
- Error_Handler();
- }
- /** Initializes the CPU, AHB and APB buses clocks
- */
- RCC_ClkInitStruct.ClockType = 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;
- if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK)
- {
- Error_Handler();
- }
- /** Enable MSI Auto calibration
- */
- HAL_RCCEx_EnableMSIPLLMode();
- }
- /* USER CODE BEGIN 4 */
- /**
- PB9
- * @brief 读å�–éœ�å°”ä¼ æ„Ÿå™¨å¿¿
- * @retval éœ�å°”ä¼ æ„Ÿå™¨å¿¼ï¼?0000æˆ?0001ï¼?
- */
- uint8_t ReadHallSensor(void)
- {
- uint8_t hallValue = 0x00;
- hallValue = (HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_9) == GPIO_PIN_RESET) ? 0x00 : 0x01;
- return hallValue;
- }
- /**
- PA1
- * @brief 读å�–ç”µæ± ç”µé‡�
- * @retval ç”µæ± ç”µé‡�(范围:0000åˆ?0064ï¼?
- */
- uint32_t ReadADCValue(void)
- {
- uint32_t adcValue = 0;
- const int numSamples = 10; // æ ·æœ¬æ•°é‡�
- uint32_t totalAdcValue = 0;
- for (int i = 0; i < numSamples; i++)
- {
- HAL_ADC_Start(&hadc1);
- if (HAL_ADC_PollForConversion(&hadc1, HAL_MAX_DELAY) == HAL_OK)
- {
- totalAdcValue += HAL_ADC_GetValue(&hadc1);
- }
- HAL_ADC_Stop(&hadc1);
- }
- adcValue = totalAdcValue / numSamples;
- return adcValue;
- }
- uint16_t CalculateBatteryLevel(uint32_t adcValue)
- {
- float batteryVoltage = 0.0f;
- const float ADC_MAX_VALUE = 4095.0f;
- const float VREF = 3.78f; // ADC�迃电县
- const float MIN_BATTERY_VOLTAGE = 2.75f; // ç”µæ± å®Œå…¨æ”¾ç”µç”µåŽ‹
- const float MAX_BATTERY_VOLTAGE = 4.2f; // ç”µæ± å®Œå…¨å……ç”µç”µåŽ‹
- // 将ADC值转�为电压�
- batteryVoltage = ((float)adcValue / ADC_MAX_VALUE) * VREF/0.474f;
- // 将电压忼转�为百分毿
- if (batteryVoltage <= MIN_BATTERY_VOLTAGE)
- {
- return 0; // ç”µæ± ç”µé‡�低于或ç‰äºŽå®Œå…¨æ”¾ç”µç”µåŽ‹æ—¶ï¼Œç”µé‡�为0%
- }
- else if (batteryVoltage >= MAX_BATTERY_VOLTAGE)
- {
- return 100; // ç”µæ± ç”µé‡�高于或ç‰äºŽå®Œå…¨å……电电压时,电é‡�为100%
- }
- else
- {
- // è®¡ç®—ç”µæ± ç”µé‡�百分æ¯?
- return (uint16_t)(((batteryVoltage - MIN_BATTERY_VOLTAGE) / (MAX_BATTERY_VOLTAGE - MIN_BATTERY_VOLTAGE)) * 100);
- }
- }
- /*读å�–åŠ é¿Ÿåº¦æ•°å¿? */
- uint8_t ReadSC7A20Sensor(void)
- {
- int16_t x1, y1, z1;
- int16_t x2, y2, z2;
- uint8_t output = 0x00;
-
- // 第一次读�,直到读到有效�
- do {
- SC7A20_ReadXYZ(&x1, &y1, &z1);
- // printf("X1: %d, Y1: %d, Z1: %d\r\n", x1, y1, z1);
- } while (x1 == 1693 && y1 == 48 && z1 == 952);
- // 第二次读�,直到读到有效�
- do {
- SC7A20_ReadXYZ(&x2, &y2, &z2);
- // printf("X2: %d, Y2: %d, Z2: %d\r\n", x2, y2, z2);
- } while (x2 == 1693 && y2 == 48 && z2 == 952);
-
- if ((x2 - x1) > 16 || (x1 - x2) > 16 || (z2 - z1) > 15 || (z1 - z2) > 15) {
- output = 0x01;
- }
- // printf("SC7A20Output: 0x%02X\r\n", output);
- return output;
- }
- void Configure_GPIOs_For_LowPower(void)
- {
- GPIO_InitTypeDef GPIO_InitStruct = {0};
- // �用�� GPIO 端�的时�
- // __HAL_RCC_GPIOA_CLK_ENABLE();
- __HAL_RCC_GPIOB_CLK_ENABLE();
- __HAL_RCC_GPIOC_CLK_ENABLE();
- __HAL_RCC_GPIOH_CLK_ENABLE();
-
- // __HAL_RCC_ADC_CLK_ENABLE();
- __HAL_RCC_USART1_CLK_ENABLE();
-
-
- GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;// �置为模拟模�,�用上拉/下拉
- GPIO_InitStruct.Pull = GPIO_NOPULL;
-
- GPIO_InitStruct.Pin = GPIO_PIN_All & ~(GPIO_PIN_0|GPIO_PIN_2|GPIO_PIN_3);
- HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);// �置 GPIOA
-
- GPIO_InitStruct.Pin = GPIO_PIN_All;// �置 GPIOB
- HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
-
- GPIO_InitStruct.Pin = GPIO_PIN_All;// �置 GPIOC
- HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
-
- GPIO_InitStruct.Pin = GPIO_PIN_All; // �置 GPIOH
- HAL_GPIO_Init(GPIOH, &GPIO_InitStruct);
-
- // 关闿‰?æœ? GPIO 端å�£çš„æ—¶é’?
- // __HAL_RCC_GPIOA_CLK_DISABLE();
- __HAL_RCC_GPIOB_CLK_DISABLE();
- __HAL_RCC_GPIOC_CLK_DISABLE();
- __HAL_RCC_GPIOH_CLK_DISABLE();
-
- // å…³é—外设时钟
- __HAL_RCC_ADC_CLK_DISABLE();
- __HAL_RCC_USART1_CLK_DISABLE();
- }
- void Enter_LPStop2Mode(void)
- {
- // printf("Entering Stop2\n");
- Configure_GPIOs_For_LowPower();
-
- SysTick->CTRL &= (~SysTick_CTRL_TICKINT_Msk); // æš‚å�œSYSTICK䏿–,以å…�å½±å“�STOP进入
- SysTick->CTRL &= (~SysTick_CTRL_ENABLE_Msk); // 暂�SYSTICK计数,以�影�STOP进入
- __HAL_RCC_PWR_CLK_ENABLE();
-
-
- __HAL_RCC_WAKEUPSTOP_CLK_CONFIG(RCC_STOP_WAKEUPCLOCK_MSI); // �置唤醒时钟�为MSI
- UART_WakeUpTypeDef UART_WakeUpStruct = {0}; // �始化UART唤醒类型结构使
- UART_WakeUpStruct.WakeUpEvent = UART_WAKEUP_ON_STARTBIT; // 设置为接收开始�时唤醿
- // �置 LPUART1 使能唤醒功能
- HAL_UARTEx_StopModeWakeUpSourceConfig(&hlpuart1, UART_WakeUpStruct); // LPUART1å�Œæ ·ä½¿ç”¨æŽ¥æ”¶å¼¿å§‹ä½�唤醒
- __HAL_UART_ENABLE_IT(&hlpuart1, UART_IT_IDLE); // 弿å�¯LPUART1 IDLE䏿–
- __HAL_RCC_LPUART1_CONFIG(RCC_LPUART1CLKSOURCE_LSE); // 使用LSE作为LPUART1时钟溿
- HAL_UARTEx_EnableClockStopMode(&hlpuart1); // å�¯ç”¨LPUART1æ—¶é’Ÿå�œæ¢æ¨¡å¼�
- HAL_UARTEx_EnableStopMode(&hlpuart1); // å�¯ç”¨LPUART1å�œæ¢æ¨¡å¼�
- hlpuart1.Instance->CR1 |= USART_CR1_UESM; // 使能LPUART1在STOP模�下的唤醒功能
- hlpuart1.Instance->CR3 |= USART_CR3_WUFIE; // 使能仿 STOP 模å¼�å”¤é†’çš„ä¸æ–¿
-
- // HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE2); // �置调压器为低功耗模弿
- HAL_PWREx_EnterSTOP2Mode(PWR_STOPENTRY_WFI); // 进入STOP2模�
- // HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1); // é…�置调压器为æ£å¸¸æ¨¡å¼�
-
- SysTick->CTRL |=(~SysTick_CTRL_TICKINT_Msk);//唤醒å�Žæ�¢å¤�SYSTICK䏿–的使èƒ?
- SysTick->CTRL |=(~SysTick_CTRL_ENABLE_Msk);//唤醒å�Žæ�¢å¤�SYSTICK䏿–的使èƒ?
- HAL_Delay(10);
- SystemClock_Config();
- MX_GPIO_Init();
- HAL_ADC_DeInit(&hadc1);
- MX_ADC1_Init();
- // HAL_UART_DeInit(&huart1);
- HAL_UART_DeInit(&hlpuart1);
- // MX_USART1_UART_Init();
- MX_LPUART1_UART_Init();
- // printf("Stop2 wakeup\n");
- }
- /* 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 */
|