From 4a55c1f9eb7679535e1dd8ed2b852631caca9ab9 Mon Sep 17 00:00:00 2001 From: edisondeng Date: Fri, 31 Jul 2026 19:26:55 +0800 Subject: [PATCH] docs: add wo-07 to add real year/month/day/weekday support --- work-order/wo-07 | 50 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 work-order/wo-07 diff --git a/work-order/wo-07 b/work-order/wo-07 new file mode 100644 index 0000000..39f3c34 --- /dev/null +++ b/work-order/wo-07 @@ -0,0 +1,50 @@ +# 工单 WO-07:完善日期功能 (年/月/日/星期) + +**优先级**:中 +**状态**:待处理 + +--- + +## 问题列表 + +1. 软时钟(`App/clock.c`)只有时/分/秒,没有年、月、日、星期。 +2. `PCF8563_ReadTime`/`PCF8563_WriteTime` 只读写时分秒三个寄存器,芯片本身支持的日/星期/月/年寄存器(0x05~0x08)从没被用过。 +3. `set_clock_app` 只能调小时和分钟,没有日期可调。 +4. HOME APP 和时间设置界面上显示的"星期 日-月"是写死的占位字符串 `"VEN 10-07"`/`"FRI 10-07"`,不是真实日期。 + +--- + +## 实现思路 + +### 1. 驱动层:`Drivers/pcf8563.c`/`.h` + +PCF8563 的秒/分/时/日/星期/月/年寄存器地址是连续的(0x02~0x08,共 7 字节),可以一次 I2C 连续读写全部拿到/写入,不用分开多次收发: + +- 新增 `PCF8563_ReadDateTime(u8 *hour, u8 *min, u8 *sec, u8 *day, u8 *month, u8 *year)`:从 0x02 开始连续读 7 字节,`day` 掩码 `0x3F`(BCD),`month` 掩码 `0x1F`(BCD,忽略 bit7 世纪位),`year` 直接 BCD 转十进制(0~99,代表 2000~2099)。 +- 新增 `PCF8563_WriteDateTime(u8 hour, u8 min, u8 sec, u8 day, u8 month, u8 year, u8 weekday)`:从 0x02 开始连续写 7 字节,包含星期(0x06,取值 0~6,不需要 BCD 转换,直接写数值)。 +- 旧的 `PCF8563_ReadTime`/`PCF8563_WriteTime` 保留,内部改成调用新函数并丢弃日期部分,避免改动现有调用点(`app_home.c`/`app_set_clock.c`)。 +- 世纪位(月寄存器 bit7)不处理,固定按 2000~2099 年处理,这个产品的使用年限内不用考虑跨世纪。 + +### 2. 软时钟层:`App/clock.c`/`.h` + +- 新增全局变量 `u8 current_day`、`u8 current_month`、`u8 current_year`(0~99,代表 2000~2099)、`u8 current_weekday`(0~6,周日=0 或周一=0,需要定一个约定,建议跟 Zeller 公式的定义保持一致)。 +- `Clock_IncMS()` 现有的时/分/小时进位链条(秒→分→时)后面继续接上日/月/年进位:小时满 24 归零时,`current_day++`;根据"每月天数表"(`{31, 28或29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}`,2 月按闰年规则(能被 4 整除且(不能被 100 整除或能被 400 整除),2000~2099 区间内简化成"能被 4 整除"即可)判断是否要月进位、年进位(99 → 0,不处理世纪)。 +- 日期发生变化(不管是自然进位还是手动调节)时,用 Zeller 公式或类似算法重新计算 `current_weekday`,不依赖 PCF8563 自己的星期寄存器自增(避免手动改日期后星期跟着错乱);写入 RTC 时把算出来的星期一起写进去,保持芯片内部数据一致。 +- `HomeApp_OnStart()`/相关读取 RTC 的地方,从 `PCF8563_ReadTime` 换成 `PCF8563_ReadDateTime`,一并读回日期。 + +### 3. 界面层:`App/ui.c`/`.h` + +- 新增星期缩写字符串表(法语/英语),参照现有占位文案风格:`LUN/MAR/MER/JEU/VEN/SAM/DIM` 对应 `MON/TUE/WED/THU/FRI/SAT/SUN`,放进 `App/strings.h` 的 `WRISTBAND_STRING_LIST`。 +- `UI_ShowClockPage()`/`UI_ShowSetTimePage()` 里原来直接 `Lang_Get(STR_CLOCK_DATE)` 显示死文案的地方,改成拼接"星期缩写 + 日-月两位数字"的动态字符串,用真实的 `current_weekday`/`current_day`/`current_month` 现算现拼。 + +### 4. 时间设置 App:`App/app_set_clock.c` + +- `time_edit_field` 从 1~2(时/分)扩展到 1~5(时/分/日/月/年),长按 CONFIRM 依次循环切换。 +- 上下键调节日/月/年时要做合理的范围限制和循环(日 1~当月最大天数、月 1~12、年 0~99),月份变化时如果当前日超过新月份的最大天数要做截断处理(比如从 31 号切到 2 月要变成 28/29 号)。 +- 局部刷新沿用 WO-06 刚做的模式,不要整屏重绘:日/月/年每个字段各自对应屏幕上一小块数字区域,只刷新当前正在调节的那一块。 +- 保存(短按 CONFIRM)时用新的 `PCF8563_WriteDateTime()`,同时把算好的 `current_weekday` 一起写入。 + +### 5. 需要确认的点 + +- 星期数值约定(0=周日 还是 0=周一)以及对应的 Zeller 公式实现需要仔细算一遍避免算错,建议实现后用几个已知日期(比如今天)手动核对星期是否正确。 +- 日期显示格式沿用现有"星期 日-月"(如 "MON 03-08")这种顺序,不显示年份(屏幕位置有限);如果需要年份显示,要另外找位置或者做成可选切换。