diff --git a/work-order/wo-05 b/work-order/wo-05 new file mode 100644 index 0000000..0eef6f4 --- /dev/null +++ b/work-order/wo-05 @@ -0,0 +1,56 @@ +# 工单 WO-05:细节问题修复清单 + +**优先级**:中 +**状态**:待处理 + +--- + +## 问题列表 + +1. 开机启动瞬间背光应保持关闭,等所有初始化都完成、即将进入 `while(1)` 主循环前才点亮,避免开机闪烁。 +2. 长按 KEY_CONFIRM 打开主菜单后,10 秒内无任何按键操作,自动关闭菜单返回时钟界面。 +3. 二级子菜单(传感器类型选择,`menu_level=1`)下,长按 KEY_CONFIRM 目前无法关闭菜单,需要补上。 +4. 默认菜单语言改为英文(目前首次开机/Flash 擦除态默认是法语)。 +5. 主菜单上下键切换菜单项允许循环切换(到顶/底后可以绕到另一端)。 +6. P3.6 进入休眠前改成电平触发方式作为唤醒源,现在经常唤醒不了处理器。 + +--- + +## 实现思路 + +### 1. 背光延迟点亮 + +- `Drivers/lcd.c` 的 `LCD_Init()` 第 89 行 `SGM_CTRL = 0;`(点亮背光)在整个 ST7789V 寄存器初始化序列**最开头**就执行了,这就是闪烁的直接原因——去掉这一行(或改成 `SGM_CTRL = 1` 熄灭)。 +- `App/system.c` 的 `GPIO_Init()` 只把 P1.7 配置成推挽输出,没有写初始电平,上电瞬间电平不确定;补一行 `SGM_CTRL = 1;`(熄灭),让背光从上电第一刻就确定是关的。 +- `App/main.c` 的 `main()` 里,在 `AppManager_StartApp(APP_ID_CLOCK)`(画出第一帧时钟界面)之后、`while(1)` 之前,加一行 `SGM_CTRL = 0;` 点亮背光。 + +### 2. 菜单 10 秒无操作自动关闭 + +- 现有的 `inactivity_timer`(`App/main.c`)是全局 60 秒深度休眠计时,粒度和用途都不一样,不能直接复用。 +- 在 `App/app_menu.c` 里新增一个 `static u16 menu_idle_enter_ms`,仿照 `Drivers/rf.c` 的 `RF_CheckDecodeWatchdog()`/`app_menu.c` 里已有的 `last_bind_tx_ms` 那种 `ms_tick` 环绕安全减法模式(`ms_tick` 是 0~999 循环的 1ms 计时)。 +- `MenuApp_onEvent()` 每收到一次按键事件就刷新这个时间戳。 +- 需要一个周期性检查点:目前 AppManager 框架没有 `OnTick`/`OnUpdate` 回调,需要确认要不要新增一个,或者简单地在 `main.c` 的 `while(1)` 里,当前台 App 是 `menu_app` 时调用一个新增的 `MenuApp_CheckIdleTimeout()`。超时后调用 `AppManager_SwitchToForeground(&clock_app)`。 + +### 3. 子菜单长按 CONFIRM 关闭菜单 + +- `App/app_menu.c` 的 `menu_level == 1` 分支(第 156-189 行)目前只处理了 `KEY_EVENT_DOWN_LONG`(退回 `menu_level=0`),没有处理 `KEY_EVENT_CONFIRM_LONG`。 +- 参照同文件 `menu_level == 2` 分支的写法,在 `menu_level == 1` 里加一段 `KEY_EVENT_CONFIRM_LONG` 处理,直接 `AppManager_SwitchToForeground(&clock_app)` 整个退出菜单(而不是只退一级)。 + +### 4. 默认语言改英文 + +- `App/language.c`:`static Language current_lang = LANG_FR;` 改成 `LANG_EN`。 +- 同文件 `Lang_Init()` 里的越界回退分支 `(lang < LANG_COUNT) ? lang : LANG_FR` 改成 `: LANG_EN`。 +- 两处都要改,否则开机静态初始值和 Flash 擦除态回退值会不一致。 + +### 5. 菜单上下循环切换 + +- `App/app_menu.c` 里两处 UP/DOWN 边界判断都要改: + - `menu_level == 0`(第 106-121 行,4 项,索引 0~3) + - `menu_level == 1`(第 158-172 行,5 项,索引 0~4) +- 现在是 `if (menu_select > 0) menu_select--;` / `if (menu_select < MAX) menu_select++;`,到边界就不动;改成到边界时绕到另一端,例如 UP 在 `menu_select==0` 时跳到 `MAX`,DOWN 在 `menu_select==MAX` 时跳回 `0`。 + +### 6. P3.6 休眠前改电平触发唤醒 + +- 现状:`RF_HandleEdgeInterrupt()` 用软件乒乓单边沿切换模拟双边沿触发,`P3IM0` 会在上升沿/下降沿之间动态翻转;`Enter_Low_Power_Sleep()` 进入休眠前完全没有重新设置 `P3IM0`/`P3IM1`,导致进入 Power Down 那一刻 `P3IM0` 具体停在哪个方向是不确定的,如果停在"等下降沿"而实际先来的是上升沿,就可能唤醒不了或唤醒延迟。 +- **需要注意**:根据 WO-04 §2.9 查到的《STC32G 技术手册》15.1.3 节真值表,`PxIM1/PxIM0` 的"高电平中断"和"低电平中断"两种模式**都标注为不支持掉电唤醒**,只有下降沿/上升沿两种边沿模式支持。这与本条需求(改成电平触发来解决唤醒不了的问题)在文档上是矛盾的,实现时要先在真机上实测电平触发是否真的能唤醒;如果实测不行,退回到"休眠前强制把 P3IM0/P3IM1 设成固定的某一个边沿方向(比如固定成上升沿),不再依赖乒乓切换留下的随机状态"这个更符合手册说明的方案。 +- 具体改法(不管选电平还是固定边沿):在 `App/system.c` 的 `Enter_Low_Power_Sleep()` 里,`P3WKUE |= 0x40;` 之前,加一段显式设置 `P3IM1`/`P3IM0` 的代码,覆盖掉睡前可能残留的任意状态;如果验证后确定要改回边沿触发,`Wakeup_Restore()` 里对应也要把 `P3IM1`/`P3IM0` 重新设回 `RF_Init()` 里的初始方向,保证唤醒后解码状态机从一个已知状态重新开始。