|
|
@@ -29,48 +29,103 @@ void RTC_SetDateTime(RTC_HandleTypeDef *hrtc, uint8_t hours, uint8_t minutes, ui
|
|
|
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};
|
|
|
+// // 读取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, ¤tTime, 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() 重新开始运行
|
|
|
+// }
|
|
|
|
|
|
- // 读取当前时间
|
|
|
- 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);
|
|
|
+/**
|
|
|
+ * @brief 设置指定秒数后的闹钟
|
|
|
+ * @param delay_seconds 延迟秒数(最大支持 24*3600-1 秒,即一天内)
|
|
|
+ */
|
|
|
+void Set_Alarm_After(uint32_t delay_seconds)
|
|
|
+{
|
|
|
+ if (delay_seconds == 0 || delay_seconds >= 24*3600)
|
|
|
+ {
|
|
|
+ // 超过 RTC 最大范围,报错或截断
|
|
|
+ printf("Error: delay_seconds must be 1 ~ 86399\r\n");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ RTC_TimeTypeDef now;
|
|
|
+ RTC_DateTypeDef date;
|
|
|
+
|
|
|
+ // 读当前时间
|
|
|
+ HAL_RTC_GetTime(&hrtc, &now, RTC_FORMAT_BIN);
|
|
|
+ HAL_RTC_GetDate(&hrtc, &date, RTC_FORMAT_BIN); // 必须读 Date 解锁
|
|
|
+
|
|
|
+ // 将当前时间转换为总秒数
|
|
|
+ uint32_t now_seconds = now.Hours * 3600 + now.Minutes * 60 + now.Seconds;
|
|
|
|
|
|
- /* 获取当前时间用于设置闹钟 */
|
|
|
- RTC_TimeTypeDef currentTime = {0};
|
|
|
- HAL_RTC_GetTime(&hrtc, ¤tTime, RTC_FORMAT_BCD);
|
|
|
+ // 计算目标时间总秒数
|
|
|
+ uint32_t alarm_seconds = now_seconds + delay_seconds;
|
|
|
+ if (alarm_seconds >= 24*3600)
|
|
|
+ alarm_seconds -= 24*3600; // 跨天处理
|
|
|
|
|
|
- /* 设置闹钟:50秒后触发 */
|
|
|
+ // 分解为时分秒
|
|
|
+ uint8_t hr = alarm_seconds / 3600;
|
|
|
+ uint8_t min = (alarm_seconds % 3600) / 60;
|
|
|
+ uint8_t sec = alarm_seconds % 60;
|
|
|
+
|
|
|
+ // 设置闹钟
|
|
|
RTC_AlarmTypeDef sAlarm = {0};
|
|
|
- sAlarm.AlarmTime.Hours = currentTime.Hours;
|
|
|
- sAlarm.AlarmTime.Minutes = currentTime.Minutes;
|
|
|
- sAlarm.AlarmTime.Seconds = (currentTime.Seconds + 50) % 60;
|
|
|
+ sAlarm.AlarmTime.Hours = hr;
|
|
|
+ sAlarm.AlarmTime.Minutes = min;
|
|
|
+ sAlarm.AlarmTime.Seconds = sec;
|
|
|
sAlarm.Alarm = RTC_ALARM_A;
|
|
|
|
|
|
- HAL_RTC_SetAlarm_IT(&hrtc, &sAlarm, RTC_FORMAT_BCD);
|
|
|
+ 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);
|
|
|
|
|
|
- /* 进入 STANDBY 模式 */
|
|
|
+ // /* 进入 STANDBY 模式 */
|
|
|
__HAL_PWR_CLEAR_FLAG(PWR_FLAG_WU); // 清除唤醒标志
|
|
|
HAL_PWR_EnterSTANDBYMode(); // MCU 进入 STANDBY
|
|
|
-
|
|
|
- // MCU 唤醒后会从 main() 重新开始运行
|
|
|
}
|
|
|
|
|
|
+
|