# RTC 模块说明 ## 1. 模块位置 - `BSP/rtc/rtc.c` - `BSP/rtc/rtc.h` ## 2. 模块职责 - 完成 MCU 内部 RTC 外设初始化(默认 `LXTAL 32.768kHz`) - 提供统一时间读写接口(业务层使用 `Comm_Time`) - 提供时间算法工具: - 本地时间(UTC+8)与 Unix 时间戳互转 - OCPP 时间戳解析 - 按时区偏移调整时间(支持跨天/月/年) ## 3. 硬件与掉电行为说明 ### 3.1 `RTC_BKP0` 是什么 - `RTC_BKP0` 是 RTC 备份寄存器中的一个槽位(软件可读写) - 本项目中它作为“RTC 是否已初始化”的标记位使用 - 典型逻辑: - `RTC_BKP0 == BKP_VALUE`:认为已配置过,不覆盖当前时间 - `RTC_BKP0 != BKP_VALUE`:按默认时间初始化并写入标记 ### 3.2 掉电后时间会不会继续走 - `RTC_BKP0` 只是存储标记,不会自动计时 - 时间能否在掉电期间继续增加,取决于 RTC 域是否持续供电(VBAT)以及 RTC 时钟是否持续工作 - 若掉电导致备份域失电,RTC 计时会停止;下次上电会按“首次初始化”逻辑处理 ## 4. 默认时间策略 - 当前默认时间由 `rtc.c` 宏定义控制: - `RTC_DEFAULT_YEAR_BCD` - `RTC_DEFAULT_MONTH_BCD` - `RTC_DEFAULT_DAY_BCD` - `RTC_DEFAULT_HOUR_BCD` - `RTC_DEFAULT_MINUTE_BCD` - `RTC_DEFAULT_SECOND_BCD` - `RTC_DEFAULT_WEEKDAY` - 默认值仅在“未初始化/备份标记无效”时生效,不会每次上电都覆盖已有时间 ## 5. 对外接口 - `void v_rtc_init(void);` - RTC 初始化入口(由 `BSP/sys_drv_init.c` 调用) - `void GetCurrentTime(Comm_Time *curTime);` - 读取当前时间到 `Comm_Time` - `void v_rtc_set_time(Comm_Time *curTime);` - 写 RTC 时间(内含时间合法性检查) - `unsigned int xDate2Seconds(Comm_Time *time);` - 本地时间(UTC+8)转 Unix 秒(UTC) - `void xSeconds2Date(unsigned long seconds, Comm_Time *time);` - Unix 秒(UTC)转本地时间(UTC+8) - `U8_T u8_ocpp_timestamp_to_tm(Comm_Time *ctTime, const char *time_str, U8_T time_type);` - 解析 OCPP 时间戳(支持 `Z`、`+08:00`、`-05:30` 等) - `time_type=0`:输出 UTC - `time_type=1`:输出北京时间(UTC+8) - `void v_adjust_time_with_timezone(Comm_Time *ctTime, int hour_offset, int min_offset);` - 对 `Comm_Time` 按时区偏移修正 - `void test_rtc(void);` - RTC 自测接口(打印当前时间) ## 6. 启动与调用链 1. `main.c` -> `v_sys_hardware_init()` 2. `BSP/sys_drv_init.c` -> `v_rtc_init()` 3. 业务层通过 `GetCurrentTime/v_rtc_set_time` 访问时间 4. `app/app_init/app_test.c` 在周期测试中可触发 RTC 读写测试 ## 7. 常见问题 - **Q: 修改默认时间后,为什么上电看到的不是默认值?** A: 因为备份标记仍有效,模块判断为“已初始化”,不会覆盖当前时间。 - **Q: 想强制重新走默认时间怎么办?** A: 清空备份标记(例如清 `RTC_BKP0`)或清备份域后重启。 ## 8. 相关文档 - [返回主说明 README](../../README.md) - [externalflash 模块说明](../externalflash/externalflash模块说明.md)