Kaynağa Gözat

添加rtc设置闹钟

xuxinyi 1 ay önce
ebeveyn
işleme
ad1aedb124
3 değiştirilmiş dosya ile 139 ekleme ve 85 silme
  1. 9 9
      Core/Inc/RTC_SLEEP.h
  2. 62 74
      Core/Src/RTC_SLEEP.c
  3. 68 2
      Core/Src/main.c

+ 9 - 9
Core/Inc/RTC_SLEEP.h

@@ -13,15 +13,15 @@
 
 
 // 定义结构体一个结构体用于存储读取到的日期时间
-// typedef struct {
-//     uint8_t hours;
-//     uint8_t minutes;
-//     uint8_t seconds;
-//     uint8_t weekday;
-//     uint8_t month;
-//     uint8_t date;
-//     uint8_t year;
-// } RTC_DateTimeTypeDef;
+typedef struct {
+    uint8_t hours;
+    uint8_t minutes;
+    uint8_t seconds;
+    uint8_t weekday;
+    uint8_t month;
+    uint8_t date;
+    uint8_t year;
+} RTC_DateTimeTypeDef;
 //
 // typedef struct {
 //     RTC_DateTimeTypeDef startTime;  // 按下时的完整RTC时间

+ 62 - 74
Core/Src/RTC_SLEEP.c

@@ -8,81 +8,69 @@ RTC_TimeTypeDef JUGE_key_struct = {0};
 RTC_TimeTypeDef Online_struct = {0};
 RTC_TimeTypeDef SOS_struct = {0};
 RTC_TimeTypeDef IDLE_struct = {0};
-// RTC_key_struct SOS_key_struct = {
-//     .key_Count = 0,
-//     .key_Duration = 0,
-//     .key_CheckActive = FALSE
-// };
-//
-// RTC_key_struct JUGE_key_struct = {
-//     .key_Count = 0,
-//     .key_Duration = 0,
-//     .key_CheckActive = FALSE
-// };
 
