feat: 添加RTC管理模块并集成SNTP时间同步功能

实现RTC时间管理功能,支持通过SNTP自动同步网络时间并持久化存储
提供时间来源追踪和掉电保持功能,优化LCD显示的时间更新机制
This commit is contained in:
2026-02-24 01:06:41 +08:00
parent 43a5042c9e
commit addfb3faad
9 changed files with 798 additions and 50 deletions

View File

@@ -34,6 +34,7 @@
#include "spi_st7735s.h"
#include "stdio.h"
#include "bsp_aht30.h"
#include "bsp_rtc.h"
#include "i2c.h"
/* USER CODE END Includes */
@@ -82,6 +83,7 @@ typedef struct {
// 全局变量
static LCD_Page_t current_page = LCD_PAGE_TIME; // 当前显示页面
static Sensor_Data_t sensor_data = {0}; // 传感器数据
static volatile uint8_t lcd_force_refresh = 0; // 强制刷新标志RTC更新时设置
/* USER CODE END Variables */
/* Definitions for defaultTask */
@@ -130,6 +132,7 @@ void LCD_UpdateSensorData(float temp, float humi, float weight, uint8_t water,
uint8_t mode);
Sensor_Data_t *LCD_GetSensorData(void);
void user_button_init(void);
void RTC_TimeUpdateCallback(void); // RTC时间更新回调函数
/* USER CODE END FunctionPrototypes */
void StartDefaultTask(void *argument);
@@ -208,6 +211,9 @@ void StartDefaultTask(void *argument)
// 2. 初始化日志和屏幕(在 RTOS 任务中)
easylogger_init();
// 3. 初始化RTC管理模块在日志初始化后
BSP_RTC_Init();
// 初始化MP3模块
HAL_StatusTypeDef ret = MP3_Init();
if (ret != HAL_OK) {
@@ -241,7 +247,7 @@ void LCD_Task(void *argument)
/* USER CODE BEGIN LCD_Task */
char display_str[32];
SNTP_Time_t now;
RTC_Time_t rtc_time;
uint16_t text_color = ST7735_WHITE;
uint16_t bg_color = ST7735_BLACK;
@@ -255,6 +261,9 @@ void LCD_Task(void *argument)
sensor_data.water_level = 0; // NC - 未检测到水
sensor_data.system_mode = 1; // 自动模式
// 注册RTC时间更新回调SNTP同步后立即刷新LCD
BSP_RTC_RegisterCallback(RTC_TimeUpdateCallback);
/* Infinite loop */
for (;;) {
// 根据当前页面显示不同内容
@@ -265,22 +274,16 @@ void LCD_Task(void *argument)
ST7735_FillScreen(bg_color);
ST7735_WriteString(2, 2, "Time", &Font_7x10, text_color, bg_color);
if (WIFI_Is_Time_Valid()) {
WIFI_Get_SNTP_Time();
now = WIFI_Get_Current_Time();
if (now.valid) {
// 显示时间(大字体,只显示时:分,不显示秒)
snprintf(display_str, sizeof(display_str), "%02d:%02d", now.hour, now.minute);
ST7735_WriteString(25, 20, display_str, &Font_16x26, text_color, bg_color);
// 使用RTC时间独立于SNTP即使网络断开也能显示
if (BSP_RTC_GetTime(&rtc_time) == 0) {
// 显示时间(大字体,只显示时:分,不显示秒)
snprintf(display_str, sizeof(display_str), "%02d:%02d", rtc_time.hour, rtc_time.minute);
ST7735_WriteString(25, 20, display_str, &Font_16x26, text_color, bg_color);
// 显示年月日(小字体,向下移动并居中)
snprintf(display_str, sizeof(display_str), "%04d-%02d-%02d", now.year,
now.month, now.day);
ST7735_WriteString(20, 60, display_str, &Font_7x10, ST7735_CYAN, bg_color);
} else {
ST7735_WriteString(25, 20, "--:--", &Font_16x26, text_color, bg_color);
ST7735_WriteString(20, 60, "----/--/--", &Font_7x10, ST7735_CYAN, bg_color);
}
// 显示年月日(小字体,向下移动并居中)
snprintf(display_str, sizeof(display_str), "%04d-%02d-%02d",
rtc_time.year, rtc_time.month, rtc_time.day);
ST7735_WriteString(20, 60, display_str, &Font_7x10, ST7735_CYAN, bg_color);
} else {
ST7735_WriteString(25, 20, "--:--", &Font_16x26, text_color, bg_color);
ST7735_WriteString(20, 60, "----/--/--", &Font_7x10, ST7735_CYAN, bg_color);
@@ -340,11 +343,11 @@ void LCD_Task(void *argument)
ST7735_FillScreen(bg_color);
ST7735_WriteString(2, 2, "System Status", &Font_7x10, text_color, bg_color);
// 显示WiFi状态
if (WIFI_Is_Time_Valid()) {
ST7735_WriteString(5, 20, "WiFi: OK", &Font_11x18, ST7735_GREEN, bg_color);
// 显示MQTT连接状态
if (WIFI_Is_MQTT_Connected()) {
ST7735_WriteString(5, 20, "MQTT: OK", &Font_11x18, ST7735_GREEN, bg_color);
} else {
ST7735_WriteString(5, 20, "WiFi: OFF", &Font_11x18, ST7735_RED, bg_color);
ST7735_WriteString(5, 20, "MQTT: OFF", &Font_11x18, ST7735_RED, bg_color);
}
// 显示系统模式
@@ -366,6 +369,11 @@ void LCD_Task(void *argument)
if (current_page != displayed_page) {
break; // 检测到页面切换,立即跳出
}
if (lcd_force_refresh) {
// RTC时间更新立即刷新LCD
lcd_force_refresh = 0;
break;
}
osDelay(100); // 每100ms检查一次总共30秒
}
} else {
@@ -601,6 +609,14 @@ void LCD_UpdateSensorData(float temp, float humi, float weight, uint8_t water,
*/
Sensor_Data_t *LCD_GetSensorData(void) { return &sensor_data; }
/**
* @brief RTC时间更新回调函数
* @note 当RTC通过SNTP更新时间时调用立即刷新LCD显示
*/
void RTC_TimeUpdateCallback(void) {
lcd_force_refresh = 1;
}
/* USER CODE END LCD_Page_Functions */
/* USER CODE END Application */

View File

@@ -74,7 +74,6 @@ void HAL_I2C_MspInit(I2C_HandleTypeDef* i2cHandle)
GPIO_InitStruct.Pin = GPIO_PIN_6|GPIO_PIN_7;
GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
GPIO_InitStruct.Pull = GPIO_PULLUP;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
/* I2C1 clock enable */

View File

@@ -28,8 +28,7 @@
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "bsp_rtc.h"
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/