feat: 实现事件驱动应用框架,支持前台/后台分离、事件优先级和CPU占用控制
This commit is contained in:
467
App/main.c
467
App/main.c
@@ -1,6 +1,8 @@
|
||||
#include "stc32g.h"
|
||||
#include "intrins.h"
|
||||
#include "config.h"
|
||||
#include "event.h"
|
||||
#include "appmgr.h"
|
||||
#include "../Drivers/lcd.h"
|
||||
#include "../Drivers/rf.h"
|
||||
|
||||
@@ -739,7 +741,15 @@ void Timer1_Isr(void) interrupt 3
|
||||
current_hour = 0;
|
||||
}
|
||||
}
|
||||
clock_updated = 1; // 标记时钟更新,在主循环中更新屏幕
|
||||
// 通过事件队列通知时钟应用分钟变化
|
||||
{
|
||||
SystemEvent evt;
|
||||
evt.key_event = KEY_EVENT_NONE;
|
||||
evt.priority = EVENT_PRIORITY_LOW;
|
||||
evt.extra_data = ((u32)current_hour << 8) | current_min;
|
||||
evt.extra_size = 2;
|
||||
EventQueue_Push(evt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -966,19 +976,38 @@ void Timer1_Isr(void) interrupt 3
|
||||
}
|
||||
|
||||
/* =========================================================================
|
||||
* 系统主循环逻辑 (交互状态机与射频匹配核心)
|
||||
* 外部声明:应用注册函数
|
||||
* ========================================================================= */
|
||||
|
||||
extern void Apps_RegisterAll(void);
|
||||
|
||||
/* =========================================================================
|
||||
* 时钟更新回调:在定时器中断中触发,通知时钟应用重绘
|
||||
* ========================================================================= */
|
||||
|
||||
void ClockApp_NotifyUpdate(void)
|
||||
{
|
||||
// 通过事件队列通知时钟应用分钟变化
|
||||
SystemEvent evt;
|
||||
evt.key_event = KEY_EVENT_NONE;
|
||||
evt.priority = EVENT_PRIORITY_LOW;
|
||||
evt.extra_data = ((u32)current_hour << 8) | current_min;
|
||||
evt.extra_size = 2;
|
||||
EventQueue_Push(evt);
|
||||
}
|
||||
|
||||
/* =========================================================================
|
||||
* 系统主循环逻辑 (事件驱动框架核心)
|
||||
* ========================================================================= */
|
||||
|
||||
void main(void)
|
||||
{
|
||||
KeyEvent ev;
|
||||
u8 state_changed = 0; // 用 u8 代替 bit 变量
|
||||
u8 last_radar_sec = 99;
|
||||
SystemEvent evt;
|
||||
char cmd;
|
||||
u8 last_led_r = 1;
|
||||
u8 last_led_g = 1;
|
||||
u8 last_led_b = 1;
|
||||
u8 last_motor = 0;
|
||||
char cmd;
|
||||
|
||||
// 单片机时钟与看门狗基础初始化
|
||||
WTST = 0;
|
||||
@@ -1007,10 +1036,12 @@ void main(void)
|
||||
Load_Database();
|
||||
Timer1_Init();
|
||||
|
||||
// 默认进入 NORMAL 待机模式,显示时钟,并将射频调制芯片置为被动接收模式
|
||||
current_state = STATE_NORMAL;
|
||||
UI_ShowClockPage(current_state, current_hour, current_min);
|
||||
RF_SetMode(1); // 开接收天线
|
||||
// 初始化事件队列和应用管理器
|
||||
EventQueue_Init();
|
||||
Apps_RegisterAll();
|
||||
AppManager_Init();
|
||||
|
||||
Uart_SendString("[FRAMEWORK] Event-driven framework started\r\n");
|
||||
|
||||
while(1)
|
||||
{
|
||||
@@ -1018,76 +1049,96 @@ void main(void)
|
||||
cmd = Uart_RxChar();
|
||||
if (cmd != '\0')
|
||||
{
|
||||
SystemEvent sys_evt;
|
||||
sys_evt.priority = EVENT_PRIORITY_NORMAL;
|
||||
sys_evt.extra_data = 0;
|
||||
sys_evt.extra_size = 0;
|
||||
|
||||
if (cmd == 'u')
|
||||
{
|
||||
key_event_buf = KEY_EVENT_UP_CLICK;
|
||||
sys_evt.key_event = KEY_EVENT_UP_CLICK;
|
||||
EventQueue_Push(sys_evt);
|
||||
Uart_SendString("[UART SIM] KEY_UP Clicked\r\n");
|
||||
}
|
||||
else if (cmd == 'U')
|
||||
{
|
||||
key_event_buf = KEY_EVENT_UP_LONG;
|
||||
sys_evt.key_event = KEY_EVENT_UP_LONG;
|
||||
EventQueue_Push(sys_evt);
|
||||
Uart_SendString("[UART SIM] KEY_UP Long Pressed\r\n");
|
||||
}
|
||||
else if (cmd == 'd')
|
||||
{
|
||||
key_event_buf = KEY_EVENT_DOWN_CLICK;
|
||||
sys_evt.key_event = KEY_EVENT_DOWN_CLICK;
|
||||
EventQueue_Push(sys_evt);
|
||||
Uart_SendString("[UART SIM] KEY_DOWN Clicked\r\n");
|
||||
}
|
||||
else if (cmd == 'D')
|
||||
{
|
||||
key_event_buf = KEY_EVENT_DOWN_LONG;
|
||||
sys_evt.key_event = KEY_EVENT_DOWN_LONG;
|
||||
EventQueue_Push(sys_evt);
|
||||
Uart_SendString("[UART SIM] KEY_DOWN Long Pressed\r\n");
|
||||
}
|
||||
else if (cmd == 's')
|
||||
{
|
||||
key_event_buf = KEY_EVENT_SOS_CLICK;
|
||||
Uart_SendString("[UART SIM] KEY_SOS Clicked\r\n");
|
||||
sys_evt.key_event = KEY_EVENT_SOS_CLICK;
|
||||
sys_evt.priority = EVENT_PRIORITY_URGENT;
|
||||
EventQueue_EmergencyDispatch(sys_evt);
|
||||
Uart_SendString("[UART SIM] KEY_SOS Clicked (Emergency)\r\n");
|
||||
}
|
||||
else if (cmd == 'S')
|
||||
{
|
||||
key_event_buf = KEY_EVENT_SOS_LONG;
|
||||
Uart_SendString("[UART SIM] KEY_SOS Long Pressed\r\n");
|
||||
sys_evt.key_event = KEY_EVENT_SOS_LONG;
|
||||
sys_evt.priority = EVENT_PRIORITY_URGENT;
|
||||
EventQueue_EmergencyDispatch(sys_evt);
|
||||
Uart_SendString("[UART SIM] KEY_SOS Long Pressed (Emergency)\r\n");
|
||||
}
|
||||
else if (cmd == 'c' || cmd == 'C')
|
||||
{
|
||||
key_event_buf = KEY_EVENT_UP_DOWN_COMB;
|
||||
sys_evt.key_event = KEY_EVENT_UP_DOWN_COMB;
|
||||
EventQueue_Push(sys_evt);
|
||||
Uart_SendString("[UART SIM] KEY_UP + KEY_DOWN Combined\r\n");
|
||||
}
|
||||
else if (cmd == 'a' || cmd == 'A')
|
||||
{
|
||||
// 模拟报警事件
|
||||
u32 mock_addr = 0x123456;
|
||||
u8 mock_slot;
|
||||
if (!Check_Sensor_ID(mock_addr, &mock_slot))
|
||||
{
|
||||
Add_Sensor(mock_addr, 0); // 0: 门磁
|
||||
Add_Sensor(mock_addr, 0);
|
||||
}
|
||||
captured_addr = mock_addr;
|
||||
current_state = STATE_ALARM;
|
||||
state_changed = 1;
|
||||
alarm_sensor_slot = mock_slot;
|
||||
|
||||
sys_evt.key_event = KEY_EVENT_NONE;
|
||||
sys_evt.priority = EVENT_PRIORITY_HIGH;
|
||||
sys_evt.extra_data = mock_addr;
|
||||
sys_evt.extra_size = 4;
|
||||
EventQueue_Push(sys_evt);
|
||||
|
||||
AppManager_StartApp(APP_ID_ALARM);
|
||||
Uart_SendString("[UART SIM] Mock RF Alarm: ADDR 0x123456\r\n");
|
||||
}
|
||||
else if (cmd == 'p' || cmd == 'P')
|
||||
{
|
||||
if (current_state == STATE_PAIR_WAIT)
|
||||
{
|
||||
captured_addr = 0x789ABC;
|
||||
captured_type = menu_select;
|
||||
current_state = STATE_PAIR_CONFIRM;
|
||||
state_changed = 1;
|
||||
Uart_SendString("[UART SIM] Mock RF Pair Signal: ADDR 0x789ABC\r\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
Uart_SendString("[UART SIM] Ignore: Not in PAIR WAIT state\r\n");
|
||||
}
|
||||
// 模拟配对信号
|
||||
captured_addr = 0x789ABC;
|
||||
captured_type = 0;
|
||||
|
||||
sys_evt.key_event = KEY_EVENT_NONE;
|
||||
sys_evt.priority = EVENT_PRIORITY_NORMAL;
|
||||
sys_evt.extra_data = 0x789ABC;
|
||||
sys_evt.extra_size = 4;
|
||||
EventQueue_Push(sys_evt);
|
||||
|
||||
Uart_SendString("[UART SIM] Mock RF Pair Signal: ADDR 0x789ABC\r\n");
|
||||
}
|
||||
else if (cmd == 't' || cmd == 'T')
|
||||
{
|
||||
Uart_SendString("[UART SIM] SPI 3MHz Clock Test on P2.5 (SCLK) and P2.3 (MOSI) active. Press reset to exit.\r\n");
|
||||
// Configure SCLK (P2.5) and MOSI (P2.3) as push-pull output
|
||||
P2M1 &= ~((1 << 3) | (1 << 5));
|
||||
P2M0 |= ((1 << 3) | (1 << 5));
|
||||
SPCTL = 0xD0; // SPI Master, 6.0 MHz (SYSCLK / 4)
|
||||
SPCTL = 0xD0;
|
||||
while(1)
|
||||
{
|
||||
SPSTAT = 0xC0;
|
||||
@@ -1097,366 +1148,116 @@ void main(void)
|
||||
}
|
||||
else if (cmd == '1')
|
||||
{
|
||||
current_state = STATE_NORMAL;
|
||||
state_changed = 1;
|
||||
Uart_SendString("[UART SIM] Set State to: NORMAL (Standby)\r\n");
|
||||
AppManager_StartApp(APP_ID_CLOCK);
|
||||
Uart_SendString("[UART SIM] Set Active App to: Clock\r\n");
|
||||
}
|
||||
else if (cmd == '2')
|
||||
{
|
||||
current_state = STATE_ARMED;
|
||||
state_changed = 1;
|
||||
Uart_SendString("[UART SIM] Set State to: ARMED (Armed)\r\n");
|
||||
Uart_SendString("[UART SIM] Set State to: ARMED\r\n");
|
||||
}
|
||||
else if (cmd == '3')
|
||||
{
|
||||
current_state = STATE_DISARMED;
|
||||
state_changed = 1;
|
||||
Uart_SendString("[UART SIM] Set State to: DISARMED (Disarmed)\r\n");
|
||||
Uart_SendString("[UART SIM] Set State to: DISARMED\r\n");
|
||||
}
|
||||
else if (cmd == '4')
|
||||
{
|
||||
rgb_test_mode = 1;
|
||||
LED_R = 0; LED_G = 1; LED_B = 1; // 红色亮 (0代表亮)
|
||||
LED_R = 0; LED_G = 1; LED_B = 1;
|
||||
Uart_SendString("[UART SIM] RGB Test -> RED\r\n");
|
||||
}
|
||||
else if (cmd == '5')
|
||||
{
|
||||
rgb_test_mode = 1;
|
||||
LED_R = 1; LED_G = 0; LED_B = 1; // 绿色亮
|
||||
LED_R = 1; LED_G = 0; LED_B = 1;
|
||||
Uart_SendString("[UART SIM] RGB Test -> GREEN\r\n");
|
||||
}
|
||||
else if (cmd == '6')
|
||||
{
|
||||
rgb_test_mode = 1;
|
||||
LED_R = 1; LED_G = 1; LED_B = 0; // 蓝色亮
|
||||
LED_R = 1; LED_G = 1; LED_B = 0;
|
||||
Uart_SendString("[UART SIM] RGB Test -> BLUE\r\n");
|
||||
}
|
||||
else if (cmd == '7')
|
||||
{
|
||||
rgb_test_mode = 1;
|
||||
LED_R = 0; LED_G = 0; LED_B = 1; // 黄色亮 (红+绿)
|
||||
LED_R = 0; LED_G = 0; LED_B = 1;
|
||||
Uart_SendString("[UART SIM] RGB Test -> YELLOW\r\n");
|
||||
}
|
||||
else if (cmd == '8')
|
||||
{
|
||||
rgb_test_mode = 1;
|
||||
LED_R = 0; LED_G = 1; LED_B = 0; // 紫色亮 (红+蓝)
|
||||
LED_R = 0; LED_G = 1; LED_B = 0;
|
||||
Uart_SendString("[UART SIM] RGB Test -> PURPLE\r\n");
|
||||
}
|
||||
else if (cmd == '9')
|
||||
{
|
||||
rgb_test_mode = 1;
|
||||
LED_R = 1; LED_G = 0; LED_B = 0; // 青色亮 (绿+蓝)
|
||||
LED_R = 1; LED_G = 0; LED_B = 0;
|
||||
Uart_SendString("[UART SIM] RGB Test -> CYAN\r\n");
|
||||
}
|
||||
else if (cmd == '0')
|
||||
{
|
||||
rgb_test_mode = 1;
|
||||
LED_R = 0; LED_G = 0; LED_B = 0; // 白色亮 (红+绿+蓝)
|
||||
LED_R = 0; LED_G = 0; LED_B = 0;
|
||||
Uart_SendString("[UART SIM] RGB Test -> WHITE\r\n");
|
||||
}
|
||||
else if (cmd == 'f' || cmd == 'F')
|
||||
{
|
||||
rgb_test_mode = 0;
|
||||
LED_R = 1; LED_G = 1; LED_B = 1; // 熄灭
|
||||
Uart_SendString("[UART SIM] RGB Test -> OFF (Normal Mode)\r\n");
|
||||
LED_R = 1; LED_G = 1; LED_B = 1;
|
||||
Uart_SendString("[UART SIM] RGB Test -> OFF\r\n");
|
||||
}
|
||||
}
|
||||
|
||||
// 1. 读取按键事件并自动清空
|
||||
ev = key_event_buf;
|
||||
key_event_buf = KEY_EVENT_NONE;
|
||||
|
||||
if (ev != KEY_EVENT_NONE)
|
||||
// 1. 处理按键事件缓冲区(来自定时器中断)
|
||||
if (key_event_buf != KEY_EVENT_NONE)
|
||||
{
|
||||
rgb_test_mode = 0; // 任何物理/按键事件触发时退出 RGB 测试模式
|
||||
// 通过串口打印获取到的按键事件代号进行测试联调
|
||||
Uart_SendString("Key Event Captured: ");
|
||||
Uart_SendHex8((u8)ev);
|
||||
Uart_SendString("\r\n");
|
||||
|
||||
// 根据不同的系统当前状态,执行状态迁移逻辑
|
||||
if (current_state == STATE_NORMAL || current_state == STATE_ARMED || current_state == STATE_DISARMED)
|
||||
{
|
||||
if (ev == KEY_EVENT_UP_DOWN_COMB) // 同时长按 UP + DOWN 3 秒进入配对菜单
|
||||
{
|
||||
current_state = STATE_PAIR_MENU;
|
||||
menu_select = 0;
|
||||
state_changed = 1;
|
||||
}
|
||||
else if (ev == KEY_EVENT_SOS_CLICK) // 短按 SOS 发射 SOS 报警
|
||||
{
|
||||
current_state = STATE_SOS_EMITTED;
|
||||
state_changed = 1;
|
||||
}
|
||||
else if (ev == KEY_EVENT_SOS_LONG) // 长按 SOS 5 秒与 IPC 绑定
|
||||
{
|
||||
UI_ShowBindingPage();
|
||||
RF_SetMode(2); // TX mode
|
||||
EV1527_Transmit(CLONED_ADDR, 0x01); // 对码绑定电报数据为 0x01
|
||||
RF_SetMode(0); // Idle
|
||||
|
||||
Delay_ms(2000); // 维持 2 秒
|
||||
current_state = STATE_NORMAL;
|
||||
state_changed = 1;
|
||||
}
|
||||
}
|
||||
else if (current_state == STATE_PAIR_MENU)
|
||||
{
|
||||
if (ev == KEY_EVENT_UP_CLICK) // 菜单选择上移
|
||||
{
|
||||
if (menu_select > 0)
|
||||
{
|
||||
menu_select--;
|
||||
state_changed = 1;
|
||||
}
|
||||
}
|
||||
else if (ev == KEY_EVENT_DOWN_CLICK) // 菜单选择下移
|
||||
{
|
||||
if (menu_select < 4)
|
||||
{
|
||||
menu_select++;
|
||||
state_changed = 1;
|
||||
}
|
||||
}
|
||||
else if (ev == KEY_EVENT_SOS_CLICK) // 单击 SOS 确认选项,进入对码搜索并触发 100ms 短振与白灯快闪
|
||||
{
|
||||
MOTOR = 1;
|
||||
Delay_ms(100);
|
||||
MOTOR = 0;
|
||||
|
||||
current_state = STATE_PAIR_WAIT;
|
||||
pair_timeout_ms = 0; // 重置对码超时计时器
|
||||
state_changed = 1;
|
||||
}
|
||||
else if (ev == KEY_EVENT_DOWN_LONG) // 长按 DOWN 键 3 秒强行返回待机
|
||||
{
|
||||
current_state = STATE_NORMAL;
|
||||
state_changed = 1;
|
||||
}
|
||||
}
|
||||
else if (current_state == STATE_PAIR_WAIT)
|
||||
{
|
||||
if (ev == KEY_EVENT_DOWN_LONG) // 在雷达页面,长按 DOWN 3秒强行退出
|
||||
{
|
||||
current_state = STATE_NORMAL;
|
||||
state_changed = 1;
|
||||
}
|
||||
}
|
||||
else if (current_state == STATE_PAIR_CONFIRM)
|
||||
{
|
||||
if (ev == KEY_EVENT_SOS_LONG) // 在确认页面,长按 SOS 3 秒保存对码结果
|
||||
{
|
||||
Add_Sensor(captured_addr, captured_type);
|
||||
current_state = STATE_PAIR_SUCCESS;
|
||||
state_changed = 1;
|
||||
}
|
||||
else if (ev == KEY_EVENT_DOWN_LONG) // 在确认页面,长按 DOWN 3 秒放弃保存返回待机
|
||||
{
|
||||
current_state = STATE_NORMAL;
|
||||
state_changed = 1;
|
||||
}
|
||||
}
|
||||
else if (current_state == STATE_ALARM)
|
||||
{
|
||||
// 在防区报警闪烁状态下,短按任意物理按键均可清除报警声光
|
||||
current_state = STATE_NORMAL;
|
||||
state_changed = 1;
|
||||
}
|
||||
else if (current_state == STATE_SOS_EMITTED)
|
||||
{
|
||||
// 再次长按任意物理按键即可主动解除求救模式
|
||||
if (ev == KEY_EVENT_SOS_LONG || ev == KEY_EVENT_UP_LONG || ev == KEY_EVENT_DOWN_LONG)
|
||||
{
|
||||
current_state = STATE_NORMAL;
|
||||
state_changed = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 2. 对码雷达扫描 30 秒超时自动跳回时钟主界面检测
|
||||
if (current_state == STATE_PAIR_WAIT && pair_timeout_ms >= 30000UL)
|
||||
{
|
||||
pair_timeout_ms = 0;
|
||||
UI_ShowPairFailPage(1); // 调用 Fail 绘制接口并传入超时标志 1
|
||||
Delay_ms(2500); // 维持 2.5 秒超时警告
|
||||
current_state = STATE_NORMAL;
|
||||
state_changed = 1;
|
||||
}
|
||||
|
||||
// 3. 状态切换的屏幕重写渲染 (只有发生状态改变才清屏,杜绝频闪)
|
||||
if (state_changed)
|
||||
{
|
||||
state_changed = 0; // 仅在此处清除状态改变标记,确保异步状态转移时屏幕能被正确重绘
|
||||
rgb_test_mode = 0;
|
||||
|
||||
// 通过串口反馈状态机重绘过程
|
||||
Uart_SendString("State Transition to: ");
|
||||
Uart_SendHex8((u8)current_state);
|
||||
Uart_SendString("\r\n");
|
||||
|
||||
if (current_state == STATE_NORMAL || current_state == STATE_ARMED || current_state == STATE_DISARMED)
|
||||
SystemEvent sys_evt;
|
||||
sys_evt.key_event = key_event_buf;
|
||||
sys_evt.extra_data = 0;
|
||||
sys_evt.extra_size = 0;
|
||||
|
||||
// 设置事件优先级
|
||||
if (key_event_buf == KEY_EVENT_SOS_CLICK ||
|
||||
key_event_buf == KEY_EVENT_SOS_LONG)
|
||||
{
|
||||
RF_SetMode(1); // 切回接收模式监听防区
|
||||
UI_ShowClockPage(current_state, current_hour, current_min);
|
||||
}
|
||||
else if (current_state == STATE_PAIR_MENU)
|
||||
{
|
||||
RF_SetMode(0); // 关闭射频节省能量
|
||||
UI_ShowPairMenuPage(menu_select);
|
||||
}
|
||||
else if (current_state == STATE_PAIR_WAIT)
|
||||
{
|
||||
RF_SetMode(1); // 开启射频解调芯片,开始抓包
|
||||
LCD_Clear(COLOR_BLACK);
|
||||
LCD_ShowStringCentered(135, "RECHERCHE...", COLOR_WHITE, COLOR_BLACK);
|
||||
LCD_ShowStringCentered(160, "DECLENCH. CAPT", COLOR_CYAN, COLOR_BLACK);
|
||||
UI_ShowPairWaitPage(0);
|
||||
last_radar_sec = 99; // 强行重置雷达波纹帧计数器
|
||||
}
|
||||
else if (current_state == STATE_PAIR_CONFIRM)
|
||||
{
|
||||
RF_SetMode(0); // 捕获成功,关闭射频
|
||||
UI_ShowPairConfirmPage(captured_addr);
|
||||
}
|
||||
else if (current_state == STATE_PAIR_SUCCESS)
|
||||
{
|
||||
RF_SetMode(0);
|
||||
UI_ShowPairSuccessPage(captured_addr);
|
||||
|
||||
// 触发对码成功物理反馈:强振 1 次 (400ms),LED 绿色常亮 2 秒
|
||||
MOTOR = 1;
|
||||
LED_G = 0; // 开启绿灯
|
||||
LED_R = 1;
|
||||
LED_B = 1;
|
||||
Delay_ms(400); // 振动 400ms
|
||||
MOTOR = 0; // 停止振动
|
||||
|
||||
Delay_ms(1600); // 维持绿灯常亮累计满 2 秒 (400 + 1600 = 2000ms)
|
||||
LED_G = 1; // 熄灭绿灯
|
||||
|
||||
Delay_ms(500); // 补齐页面显示总时间 2.5 秒 (2000 + 500 = 2500ms)
|
||||
current_state = STATE_NORMAL;
|
||||
UI_ShowClockPage(current_state, current_hour, current_min);
|
||||
RF_SetMode(1);
|
||||
}
|
||||
else if (current_state == STATE_ALARM)
|
||||
{
|
||||
u8 slot;
|
||||
static char alarm_name[24];
|
||||
char *name = "UNKNOWN SENSOR";
|
||||
if (Check_Sensor_ID(captured_addr, &slot))
|
||||
{
|
||||
Format_Sensor_Name(slot, alarm_name);
|
||||
name = alarm_name;
|
||||
alarm_sensor_slot = slot;
|
||||
}
|
||||
UI_ShowAlarmPage(name, 1);
|
||||
}
|
||||
else if (current_state == STATE_SOS_EMITTED)
|
||||
{
|
||||
UI_ShowSosPage();
|
||||
}
|
||||
}
|
||||
|
||||
// 4. 定期局部刷新、动画更新与射频解调轮询
|
||||
if (current_state == STATE_NORMAL || current_state == STATE_ARMED || current_state == STATE_DISARMED)
|
||||
{
|
||||
// 时钟分钟数字局部刷新 (防闪烁)
|
||||
if (clock_updated)
|
||||
{
|
||||
clock_updated = 0;
|
||||
UI_ShowClockPage(current_state, current_hour, current_min);
|
||||
}
|
||||
|
||||
// 监听并解析防区发射的信号码
|
||||
{
|
||||
u32 rx_addr;
|
||||
u8 rx_data;
|
||||
if (EV1527_Decode(&rx_addr, &rx_data))
|
||||
{
|
||||
u8 slot;
|
||||
if (Check_Sensor_ID(rx_addr, &slot)) // 检查接收 of 地址是否在配对列表中
|
||||
{
|
||||
u32 slot_addr = ((u32)sensor_list[slot].addr[0] << 16) |
|
||||
((u32)sensor_list[slot].addr[1] << 8) |
|
||||
sensor_list[slot].addr[2];
|
||||
u8 sensor_type = slot_addr & 0x0F;
|
||||
if (sensor_type < 5) // 仅触发普通防区传感器,彻底过滤并排除SOS信号接收
|
||||
{
|
||||
u8 zone = default_zones[sensor_type];
|
||||
// 24小时防区 (zone==0) 任何时候都触发,普通防区 (zone==1) 仅在 ARMED 状态下触发
|
||||
if (zone == 0 || current_state == STATE_ARMED)
|
||||
{
|
||||
captured_addr = rx_addr;
|
||||
current_state = STATE_ALARM;
|
||||
state_changed = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (current_state == STATE_PAIR_WAIT)
|
||||
{
|
||||
// 雷达搜索页面每 250ms 局部刷新一帧雷达天线波纹
|
||||
u8 frame = (u8)((ms_tick / 250) % 3);
|
||||
if (frame != last_radar_sec)
|
||||
{
|
||||
last_radar_sec = frame;
|
||||
UI_ShowPairWaitPage(frame);
|
||||
}
|
||||
|
||||
// 在对码搜索状态下监听任意 EV1527 无线电码
|
||||
{
|
||||
u32 rx_addr;
|
||||
u8 rx_data;
|
||||
if (EV1527_Decode(&rx_addr, &rx_data))
|
||||
{
|
||||
captured_addr = rx_addr;
|
||||
captured_type = menu_select;
|
||||
current_state = STATE_PAIR_CONFIRM; // 捕获到信号,移至确认页
|
||||
state_changed = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (current_state == STATE_SOS_EMITTED)
|
||||
{
|
||||
// 主动 SOS 求救状态下,每 500ms 通过 LT4455 发射一次射频求救帧
|
||||
u8 sec_phase = (u8)((ms_tick / 500) % 2);
|
||||
if (sec_phase != last_radar_sec)
|
||||
{
|
||||
last_radar_sec = sec_phase;
|
||||
RF_SetMode(2); // 射频置为发射端模式
|
||||
EV1527_Transmit(CLONED_ADDR, 0x08); // 发射手环自带地址 CLONED_ADDR 且数据为 0x08
|
||||
RF_SetMode(0); // 发射完成复位,关闭发射机
|
||||
}
|
||||
|
||||
// 双实线红色警告边框的闪烁效果
|
||||
if (alarm_flash_flag)
|
||||
{
|
||||
LCD_DrawRectBorder(4, 4, 112, 232, COLOR_RED);
|
||||
LCD_DrawRectBorder(8, 8, 104, 224, COLOR_WHITE);
|
||||
sys_evt.priority = EVENT_PRIORITY_URGENT;
|
||||
// 紧急事件直接分发,跳过队列
|
||||
EventQueue_EmergencyDispatch(sys_evt);
|
||||
}
|
||||
else
|
||||
{
|
||||
LCD_DrawRectBorder(4, 4, 112, 232, COLOR_BLACK);
|
||||
LCD_DrawRectBorder(8, 8, 104, 224, COLOR_BLACK);
|
||||
sys_evt.priority = EVENT_PRIORITY_NORMAL;
|
||||
EventQueue_Push(sys_evt);
|
||||
}
|
||||
|
||||
key_event_buf = KEY_EVENT_NONE;
|
||||
}
|
||||
else if (current_state == STATE_ALARM)
|
||||
|
||||
// 2. 处理事件队列中的事件
|
||||
while (!EventQueue_IsEmpty())
|
||||
{
|
||||
// 警报闪烁状态下,交替绘制红色和黑色边框
|
||||
if (alarm_flash_flag)
|
||||
evt = EventQueue_Pop();
|
||||
if (evt.key_event != KEY_EVENT_NONE || evt.priority != EVENT_PRIORITY_LOW)
|
||||
{
|
||||
LCD_DrawRectBorder(4, 4, 112, 232, COLOR_RED);
|
||||
}
|
||||
else
|
||||
{
|
||||
LCD_DrawRectBorder(4, 4, 112, 232, COLOR_BLACK);
|
||||
Uart_SendString("[EVENT] Processing event: ");
|
||||
Uart_SendHex8((u8)evt.key_event);
|
||||
Uart_SendString(" Priority: ");
|
||||
Uart_SendHex8((u8)evt.priority);
|
||||
Uart_SendString("\r\n");
|
||||
|
||||
AppManager_DispatchEvent(evt);
|
||||
}
|
||||
}
|
||||
|
||||
// 仿真 LED/马达状态串口输出
|
||||
// 3. 运行当前活跃应用的 onRun 回调(带CPU占用控制)
|
||||
AppManager_RunActiveApp();
|
||||
|
||||
// 4. 仿真 LED/马达状态串口输出
|
||||
if (LED_R != last_led_r || LED_G != last_led_g || LED_B != last_led_b)
|
||||
{
|
||||
last_led_r = LED_R;
|
||||
|
||||
Reference in New Issue
Block a user