+// 单独的RTC时间和日期设置函数
+void RTC_SetDateTime(RTC_HandleTypeDef *hrtc, uint8_t hours, uint8_t minutes, uint8_t seconds,
+                     uint8_t weekday, uint8_t month, uint8_t date, uint8_t year) {
+    RTC_TimeTypeDef sTime = {0};
+    RTC_DateTypeDef sDate = {0};
 
-// // 单独的RTC时间和日期设置函数
-// void RTC_SetDateTime(RTC_HandleTypeDef *hrtc, uint8_t hours, uint8_t minutes, uint8_t seconds,
-//                      uint8_t weekday, uint8_t month, uint8_t date, uint8_t year) {
-//     RTC_TimeTypeDef sTime = {0};
-//     RTC_DateTypeDef sDate = {0};
-//
-//     // 设置时间
-//     sTime.Hours = hours;
-//     sTime.Minutes = minutes;
-//     sTime.Seconds = seconds;
-//     HAL_RTC_SetTime(hrtc, &sTime, RTC_FORMAT_BCD);
-//
-//     // 设置日期
-//     sDate.WeekDay = weekday;
-//     sDate.Month = month;
-//     sDate.Date = date;
-//     sDate.Year = year;
-//     HAL_RTC_SetDate(hrtc, &sDate, RTC_FORMAT_BCD);
-// }
+    // 设置时间
+    sTime.Hours = hours;
+    sTime.Minutes = minutes;
+    sTime.Seconds = seconds;
+    HAL_RTC_SetTime(hrtc, &sTime, RTC_FORMAT_BCD);
 
-// // 读取RTC当前时间和日期
-// void RTC_GetDateTime(RTC_HandleTypeDef *hrtc, RTC_DateTimeTypeDef *datetime) {
-//     RTC_TimeTypeDef sTime = {0};
-//     RTC_DateTypeDef sDate = {0};
-//
-//     // 读取当前时间
-//     HAL_RTC_GetTime(hrtc, &sTime, RTC_FORMAT_BCD);
-//     // 读取当前日期
-//     HAL_RTC_GetDate(hrtc, &sDate, RTC_FORMAT_BCD);
-//
-//     // 存储到自定义结构体中
-//     datetime->hours = sTime.Hours;
-//     datetime->minutes = sTime.Minutes;
-//     datetime->seconds = sTime.Seconds;
-//     datetime->weekday = sDate.WeekDay;
-//     datetime->month = sDate.Month;
-//     datetime->date = sDate.Date;
-//     datetime->year = sDate.Year;
-// }
-//
-// void RTC_Sleep_Enter_Fun() {
-//     /* 调用独立的函数设置初始时间 */
-//     RTC_SetDateTime(&hrtc, 0x12, 0x00, 0x00,
-//                    RTC_WEEKDAY_MONDAY, RTC_MONTH_SEPTEMBER, 0x16, 0x25);
-//
-//     /* 获取当前时间用于设置闹钟 */
-//     RTC_TimeTypeDef currentTime = {0};
-//     HAL_RTC_GetTime(&hrtc, &currentTime, RTC_FORMAT_BCD);
-//
-//     /* 设置闹钟:50秒后触发 */
-//     RTC_AlarmTypeDef sAlarm = {0};
-//     sAlarm.AlarmTime.Hours = currentTime.Hours;
-//     sAlarm.AlarmTime.Minutes = currentTime.Minutes;
-//     sAlarm.AlarmTime.Seconds = (currentTime.Seconds + 50) % 60;
-//     sAlarm.Alarm = RTC_ALARM_A;
-//
-//     HAL_RTC_SetAlarm_IT(&hrtc, &sAlarm, RTC_FORMAT_BCD);
-//
-//     /* 进入 STANDBY 模式 */
-//     __HAL_PWR_CLEAR_FLAG(PWR_FLAG_WU);               // 清除唤醒标志
-//     HAL_PWR_EnterSTANDBYMode();                      // MCU 进入 STANDBY
-//
-//     // MCU 唤醒后会从 main() 重新开始运行
-// }
+    // 设置日期
+    sDate.WeekDay = weekday;
+    sDate.Month = month;
+    sDate.Date = date;
+    sDate.Year = year;
+    HAL_RTC_SetDate(hrtc, &sDate, RTC_FORMAT_BCD);
+}
+
+// 读取RTC当前时间和日期
+void RTC_GetDateTime(RTC_HandleTypeDef *hrtc, RTC_DateTimeTypeDef *datetime) {
+    RTC_TimeTypeDef sTime = {0};
+    RTC_DateTypeDef sDate = {0};
+
+    // 读取当前时间
+    HAL_RTC_GetTime(hrtc, &sTime, RTC_FORMAT_BCD);
+    // 读取当前日期
+    HAL_RTC_GetDate(hrtc, &sDate, RTC_FORMAT_BCD);
+
+    // 存储到自定义结构体中
+    datetime->hours = sTime.Hours;
+    datetime->minutes = sTime.Minutes;
+    datetime->seconds = sTime.Seconds;
+    datetime->weekday = sDate.WeekDay;
+    datetime->month = sDate.Month;
+    datetime->date = sDate.Date;
+    datetime->year = sDate.Year;
+}
+
+void RTC_Sleep_Enter_Fun() {
+    /* 调用独立的函数设置初始时间 */
+    RTC_SetDateTime(&hrtc, 0x12, 0x00, 0x00,
+                   RTC_WEEKDAY_MONDAY, RTC_MONTH_SEPTEMBER, 0x16, 0x25);
+
+    /* 获取当前时间用于设置闹钟 */
+    RTC_TimeTypeDef currentTime = {0};
+    HAL_RTC_GetTime(&hrtc, &currentTime, RTC_FORMAT_BCD);
+
+    /* 设置闹钟:50秒后触发 */
+    RTC_AlarmTypeDef sAlarm = {0};
+    sAlarm.AlarmTime.Hours = currentTime.Hours;
+    sAlarm.AlarmTime.Minutes = currentTime.Minutes;
+    sAlarm.AlarmTime.Seconds = (currentTime.Seconds + 50) % 60;
+    sAlarm.Alarm = RTC_ALARM_A;
+
+    HAL_RTC_SetAlarm_IT(&hrtc, &sAlarm, RTC_FORMAT_BCD);
+
+    /* 进入 STANDBY 模式 */
+    __HAL_PWR_CLEAR_FLAG(PWR_FLAG_WU);               // 清除唤醒标志
+    HAL_PWR_EnterSTANDBYMode();                      // MCU 进入 STANDBY
+
+    // MCU 唤醒后会从 main() 重新开始运行
+}
 

