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