51 lines
4.3 KiB
Plaintext
51 lines
4.3 KiB
Plaintext
|
|
# 工单 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")这种顺序,不显示年份(屏幕位置有限);如果需要年份显示,要另外找位置或者做成可选切换。
|