+ 68 - 2
Core/Src/main.c

@@ -231,6 +231,47 @@ int IsTimeElapsed(RTC_HandleTypeDef *hrtc, RTC_TimeTypeDef *last, uint32_t inter
   return 0;         // 未超时
 }
 
+
+#include "stdio.h"
+
+void Set_Alarm_After_20s(void)
+{
+  RTC_TimeTypeDef now;
+  RTC_DateTypeDef date;
+
+  // 读当前时间
+  HAL_RTC_GetTime(&hrtc, &now, RTC_FORMAT_BIN);
+  HAL_RTC_GetDate(&hrtc, &date, RTC_FORMAT_BIN); // 必须读 Date 解锁
+
+  // 计算目标时间
+  uint8_t sec = now.Seconds + 50;
+  uint8_t min = now.Minutes;
+  uint8_t hr  = now.Hours;
+
+  if (sec >= 60) { sec -= 60; min++; }
+  if (min >= 60) { min -= 60; hr++; }
+  if (hr >= 24)  { hr = 0; }
+
+  RTC_AlarmTypeDef sAlarm = {0};
+  sAlarm.AlarmTime.Hours   = hr;
+  sAlarm.AlarmTime.Minutes = min;
+  sAlarm.AlarmTime.Seconds = sec;
+  sAlarm.Alarm = RTC_ALARM_A;
+
+  // 设置闹钟中断
+  if(HAL_RTC_SetAlarm_IT(&hrtc, &sAlarm, RTC_FORMAT_BIN) != HAL_OK)
+  {
+    Error_Handler();
+  }
+
+  printf("Now      : %02d:%02d:%02d\r\n", now.Hours, now.Minutes, now.Seconds);
+  printf("NextAlarm: %02d:%02d:%02d\r\n", hr, min, sec);
+}
+
+
+
+
+
 /* USER CODE END 0 */
 
 /**
@@ -278,7 +319,32 @@ int main(void)
   HAL_UART_Receive_DMA(&huart2, rx_buf_uart2_DMA, sizeof(rx_buf_uart2_DMA));
   __HAL_UART_ENABLE_IT(&huart2, UART_IT_IDLE);
   Flash_Read_LoraAddr(&deviceInfo.loraDeviceAddress_H, &deviceInfo.loraDeviceAddress_L);
-  // printf("deviceInfo.loraDeviceAddress_H:%02X,deviceInfo.loraDeviceAddress_L:%02X\r\n", deviceInfo.loraDeviceAddress_H, deviceInfo.loraDeviceAddress_L);
+
+  printf("开始\r\n");
+  // HAL_Delay(10000);
+  int i = 0;
+  // HAL_Delay(10*1000);
+  Set_Alarm_After_20s();
+
+  while (TRUE) {
+
+
+    RTC_TimeTypeDef now;
+
+    // 读当前时间
+    HAL_RTC_GetTime(&hrtc, &now, RTC_FORMAT_BIN);
+
+    printf("Now      : %02d:%02d:%02d\r\n", now.Hours, now.Minutes, now.Seconds);
+    // printf("NextAlarm: %02d:%02d:%02d\r\n", hr, min, sec);
+
+    // HAL_Delay(1000);
+  }
+
+
+
+  while (TRUE) {
+    printf("123\r\n");
+  }
   if (deviceInfo.loraDeviceAddress_H == 0xFF || deviceInfo.loraDeviceAddress_L == 0xFF || deviceInfo.loraDeviceAddress_H == 0x00 || deviceInfo.loraDeviceAddress_L == 0x00) { // 未设置Lora地址,应该是初次启动,配置Lora地址蓝牙等
     HAL_Delay(4000);
     printf("开始初始化\r\n");
@@ -328,7 +394,7 @@ int main(void)
   /* USER CODE BEGIN WHILE */
 
   printf("设备地址:0x%02X%02X\n", deviceInfo.loraDeviceAddress_H, deviceInfo.loraDeviceAddress_L);
-  uint8_t i = 0;
+
   while (1)
   {
     /* USER CODE END WHILE */