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

158 lines
4.8 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-event.md)
本文件对应物理按键及射频中断事件采集(输入)、环形消息队列缓冲、以及事件路由分配器(输出)的具体编码实现。
## 1. 对应代码源文件
* [App/main.c](file:///c:/workfile/105/stc32g12k128/App/main.c) (按键消抖 `Key_Scan_Process`、事件队列及 `Event_Dispatcher_Loop` 分发逻辑)
* [Drivers/rf.c](file:///c:/workfile/105/stc32g12k128/Drivers/rf.c) (配置 `P2.1` 输入捕捉及解码逻辑)
* [App/config.h](file:///c:/workfile/105/stc32g12k128/App/config.h) (`KeyEvent` 核心事件枚举类型声明)
## 2. 关键代码片段与逻辑实现
### 2.1 事件采集输入(按键定时扫描与消抖)
定义按键 IO 宏,在 `Timer1` (10ms) 分频中读取并判定:
```c
sbit KEY_UP = P0^1; // Pin 30
sbit KEY_CONFIRM = P0^2; // Pin 31
sbit KEY_DOWN = P0^3; // Pin 32
sbit KEY_SOS = P2^6; // Pin 27 (物理并联 SOS1/SOS2 按键)
void Key_Scan_Process(void) {
static u8 key_up_state = 0xFF;
static u8 key_down_state = 0xFF;
static u8 key_confirm_state = 0xFF;
static u8 key_sos_state = 0xFF;
// 移位滤波消抖
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_sos_state = (key_sos_state << 1) | KEY_SOS;
// ▲ 键 (UP) 处理
if ((key_up_state & 0x07) == 0) {
key_up_hold++;
} else {
if (key_up_hold > 2) {
Event_Queue_Push(KEY_EVENT_UP_CLICK);
}
key_up_hold = 0;
}
// ▼ 键 (DOWN) 处理 (长按 2 秒退出或清除警报)
if ((key_down_state & 0x07) == 0) {
key_down_hold++;
if (key_down_hold == 200) {
Event_Queue_Push(KEY_EVENT_DOWN_LONG);
}
} else {
if (key_down_hold > 2 && key_down_hold < 200) {
Event_Queue_Push(KEY_EVENT_DOWN_CLICK);
}
key_down_hold = 0;
}
// ■ 确认键 (CONFIRM) 处理 (长按 3 秒进入菜单,短按确认)
if ((key_confirm_state & 0x07) == 0) {
key_confirm_hold++;
if (key_confirm_hold == 300) {
Event_Queue_Push(KEY_EVENT_SOS_LONG); // 长按事件
}
} else {
if (key_confirm_hold > 2 && key_confirm_hold < 300) {
Event_Queue_Push(KEY_EVENT_SOS_CLICK); // 短击事件
}
key_confirm_hold = 0;
}
// SOS 求救键 (下降沿低电平即刻触发)
if ((key_sos_state & 0x07) == 0) {
key_sos_hold++;
if (key_sos_hold == 3) {
Event_Queue_Push(KEY_SOS_ACTIVE); // 触发本地主动报警
}
} else {
key_sos_hold = 0;
}
}
```
### 2.2 事件采集输入(射频数据解调)
射频数据接收线连在 `P2.1`。当发生跳变时触发 INT2 外部沿中断:
```c
sbit RF_RX_DATA = P2^1; // Pin 22
bit EV1527_Decode(u32 *out_addr, u8 *out_type) {
// 轮询或中断检测引脚 P2.1 沿变化
// 自适应同步低电平 T = low_time / 31
// 连续读取 24 位宽数据 (1:3 对应 03:1 对应 1)
// 解密出地址和数据码,返回结果给事件总线
// ...
return 1;
}
```
### 2.3 事件环形缓冲存储区
```c
#define EVENT_QUEUE_SIZE 4
KeyEvent idata event_queue[EVENT_QUEUE_SIZE];
u8 event_write_ptr = 0;
u8 event_read_ptr = 0;
u8 event_count = 0;
bit Event_Queue_Push(KeyEvent evt) {
if (event_count >= EVENT_QUEUE_SIZE) {
return 0; // 溢出丢弃
}
event_queue[event_write_ptr] = evt;
event_write_ptr = (event_write_ptr + 1) % EVENT_QUEUE_SIZE;
EA = 0;
event_count++;
EA = 1;
return 1;
}
KeyEvent Event_Queue_Pop(void) {
KeyEvent evt;
if (event_count == 0) {
return KEY_EVENT_NONE;
}
evt = event_queue[event_read_ptr];
event_read_ptr = (event_read_ptr + 1) % EVENT_QUEUE_SIZE;
EA = 0;
event_count--;
EA = 1;
return evt;
}
```
### 2.4 事件输出路由路由器 (Event Dispatcher)
在主循环 `while(1)` 内,系统以极速轮询该路由分发引擎:
```c
void Event_Dispatcher_Loop(void) {
KeyEvent evt = Event_Queue_Pop();
if (evt == KEY_EVENT_NONE) {
return; // 无事件
}
// 1. 本地最高优先级强占处理
if (evt == KEY_SOS_ACTIVE) {
StartApp(APP_SOS); // 物理强制唤醒并抢占前台
return;
}
// 2. 无线报警/配对包推送给后台守护进程
if (evt == RF_EVENT_ALARM || evt == RF_EVENT_PAIR) {
BgApp_Process_RF(evt); // 后台比对 Flash 决定是否启动 APP_ALARM 报警页
return;
}
// 3. 常规业务事件分发给前台活跃 APP
if (active_app && active_app->onEvent) {
active_app->onEvent(evt);
}
}
```