Files
stc32g128k/Docs/60_coding/mod-key.md

137 lines
4.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 编码实现 - 按键扫描与事件判定 (Docs/60_coding/mod-key.md)
本文件对应按键状态消抖、确认键长按 3 秒判定以及主键事件注入的具体编码实现细节。
## 1. 对应代码源文件
* [App/main.c](file:///c:/workfile/105/stc32g12k128/App/main.c) (定时中断内的按键扫描、按键状态高阻读取、长短按电平扫描)
## 2. 关键代码片段与逻辑实现
### 2.1 按键中断定时器扫描 (每 10ms 调度一次)
`Timer1_Isr` (1ms 滴答) 内,通过 `key_scan_timer` 进行 10ms 分频并调用 `Key_Scan_Process()`
```c
void Key_Scan_Process(void) {
// 1. 读取引脚状态并消抖
static u8 key_up_state = 0xFF;
static u8 key_down_state = 0xFF;
static u8 key_confirm_state = 0xFF;
static u8 key_sos1_state = 0xFF;
static u8 key_sos2_state = 0xFF;
u8 key_sos_state;
key_up_state = (key_up_state << 1) | KEY_UP;
key_down_state = (key_down_state << 1) | KEY_DOWN;
key_confirm_state = (key_confirm_state << 1) | KEY_CONFIRM;
key_sos1_state = (key_sos1_state << 1) | KEY_SOS1;
key_sos2_state = (key_sos2_state << 1) | KEY_SOS2;
// 双上部 SOS 键的逻辑并联
key_sos_state = key_sos1_state & key_sos2_state;
// 2. 按键长按与短按状态机扫描
// ▲ 键 (UP) 处理
if ((key_up_state & 0x07) == 0) {
key_up_hold++;
} else {
if (key_up_hold > 2) {
key_event_buf = KEY_UP_SHORT;
}
key_up_hold = 0;
}
// ▼ 键 (DOWN) 处理 (支持长按 2 秒清除报警/退出)
if ((key_down_state & 0x07) == 0) {
key_down_hold++;
if (key_down_hold == 200) { // 2秒
key_event_buf = KEY_DOWN_LONG;
}
} else {
if (key_down_hold > 2 && key_down_hold < 200) {
key_event_buf = KEY_DOWN_SHORT;
}
key_down_hold = 0;
}
// ■ 确认键 (CONFIRM) 处理 (支持长按 3 秒进入/退出)
if ((key_confirm_state & 0x07) == 0) {
key_confirm_hold++;
if (key_confirm_hold == 300) { // 3秒
key_event_buf = KEY_CONFIRM_LONG;
}
} else {
if (key_confirm_hold > 2 && key_confirm_hold < 300) {
key_event_buf = KEY_CONFIRM_CLICK;
}
key_confirm_hold = 0;
}
// 并联 SOS 键
if ((key_sos_state & 0x07) == 0) {
key_sos_hold++;
if (key_sos_hold == 3) {
key_event_buf = KEY_SOS_ACTIVE;
}
} else {
key_sos_hold = 0;
}
}
```
### 2.2 事件解调与微调分配分发 (Process_System_Event 示例)
在主循环事件分发中,对各个状态下的事件进行处理:
```c
void Process_System_Event(KeyEvent evt) {
switch (current_state) {
case STATE_MENU:
if (evt == KEY_UP_SHORT) {
if (menu_index > 0) menu_index--;
Redraw = 1;
} else if (evt == KEY_DOWN_SHORT) {
if (menu_index < 3) menu_index++;
Redraw = 1;
} else if (evt == KEY_CONFIRM_CLICK) {
Enter_Menu_Branch(menu_index);
} else if (evt == KEY_CONFIRM_LONG) {
current_state = STATE_CLOCK;
Redraw = 1;
}
break;
case STATE_PAIR_CONFIRM:
// 直接进行后缀序号微调 (传感器类型已由射频数据码自动识别并锁定)
if (evt == KEY_UP_SHORT) {
if (selected_suffix < 99) selected_suffix++;
Redraw = 1;
} else if (evt == KEY_DOWN_SHORT) {
if (selected_suffix > 1) selected_suffix--;
Redraw = 1;
} else if (evt == KEY_CONFIRM_CLICK) {
// 点击 CONFIRM直接将自动解析的类型和调整好的序号写入数据库
Add_Sensor(captured_addr, auto_detected_type, selected_suffix);
current_state = STATE_CLOCK;
Redraw = 1;
} else if (evt == KEY_CONFIRM_LONG) {
// 长按 3 秒放弃保存返回时钟
current_state = STATE_CLOCK;
Redraw = 1;
}
break;
case STATE_IPC_BIND:
if (evt == KEY_CONFIRM_LONG || evt == KEY_DOWN_LONG) {
current_state = STATE_CLOCK;
Redraw = 1;
} else if (evt == KEY_CONFIRM_CLICK) {
EV1527_Transmit(bracelet_factory_id, 0x01);
}
break;
// 其它状态处理...
}
}
```
<!-- Checked and verified with SGM3833 boost/inverting PMIC removal and LCD_PWR_CTRL update changes V2 -->