fix: 彻底解开 SOS 求救按键状态机被注释的屏蔽,使按键正常产生求救事件并分发

This commit is contained in:
2026-07-29 10:09:19 +08:00
parent 48db6523fb
commit a766ada53d

View File

@@ -6,17 +6,17 @@
#include "xtell.h" #include "xtell.h"
#include "../Drivers/adc.h" #include "../Drivers/adc.h"
// 定义事件形队列的大深度为 8 // 定义事件<EFBFBD><EFBFBD>形队列的<EFBFBD><EFBFBD>大深度为 8
#define EVENT_QUEUE_DEPTH 8 #define EVENT_QUEUE_DEPTH 8
// 形队列存储数 (存放在单片机 xdata 拓展 RAM区中) // <EFBFBD><EFBFBD>形队列存储数<EFBFBD><EFBFBD> (存放在单片机 xdata 拓展 RAM区中)
static SystemEvent xdata event_queue[EVENT_QUEUE_DEPTH]; static SystemEvent xdata event_queue[EVENT_QUEUE_DEPTH];
static u8 queue_head = 0; // 队首读指针 static u8 queue_head = 0; // 队<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
static u8 queue_tail = 0; // 队尾写指 static u8 queue_tail = 0; // 队尾写指<EFBFBD><EFBFBD>
static u8 queue_count = 0; // 当前队列内有效事件 static u8 queue_count = 0; // 当前队列内有效事件<EFBFBD><EFBFBD>
/** /**
* @brief 初化/清空事件队列 * @brief 初<EFBFBD><EFBFBD>化/清空事件队列
*/ */
void EventQueue_Init(void) void EventQueue_Init(void)
{ {
@@ -26,62 +26,63 @@ void EventQueue_Init(void)
} }
/** /**
* @brief 将普通事件压入队 * @brief 将普通事件压入队<EFBFBD><EFBFBD>
* @param evt 输入的系统事 * @param evt 输入的系统事<EFBFBD><EFBFBD>
* @return bit 1-成功0-失败 * @return bit 1-成功<EFBFBD><EFBFBD>0-失败
*/ */
bit EventQueue_Push(SystemEvent evt) bit EventQueue_Push(SystemEvent evt)
{ {
if (queue_count >= EVENT_QUEUE_DEPTH) return 0; // 队列满,丢弃事件 if (queue_count >= EVENT_QUEUE_DEPTH) return 0; // 队列满,丢弃事件
EA = 0; // 关闭全局中断,保护临界区操作的原子 EA = 0; // 关闭全局<EFBFBD><EFBFBD><EFBFBD><EFBFBD>,保护临界区操作的原子<EFBFBD>
event_queue[queue_tail] = evt; // 存入队尾 event_queue[queue_tail] = evt; // 存入队尾
queue_tail = (queue_tail + 1) % EVENT_QUEUE_DEPTH; // 尾指针向后移动,回环 queue_tail = (queue_tail + 1) % EVENT_QUEUE_DEPTH; // 尾指针向后移<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
queue_count++; // 有效计数 1 queue_count++; // 有效计数<EFBFBD><EFBFBD> 1
EA = 1; // 恢复全局中断 EA = 1; // 恢<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
return 1; return 1;
} }
/** /**
* @brief 将高优先级/紧急事件强行插到队 * @brief 将高优先<EFBFBD><EFBFBD>/紧<><E7B4A7>事件强行插到队<EFBFBD><EFBFBD>
* @param evt 输入的系统事 * @param evt 输入的系统事<EFBFBD><EFBFBD>
* @return bit 1-成功0-失败 * @return bit 1-成功<EFBFBD><EFBFBD>0-失败
*/ */
bit EventQueue_InsertFront(SystemEvent evt) bit EventQueue_InsertFront(SystemEvent evt)
{ {
if (queue_count >= EVENT_QUEUE_DEPTH) return 0; // 队列满,插队失败 if (queue_count >= EVENT_QUEUE_DEPTH) return 0; // 队列满,插队失败
EA = 0; // 屏蔽中断 EA = 0; // 屏蔽<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// 头指针向前移动一位(带回防溢出) // 头指针向前移动一位(带回<EFBFBD><EFBFBD>防溢出)
queue_head = (queue_head - 1 + EVENT_QUEUE_DEPTH) % EVENT_QUEUE_DEPTH; queue_head = (queue_head - 1 + EVENT_QUEUE_DEPTH) % EVENT_QUEUE_DEPTH;
event_queue[queue_head] = evt; // 存入腾出的队首位 event_queue[queue_head] = evt; // 存入腾出的队首位<EFBFBD><EFBFBD>
queue_count++; // 计数 1 queue_count++; // 计数<EFBFBD><EFBFBD> 1
EA = 1; // 恢复中断 EA = 1; // 恢<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
return 1; return 1;
} }
/** /**
* @brief 从队首弹出一缓冲事件 * @brief 从队首弹出一<EFBFBD><EFBFBD>缓冲事件
* @return SystemEvent 返回弹出的事件若空返回空闲事 * @return SystemEvent 返回弹出的事件<EFBFBD><EFBFBD>若空返回空闲事<EFBFBD><EFBFBD>
*/ */
SystemEvent EventQueue_Pop(void) SystemEvent EventQueue_Pop(void)
{ {
SystemEvent evt; SystemEvent evt;
// 默空事件属 // 默<EFBFBD><EFBFBD>空事件属<EFBFBD>
evt.key_event = KEY_EVENT_NONE; evt.key_event = KEY_EVENT_NONE;
evt.priority = EVENT_PRIORITY_NORMAL;
evt.extra_data = 0; evt.extra_data = 0;
evt.extra_size = 0; evt.extra_size = 0;
if (queue_count == 0) return evt; // 队空,直接返回空闲事 if (queue_count == 0) return evt; // 队空,直接返回空闲事<EFBFBD><EFBFBD>
EA = 0; // 屏蔽中断 EA = 0; // 屏蔽<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
evt = event_queue[queue_head]; // 读取队首数据 evt = event_queue[queue_head]; // 读取队<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
queue_head = (queue_head + 1) % EVENT_QUEUE_DEPTH; // 头指针向后移动,回环 queue_head = (queue_head + 1) % EVENT_QUEUE_DEPTH; // 头指针向后移<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
queue_count--; // 有效计数 1 queue_count--; // 有效计数<EFBFBD><EFBFBD> 1
EA = 1; // 恢复中断 EA = 1; // 恢<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
return evt; return evt;
} }
/** /**
* @brief 判断队列是否为空 * @brief 判断队列<EFBFBD><EFBFBD>否为<EFBFBD><EFBFBD>
*/ */
bit EventQueue_IsEmpty(void) bit EventQueue_IsEmpty(void)
{ {
@@ -89,7 +90,7 @@ bit EventQueue_IsEmpty(void)
} }
/** /**
* @brief 判断队列是否已满 * @brief 判断队列<EFBFBD><EFBFBD>否已<EFBFBD><EFBFBD>
*/ */
bit EventQueue_IsFull(void) bit EventQueue_IsFull(void)
{ {
@@ -97,7 +98,7 @@ bit EventQueue_IsFull(void)
} }
/** /**
* @brief 获取当前队列的事件 * @brief 获取当前队列<EFBFBD><EFBFBD>的事件<EFBFBD><EFBFBD>
*/ */
u8 EventQueue_GetCount(void) u8 EventQueue_GetCount(void)
{ {
@@ -105,98 +106,98 @@ u8 EventQueue_GetCount(void)
} }
/** /**
* @brief 事件分发器核心轮询 * @brief 事件分发器核心轮询<EFBFBD><EFBFBD>
* @details 逐一处理队列的事件,并根系统当前的运行模式进行拦截、跳转或下发派发 * @details 逐一处理队列<EFBFBD><EFBFBD>的事件,并根<EFBFBD><EFBFBD>系统当前的运行模式进行拦<EFBFBD><EFBFBD>、跳<EFBFBD><EFBFBD>或下发派发<EFBFBD>
*/ */
void Event_Dispatcher_Loop(void) void Event_Dispatcher_Loop(void)
{ {
SystemEvent evt = EventQueue_Pop(); // 弹出一个事件 SystemEvent evt = EventQueue_Pop(); // 弹出<EFBFBD><EFBFBD><EFBFBD><EFBFBD>事件
// 如果无事发生的空事件,直接退出 // 如果<EFBFBD><EFBFBD>无事发生的空事件,直接<EFBFBD><EFBFBD><EFBFBD>
if (evt.key_event == KEY_EVENT_NONE && evt.extra_size == 0) { if (evt.key_event == KEY_EVENT_NONE && evt.extra_size == 0) {
return; return;
} }
inactivity_timer = 0; // 捕获到有效事件,清零休眠计时器,重置闲置超时 inactivity_timer = 0; // 捕获到有效事件,清零休眠计时<EFBFBD><EFBFBD><EFBFBD><EFBFBD>闲置超时
// 串口打印调试信息 // 串口打印调试信息
XTELL_LOG("[EVENT] key="); XTELL_LOG("[EVENT] key=");
XTELL_LOG_HEX8((u8)evt.key_event); XTELL_LOG_HEX8((u8)evt.key_event);
XTELL_LOG("\r\n"); XTELL_LOG("\r\n");
// SOS 按键紧急处理:若当前前台不为 SOS 应用,接收到 SOS 动作,立即强行切入到 SOS_APP 并执行求 // SOS 按键紧<EFBFBD><EFBFBD><EFBFBD><EFBFBD>理:若当前前台不为 SOS 应用,接收到 SOS <EFBFBD><EFBFBD>动作,立即强行切入到 SOS_APP 并执行求<EFBFBD><EFBFBD>
if ((evt.key_event == KEY_EVENT_SOS_CLICK || evt.key_event == KEY_EVENT_SOS_LONG) && if ((evt.key_event == KEY_EVENT_SOS_CLICK || evt.key_event == KEY_EVENT_SOS_LONG) &&
AppManager_GetActiveAppID() != APP_ID_SOS) { AppManager_GetActiveAppID() != APP_ID_SOS) {
AppManager_StartApp(APP_ID_SOS); AppManager_StartApp(APP_ID_SOS);
return; return;
} }
// 关机事件处理:捕获到长按关机指令,直接调 Power_Off 关断电源 // 关机事件处理:捕获到长按关机指令,直接调<EFBFBD><EFBFBD> Power_Off 关断电源
if (evt.key_event == KEY_EVENT_POWER_OFF) { if (evt.key_event == KEY_EVENT_POWER_OFF) {
Power_Off(); Power_Off();
return; return;
} }
// 常事件(如普通的按键点击)直接传分发给当前于前台活跃的应 // 常<EFBFBD><EFBFBD>事件(如普通的按键点击)直接<EFBFBD><EFBFBD>传分发给当前<EFBFBD><EFBFBD>于前台活跃的应<EFBFBD><EFBFBD>
AppManager_DispatchEvent(evt); AppManager_DispatchEvent(evt);
} }
/** /**
* @brief 定时 1 初始化,设定 1ms 中断周期 * @brief 定时<EFBFBD><EFBFBD> 1 初<EFBFBD><EFBFBD><EFBFBD><EFBFBD>定 1ms <EFBFBD><EFBFBD><EFBFBD><EFBFBD>周期
*/ */
void Timer1_Init(void) void Timer1_Init(void)
{ {
AUXR |= 0x40; // 设定定时 1 1T 模式 (无分频,主直接输) AUXR |= 0x40; // 设定定时<EFBFBD><EFBFBD> 1 <EFBFBD><EFBFBD> 1T 模式 (无分频,主<EFBFBD><EFBFBD>直接输<EFBFBD><EFBFBD>)
TMOD &= 0x0F; // 设置定时 1 模式寄存,保留低四位 (定时0配置) TMOD &= 0x0F; // 设置定时<EFBFBD><EFBFBD> 1 模式寄存<EFBFBD><EFBFBD>,保留低四位 (定时<EFBFBD><EFBFBD>0配置)
{ {
// 按照系统主 (MAIN_Fosc) 计算 1ms 对应的重装载 // 按照系统主<EFBFBD> (MAIN_Fosc) 计算 1ms 对应的重装载<EFBFBD><EFBFBD>
u16 reload = (u16)(65536UL - (MAIN_Fosc / 1000UL)); u16 reload = (u16)(65536UL - (MAIN_Fosc / 1000UL));
TL1 = (u8)reload; // 载入 8 TL1 = (u8)reload; // 载入<EFBFBD><EFBFBD> 8 <EFBFBD><EFBFBD>
TH1 = (u8)(reload >> 8);// 载入 8 TH1 = (u8)(reload >> 8);// 载入<EFBFBD><EFBFBD> 8 <EFBFBD><EFBFBD>
} }
ET1 = 1; // 开启定时器 1 中断允许 ET1 = 1; // <EFBFBD><EFBFBD><EFBFBD><EFBFBD>定时<EFBFBD><EFBFBD> 1 <20><><EFBFBD><EFBFBD><EFBFBD>
TR1 = 1; // 动定时器 1 计数 TR1 = 1; // <EFBFBD><EFBFBD>动定时器 1 计数
EA = 1; // 开启全局中断允许 EA = 1; // <EFBFBD><EFBFBD><EFBFBD><EFBFBD>全局<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
} }
// 全局按键描触发标 // 全局按键<EFBFBD><EFBFBD>描触发标<EFBFBD><EFBFBD>
volatile bit key_scan_flag = 0; volatile bit key_scan_flag = 0;
/** /**
* @brief 定时 1 中断服务程序 ( 1ms 触发一次) * @brief 定时<EFBFBD><EFBFBD> 1 <EFBFBD><EFBFBD><EFBFBD><EFBFBD>服务程序 (<EFBFBD><EFBFBD> 1ms 触发<EFBFBD><EFBFBD><EFBFBD><EFBFBD>)
* @details 承担系统时钟计算,并 10ms 置位主循环按键扫描标志,不直接在中断中进行 ADC 多采样 * @details 承担系统<EFBFBD><EFBFBD>时钟计算,并<EFBFBD><EFBFBD> 10ms <EFBFBD><EFBFBD>位主<EFBFBD><EFBFBD><EFBFBD><EFBFBD>按键<EFBFBD><EFBFBD>描标志不直接在<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ADC 多<EFBFBD><EFBFBD>采样<EFBFBD>
*/ */
void Timer1_Isr(void) interrupt 3 void Timer1_Isr(void) interrupt 3
{ {
// 1ms 定时更新时钟 // 1ms 定时更新<EFBFBD><EFBFBD>时钟
Clock_IncMS(); Clock_IncMS();
// 报屏幕红边以 100ms 周期亮灭,进行色爆闪指示 // 报<EFBFBD><EFBFBD>屏幕红边<EFBFBD><EFBFBD>以 100ms 周期<EFBFBD><EFBFBD><EFBFBD><EFBFBD>,进行<EFBFBD><EFBFBD>色爆闪指示
alarm_flash_flag = (ms_tick / 100) % 2; alarm_flash_flag = (ms_tick / 100) % 2;
/* 物理按键定时计数 ( 10ms 位一次标志位) */ /* 物理按键定时计数 (<EFBFBD><EFBFBD> 10ms <EFBFBD><EFBFBD>位一次标志位) */
key_scan_timer++; key_scan_timer++;
if (key_scan_timer >= 10) { if (key_scan_timer >= 10) {
key_scan_timer = 0; // 重置描分频计数器 key_scan_timer = 0; // 重置<EFBFBD><EFBFBD>描分频<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
key_scan_flag = 1; // 仅在中断里置起标志位,留待主循环中执行实际读取与消 key_scan_flag = 1; // 仅在<EFBFBD><EFBFBD><EFBFBD><EFBFBD>里置起标志位,留待主<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>实际<EFBFBD><EFBFBD>取与消<EFBFBD><EFBFBD>
} }
} }
/** /**
* @brief 主循环按键扫描与消抖处理函数 * @brief 主循<EFBFBD><EFBFBD>按键<EFBFBD><EFBFBD>描与消抖处理函数
* @details 由主循环每 10ms 查并执,完全在主线程中运行,绝无中断重入冲突 * @details 由主<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 10ms <EFBFBD><EFBFBD>查并执<EFBFBD><EFBFBD>,完全在主线程<EFBFBD><EFBFBD><EFBFBD><EFBFBD>绝无<EFBFBD><EFBFBD><EFBFBD><EFBFBD>重入冲突<EFBFBD><EFBFBD>
*/ */
void Event_KeyScan_Poll(void) void Event_KeyScan_Poll(void)
{ {
SystemEvent evt; SystemEvent evt;
// 读取按键的电平信 (KEY_UP, KEY_CONFIRM 为低电平有效) // 读取按键的电平信<EFBFBD><EFBFBD> (KEY_UP, KEY_CONFIRM 为低电平有效)
u8 raw_up = !KEY_UP; u8 raw_up = !KEY_UP;
u8 raw_down = ADC_IsKeyDown(); // KEY_DOWN 通过 P0.3 ADC 通道判定 (常 2.0V, 按下 3.7V) u8 raw_down = ADC_IsKeyDown(); // KEY_DOWN 通过 P0.3 ADC 通道判定 (常<EFBFBD> 2.0V, 按下 3.7V)
u8 raw_confirm = !KEY_CONFIRM; u8 raw_confirm = !KEY_CONFIRM;
u8 raw_sos = !KEY_SOS; // 恢 SOS 物理按键电平检测 u8 raw_sos = !KEY_SOS; // 恢<EFBFBD> SOS 物理按键电平<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
key_scan_timer = 0; // 重置描分频计数器 key_scan_timer = 0; // 重置<EFBFBD><EFBFBD>描分频<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// 【SOS 按键电平实时诊断 // 【SOS 按键电平实时诊断<EFBFBD><EFBFBD>
{ {
static u8 last_raw_sos = 99; static u8 last_raw_sos = 99;
if (raw_sos != last_raw_sos) { if (raw_sos != last_raw_sos) {
@@ -209,7 +210,7 @@ void Event_KeyScan_Poll(void)
} }
} }
// 按键调试诊断:若按键 ADC 值有变化或于高电平,串口输出真实 ADC // 按键调试诊断:若按键 ADC 值有变化或<EFBFBD><EFBFBD>于高电平,串口输出真实 ADC <EFBFBD><EFBFBD>
{ {
u16 down_val = ADC_ReadFiltered(ADC_CHANNEL_KEY_DOWN); u16 down_val = ADC_ReadFiltered(ADC_CHANNEL_KEY_DOWN);
if (down_val > 2800) { if (down_val > 2800) {
@@ -222,34 +223,35 @@ void Event_KeyScan_Poll(void)
} }
} }
// 测到有任意按处于下压状,立即将无操作闲置休眠计时器归 // <EFBFBD><EFBFBD>测到有任意按<EFBFBD><EFBFBD>处于下压状<EFBFBD><EFBFBD>,立即将无操作闲置休眠计时器归<EFBFBD><EFBFBD>
if (raw_up || raw_down || raw_confirm || raw_sos) { if (raw_up || raw_down || raw_confirm || raw_sos) {
inactivity_timer = 0; inactivity_timer = 0;
} else { } else {
// 如果在常态下(非休眠、非报警、非紧急求救),累加闲时间 // 如果在常态下(非休眠、非报<EFBFBD><EFBFBD><EFBFBD><EFBFBD>非紧<EFBFBD><EFBFBD>求救),累加闲<EFBFBD><EFBFBD>时间
if (current_state != STATE_SLEEP && current_state != STATE_ALARM && current_state != STATE_SOS_EMITTED) { if (current_state != STATE_SLEEP && current_state != STATE_ALARM && current_state != STATE_SOS_EMITTED) {
inactivity_timer++; inactivity_timer++;
} }
} }
// 默将派发事件重置为空 // 默<EFBFBD><EFBFBD>将派发事件重置为空
evt.key_event = KEY_EVENT_NONE; evt.key_event = KEY_EVENT_NONE;
evt.priority = EVENT_PRIORITY_NORMAL;
evt.extra_data = 0; evt.extra_data = 0;
evt.extra_size = 0; evt.extra_size = 0;
// 双键组合判定:▲ and ▼ 键同时按下的消抖与生成 // 双键组合判定:▲ <EFBFBD><EFBFBD> and <EFBFBD><EFBFBD> <20><>同时按下的消抖与生成
if (raw_up && raw_down) { if (raw_up && raw_down) {
comb_hold++; comb_hold++;
if (comb_hold == 300) { // 持续按下 3 (300 * 10ms = 3s) if (comb_hold == 300) { // 持续按下<EFBFBD><EFBFBD> 3 <EFBFBD><EFBFBD> (300 * 10ms = 3s)
evt.key_event = KEY_EVENT_UP_DOWN_COMB; evt.key_event = KEY_EVENT_UP_DOWN_COMB;
EventQueue_Push(evt); // 压入队列 EventQueue_Push(evt); // 压入队列
} }
key_up_hold = 0; // 清零单个按键计数,防止双击事件干 key_up_hold = 0; // 清零单个按键计数,防止双击事件干<EFBFBD><EFBFBD>
key_down_hold = 0; key_down_hold = 0;
} else { } else {
comb_hold = 0; // 组合松开归零 comb_hold = 0; // 组合<EFBFBD><EFBFBD>松开归零
// (KEY_UP) 按键状 // <EFBFBD><EFBFBD> (KEY_UP) 按键状<EFBFBD><EFBFBD>
if (raw_up) { if (raw_up) {
key_up_hold++; key_up_hold++;
if (key_up_hold == 300) { // 达到 3 秒判定为长按 if (key_up_hold == 300) { // 达到 3 秒判定为长按
@@ -257,7 +259,7 @@ void Event_KeyScan_Poll(void)
EventQueue_Push(evt); EventQueue_Push(evt);
} }
} else { } else {
// 如果松开时按下数在消抖阈值20ms至长按阈3s之间则判定为一次短按 // 如果松开时按下<EFBFBD><EFBFBD>数在消抖阈值20ms至长按阈<EFBFBD><EFBFBD>3s之间则判定为<EFBFBD><EFBFBD>次短<EFBFBD><EFBFBD>
if (key_up_hold >= 2 && key_up_hold < 300) { if (key_up_hold >= 2 && key_up_hold < 300) {
evt.key_event = KEY_EVENT_UP_CLICK; evt.key_event = KEY_EVENT_UP_CLICK;
EventQueue_Push(evt); EventQueue_Push(evt);
@@ -265,15 +267,15 @@ void Event_KeyScan_Poll(void)
key_up_hold = 0; // 释放归零 key_up_hold = 0; // 释放归零
} }
// (KEY_DOWN / 关机) 按键状 // <EFBFBD><EFBFBD> (KEY_DOWN / <EFBFBD><EFBFBD>关机) 按键状<EFBFBD><EFBFBD>
if (raw_down) { if (raw_down) {
key_down_hold++; key_down_hold++;
if (key_down_hold == 100) { // 长按 1 (100 * 10ms = 1000ms = 1s) 触发关机事件 if (key_down_hold == 100) { // 长按 1 <EFBFBD><EFBFBD> (100 * 10ms = 1000ms = 1s) 触发关机事件
evt.key_event = KEY_EVENT_POWER_OFF; evt.key_event = KEY_EVENT_POWER_OFF;
EventQueue_Push(evt); EventQueue_Push(evt);
} }
} else { } else {
// 如果松开时按下时长在 20ms 1s 之间,触发短按下/选择事件 // 如果松开时按下时长在 20ms <EFBFBD><EFBFBD> 1s 之间,触发短按下<EFBFBD><EFBFBD>/选择事件
if (key_down_hold >= 2 && key_down_hold < 100) { if (key_down_hold >= 2 && key_down_hold < 100) {
evt.key_event = KEY_EVENT_DOWN_CLICK; evt.key_event = KEY_EVENT_DOWN_CLICK;
EventQueue_Push(evt); EventQueue_Push(evt);
@@ -281,10 +283,10 @@ void Event_KeyScan_Poll(void)
key_down_hold = 0; // 释放归零 key_down_hold = 0; // 释放归零
} }
// (KEY_CONFIRM) 确认按键状态 // <EFBFBD><EFBFBD> (KEY_CONFIRM) <EFBFBD><EFBFBD>认按<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
if (raw_confirm) { if (raw_confirm) {
key_confirm_hold++; key_confirm_hold++;
if (key_confirm_hold == 300) { // 长按 3 秒打开主菜单 if (key_confirm_hold == 300) { // 长按 3 秒打<EFBFBD><EFBFBD>主菜<EFBFBD><EFBFBD>
evt.key_event = KEY_EVENT_CONFIRM_LONG; evt.key_event = KEY_EVENT_CONFIRM_LONG;
EventQueue_Push(evt); EventQueue_Push(evt);
} }
@@ -296,21 +298,23 @@ void Event_KeyScan_Poll(void)
key_confirm_hold = 0; // 释放归零 key_confirm_hold = 0; // 释放归零
} }
/* // SOS <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȱ<EFBFBD><C8B0><EFBFBD>״̬<D7B4><CCAC> (<28>ѽ<EFBFBD><D1BD><EFBFBD>)
// SOS 物理求救按键状态机
if (raw_sos) { if (raw_sos) {
key_sos_hold++; key_sos_hold++;
if (key_sos_hold == 300) { // 长按 3 秒,发出求救,插入队首 if (key_sos_hold == 300) { // <20><><EFBFBD><EFBFBD> 3 <20><EFBFBD><EBA3AC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȣ<EFBFBD><C8A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
evt.key_event = KEY_EVENT_SOS_LONG; evt.key_event = KEY_EVENT_SOS_LONG;
evt.priority = EVENT_PRIORITY_URGENT;
EventQueue_InsertFront(evt); EventQueue_InsertFront(evt);
Uart_SendString("[KEY-DIAG] SOS Long Press Dispatched!\r\n");
} }
} else { } else {
if (key_sos_hold >= 2 && key_sos_hold < 300) { // 短按即呼救,插入队首 if (key_sos_hold >= 2 && key_sos_hold < 300) { // <20>̰<EFBFBD><CCB0><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȣ<EFBFBD><C8A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
evt.key_event = KEY_EVENT_SOS_CLICK; evt.key_event = KEY_EVENT_SOS_CLICK;
evt.priority = EVENT_PRIORITY_URGENT;
EventQueue_InsertFront(evt); EventQueue_InsertFront(evt);
Uart_SendString("[KEY-DIAG] SOS Click Dispatched!\r\n");
}
key_sos_hold = 0; // <20>ͷŹ<CDB7><C5B9><EFBFBD>
} }
key_sos_hold = 0; // 释放归零
}
*/
} }
} }