2026-07-15 15:57:37 +08:00
|
|
|
|
#include "config.h"
|
2026-07-15 16:14:30 +08:00
|
|
|
|
#include "rgb.h"
|
|
|
|
|
|
#include "event.h"
|
|
|
|
|
|
#include "app_manager.h"
|
|
|
|
|
|
#include "database.h"
|
|
|
|
|
|
#include "ui.h"
|
|
|
|
|
|
#include "system.h"
|
2026-07-15 15:57:37 +08:00
|
|
|
|
#include "../Drivers/rf.h"
|
2026-07-15 16:14:30 +08:00
|
|
|
|
#include "../Drivers/lcd.h"
|
2026-07-15 15:57:37 +08:00
|
|
|
|
|
|
|
|
|
|
/* =========================================================================
|
2026-07-15 16:14:30 +08:00
|
|
|
|
* 系统全局变量定义
|
2026-07-15 15:57:37 +08:00
|
|
|
|
* ========================================================================= */
|
2026-07-30 13:46:44 +08:00
|
|
|
|
SystemState current_state = STATE_NORMAL; // 系统整体的当前运行状态,默<EFBC8C><E9BB98>为正常时钟待机<E5BE85><E69CBA>
|
2026-07-16 17:52:52 +08:00
|
|
|
|
|
2026-07-17 19:43:02 +08:00
|
|
|
|
|
2026-07-30 13:46:44 +08:00
|
|
|
|
u8 menu_select = 0; // 主菜单当前<E5BD93><E5898D>中的<E4B8AD><E79A84>高<EFBFBD><E9AB98>索引 (0~2)
|
|
|
|
|
|
u32 captured_addr = 0; // 配<><E9858D>或报<E68896><E68AA5>时,捕获到的传感器 24 <20><> EV1527 射<><E5B084>物理地<E79086><E59CB0>
|
|
|
|
|
|
u8 captured_type = 0; // 正在对码或触发<E8A7A6><E58F91>报的传感器设<E599A8><E8AEBE>类<EFBFBD><E7B1BB> (0:门<>, 1:PIR...)
|
|
|
|
|
|
u8 alarm_sensor_slot = 0; // 触发警报的传感器<E6849F><E599A8> sensor_list 数组<E695B0><E7BB84>的索引槽位号
|
2026-07-16 17:52:52 +08:00
|
|
|
|
|
2026-07-30 13:46:44 +08:00
|
|
|
|
// 传感器存储列表数<E8A1A8><E695B0>库,位于单片机<E78987><E69CBA>部 XDATA 存储空间,<E997B4><EFBC8C>共 16 <20><>槽位
|
2026-07-15 15:57:37 +08:00
|
|
|
|
Sensor_Slot xdata sensor_list[16];
|
|
|
|
|
|
|
2026-07-30 13:46:44 +08:00
|
|
|
|
// 全局滴答与定时中<E697B6><E4B8AD>计数变量,位<EFBC8C><E4BD8D> volatile 防<><E998B2><EFBFBD>编译器优<E599A8><E4BC98>
|
|
|
|
|
|
volatile u16 ms_tick = 0; // 定时<E5AE9A><E697B6><EFBFBD><EFBFBD> 1ms 基准滴答<E6BBB4><E7AD94>加器
|
|
|
|
|
|
volatile u16 inactivity_timer = 0; // 用户闲置计时<E8AEA1><E697B6>,用于无操作判定(单<EFBC88><E58D95>: 10ms<6D><73>
|
|
|
|
|
|
volatile u32 pair_timeout_ms = 0; // 传感器配对<E9858D><E5AFB9>码超时<E8B685><E697B6>秒<EFBFBD><E7A792>时<EFBFBD><E697B6> (上限 30000ms <20><> 30s)
|
|
|
|
|
|
volatile u16 alarm_timer_ms = 0; // 入侵报<E4BEB5><E68AA5>马达震动时序<E697B6><E5BA8F>数<EFBFBD><E695B0>
|
|
|
|
|
|
volatile u16 motor_timer_ms = 0; // <20><>立马达震动时长<E697B6><E995BF>数<EFBFBD><E695B0>
|
|
|
|
|
|
volatile bit alarm_flash_flag = 0; // 报<><E68AA5>时红<E697B6><E7BAA2>周期<E591A8><E69C9F>闪烁亮<E78381><E4BAAE>标志<E6A087><E5BF97>
|
|
|
|
|
|
|
|
|
|
|
|
// 物理按键<E68C89><E994AE>描与消抖长按计数<E8AEA1><E695B0> (10ms <20><>描一<E68F8F><E4B880>)
|
|
|
|
|
|
volatile u16 key_scan_timer = 0; // 10ms <20><>描周期分频器
|
|
|
|
|
|
volatile u16 key_up_hold = 0; // <20><> (KEY_UP) 按下时长<E697B6><E995BF><EFBFBD><EFBFBD>
|
|
|
|
|
|
volatile u16 key_down_hold = 0; // <20><> (KEY_DOWN) 按下时长<E697B6><E995BF><EFBFBD><EFBFBD>
|
|
|
|
|
|
volatile u16 key_confirm_hold = 0; // <20><> (KEY_CONFIRM) 按下时长<E697B6><E995BF><EFBFBD><EFBFBD>
|
|
|
|
|
|
volatile u16 key_sos_hold = 0; // SOS 按下时长<E697B6><E995BF><EFBFBD><EFBFBD>
|
|
|
|
|
|
volatile u16 comb_hold = 0; // <20><> + <20><> 组合<E7BB84><E59088>按下时长<E697B6><E995BF><EFBFBD><EFBFBD>
|
2026-07-15 15:57:37 +08:00
|
|
|
|
|
|
|
|
|
|
/* =========================================================================
|
2026-07-30 13:46:44 +08:00
|
|
|
|
* 串口调试指令解析与事件派发封<EFBFBD><EFBFBD>
|
2026-07-15 16:14:30 +08:00
|
|
|
|
* ========================================================================= */
|
2026-07-16 17:52:52 +08:00
|
|
|
|
/**
|
2026-07-30 13:46:44 +08:00
|
|
|
|
* @brief 解析通过串口 1 发<EFBFBD><EFBFBD>来的键盘及测试模拟指令
|
|
|
|
|
|
* @param cmd 接收到的 ASCII 字<EFBFBD><EFBFBD>命<EFBFBD><EFBFBD>
|
|
|
|
|
|
* @details 负责将字符指令转化<EFBFBD><EFBFBD>应的系统按<EFBFBD><EFBFBD>或射频事件,并推入事件队列以测试<EFBFBD><EFBFBD>件架构:
|
|
|
|
|
|
* - 'u'/'U': 模拟<EFBFBD><EFBFBD><EFBFBD><EFBFBD>/长按 <EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
|
* - 'd'/'D': 模拟<EFBFBD><EFBFBD><EFBFBD><EFBFBD>/长按 <EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
|
* - 's'/'S': 模拟<EFBFBD><EFBFBD><EFBFBD><EFBFBD>/长按 SOS 物理<EFBFBD><EFBFBD>(优先插入队首)<EFBFBD><EFBFBD>
|
|
|
|
|
|
* - 'c'/'C': 模拟组合<EFBFBD><EFBFBD>触发<EFBFBD><EFBFBD>
|
|
|
|
|
|
* - 'a'/'A': 模拟无线传感器入侵触发<EFBFBD><EFBFBD>报信号,地<EFBFBD><EFBFBD>固定<EFBFBD><EFBFBD> 0x123456,zone=1<EFBFBD><EFBFBD>
|
|
|
|
|
|
* - 'p'/'P': 模拟对码期间捕获<EFBFBD><EFBFBD> 24 位无线<EFBFBD><EFBFBD>码信号,地<EFBFBD><EFBFBD>固定<EFBFBD><EFBFBD> 0x789ABC<EFBFBD><EFBFBD>
|
|
|
|
|
|
* - '1'/'2'/'3': 模拟系统的<EFBFBD><EFBFBD>常、已布防、已撤防状<EFBFBD><EFBFBD>切<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
|
* - 'z'/'Z': 模拟超时,强行使闲置计数器置 6000,触发自动深度休眠<EFBFBD>
|
|
|
|
|
|
* - 't'/'T': 触发屏幕与无线控制引脚测试<EFBFBD>
|
|
|
|
|
|
*/
|
|
|
|
|
|
/**
|
|
|
|
|
|
* @brief <EFBFBD><EFBFBD><EFBFBD>ڵ<EFBFBD><EFBFBD><EFBFBD>ר<EFBFBD><EFBFBD><EFBFBD><EFBFBD>RGB <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɫͨ<EFBFBD><EFBFBD><EFBFBD>Ų<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
|
* @details <EFBFBD><EFBFBD><EFBFBD>η<EFBFBD><EFBFBD>ʹ<EFBFBD><EFBFBD>졢<EFBFBD><EFBFBD><EFBFBD>̡<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ÿ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD> 2 <EFBFBD>룬<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>У<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɫӳ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϵ
|
2026-07-16 17:52:52 +08:00
|
|
|
|
*/
|
2026-07-30 13:46:44 +08:00
|
|
|
|
void RGB_Diagnostic_Test(void)
|
|
|
|
|
|
{
|
|
|
|
|
|
Uart_SendString("\r\n=== RGB LED Color Channel Test Starting ===\r\n");
|
|
|
|
|
|
|
|
|
|
|
|
// 1. <20><><EFBFBD>Է<EFBFBD><D4B7>ͺ<EFBFBD>ɫ<EFBFBD><C9AB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (G=0, R=150, B=0)
|
|
|
|
|
|
Uart_SendString("[RGB-TEST] 1. Sending RED command -> G=0, R=150, B=0\r\n");
|
|
|
|
|
|
RGB_Send(0, 150, 0, 0, 150, 0);
|
|
|
|
|
|
Delay_ms(2000);
|
|
|
|
|
|
|
|
|
|
|
|
// Ϩ<><CFA8>
|
|
|
|
|
|
RGB_Send(0, 0, 0, 0, 0, 0);
|
|
|
|
|
|
Delay_ms(300);
|
|
|
|
|
|
|
|
|
|
|
|
// 2. <20><><EFBFBD>Է<EFBFBD><D4B7><EFBFBD><EFBFBD><EFBFBD>ɫ<EFBFBD><C9AB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (G=150, R=0, B=0)
|
|
|
|
|
|
Uart_SendString("[RGB-TEST] 2. Sending GREEN command -> G=150, R=0, B=0\r\n");
|
|
|
|
|
|
RGB_Send(150, 0, 0, 150, 0, 0);
|
|
|
|
|
|
Delay_ms(2000);
|
|
|
|
|
|
|
|
|
|
|
|
// Ϩ<><CFA8>
|
|
|
|
|
|
RGB_Send(0, 0, 0, 0, 0, 0);
|
|
|
|
|
|
Delay_ms(300);
|
|
|
|
|
|
|
|
|
|
|
|
// 3. <20><><EFBFBD>Է<EFBFBD><D4B7><EFBFBD><EFBFBD><EFBFBD>ɫ<EFBFBD><C9AB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (G=0, R=0, B=150)
|
|
|
|
|
|
Uart_SendString("[RGB-TEST] 3. Sending BLUE command -> G=0, R=0, B=150\r\n");
|
|
|
|
|
|
RGB_Send(0, 0, 150, 0, 0, 150);
|
|
|
|
|
|
Delay_ms(2000);
|
|
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD>Ϩ<EFBFBD><CFA8>
|
|
|
|
|
|
RGB_Send(0, 0, 0, 0, 0, 0);
|
|
|
|
|
|
Uart_SendString("=== RGB LED Color Channel Test Ended ===\r\n");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-07-15 16:14:30 +08:00
|
|
|
|
void Debug_ProcessCommand(char cmd)
|
|
|
|
|
|
{
|
|
|
|
|
|
SystemEvent debug_evt;
|
2026-07-30 13:46:44 +08:00
|
|
|
|
inactivity_timer = 0; // 收到指令,立即重<E58DB3><E9878D>用户的无操作闲置计时<E8AEA1><E697B6>
|
2026-07-15 16:14:30 +08:00
|
|
|
|
debug_evt.extra_data = 0;
|
|
|
|
|
|
debug_evt.extra_size = 0;
|
|
|
|
|
|
|
|
|
|
|
|
if (cmd == 'u') {
|
|
|
|
|
|
debug_evt.key_event = KEY_EVENT_UP_CLICK;
|
2026-07-17 19:43:02 +08:00
|
|
|
|
debug_evt.priority = EVENT_PRIORITY_NORMAL;
|
2026-07-16 17:52:52 +08:00
|
|
|
|
EventQueue_Push(debug_evt); // 压入队尾
|
2026-07-17 19:43:02 +08:00
|
|
|
|
Uart_SendString("[UART] KEY_UP Clicked\r\n");
|
2026-07-15 16:14:30 +08:00
|
|
|
|
} else if (cmd == 'U') {
|
|
|
|
|
|
debug_evt.key_event = KEY_EVENT_UP_LONG;
|
2026-07-17 19:43:02 +08:00
|
|
|
|
debug_evt.priority = EVENT_PRIORITY_NORMAL;
|
2026-07-15 16:14:30 +08:00
|
|
|
|
EventQueue_Push(debug_evt);
|
2026-07-17 19:43:02 +08:00
|
|
|
|
Uart_SendString("[UART] KEY_UP Long Pressed\r\n");
|
2026-07-15 16:14:30 +08:00
|
|
|
|
} else if (cmd == 'd') {
|
|
|
|
|
|
debug_evt.key_event = KEY_EVENT_DOWN_CLICK;
|
2026-07-17 19:43:02 +08:00
|
|
|
|
debug_evt.priority = EVENT_PRIORITY_NORMAL;
|
2026-07-15 16:14:30 +08:00
|
|
|
|
EventQueue_Push(debug_evt);
|
2026-07-17 19:43:02 +08:00
|
|
|
|
Uart_SendString("[UART] KEY_DOWN Clicked\r\n");
|
2026-07-15 16:14:30 +08:00
|
|
|
|
} else if (cmd == 'D') {
|
|
|
|
|
|
debug_evt.key_event = KEY_EVENT_DOWN_LONG;
|
2026-07-17 19:43:02 +08:00
|
|
|
|
debug_evt.priority = EVENT_PRIORITY_NORMAL;
|
2026-07-15 16:14:30 +08:00
|
|
|
|
EventQueue_Push(debug_evt);
|
2026-07-17 19:43:02 +08:00
|
|
|
|
Uart_SendString("[UART] KEY_DOWN Long Pressed\r\n");
|
2026-07-15 16:14:30 +08:00
|
|
|
|
} else if (cmd == 's') {
|
|
|
|
|
|
debug_evt.key_event = KEY_EVENT_SOS_CLICK;
|
2026-07-17 19:43:02 +08:00
|
|
|
|
debug_evt.priority = EVENT_PRIORITY_URGENT;
|
2026-07-30 13:46:44 +08:00
|
|
|
|
EventQueue_InsertFront(debug_evt); // 紧<><E7B4A7>事件插入队<E585A5><E9989F>
|
2026-07-17 19:43:02 +08:00
|
|
|
|
Uart_SendString("[UART] KEY_SOS Clicked\r\n");
|
2026-07-15 16:14:30 +08:00
|
|
|
|
} else if (cmd == 'S') {
|
|
|
|
|
|
debug_evt.key_event = KEY_EVENT_SOS_LONG;
|
2026-07-17 19:43:02 +08:00
|
|
|
|
debug_evt.priority = EVENT_PRIORITY_URGENT;
|
2026-07-15 16:14:30 +08:00
|
|
|
|
EventQueue_InsertFront(debug_evt);
|
2026-07-17 19:43:02 +08:00
|
|
|
|
Uart_SendString("[UART] KEY_SOS Long Pressed\r\n");
|
2026-07-15 16:14:30 +08:00
|
|
|
|
} else if (cmd == 'c' || cmd == 'C') {
|
|
|
|
|
|
debug_evt.key_event = KEY_EVENT_UP_DOWN_COMB;
|
2026-07-17 19:43:02 +08:00
|
|
|
|
debug_evt.priority = EVENT_PRIORITY_NORMAL;
|
2026-07-15 16:14:30 +08:00
|
|
|
|
EventQueue_Push(debug_evt);
|
2026-07-17 19:43:02 +08:00
|
|
|
|
Uart_SendString("[UART] KEY_UP+DOWN Combined\r\n");
|
2026-07-15 16:14:30 +08:00
|
|
|
|
} else if (cmd == 'a' || cmd == 'A') {
|
2026-07-16 17:52:52 +08:00
|
|
|
|
u32 mock_addr = 0x123456; // 设定模拟的报警射频源地址
|
2026-07-15 16:14:30 +08:00
|
|
|
|
u8 mock_slot;
|
2026-07-30 13:46:44 +08:00
|
|
|
|
// 如果<E5A682><E69E9C>地数<E59CB0><E695B0>库中没有匹配该射频,则强制登记进 1 号防<E58FB7><E998B2>
|
2026-07-15 16:14:30 +08:00
|
|
|
|
if (!Check_Sensor_ID(mock_addr, &mock_slot)) {
|
|
|
|
|
|
Add_Sensor_With_Zone(mock_addr, 0, 1);
|
|
|
|
|
|
}
|
2026-07-17 19:43:02 +08:00
|
|
|
|
debug_evt.key_event = KEY_EVENT_NONE;
|
2026-07-30 13:46:44 +08:00
|
|
|
|
debug_evt.priority = EVENT_PRIORITY_HIGH; // 入侵报<E4BEB5><E68AA5><EFBFBD><EFBFBD>为 HIGH 优先<E4BC98><E58588>
|
2026-07-17 19:43:02 +08:00
|
|
|
|
debug_evt.extra_data = mock_addr;
|
|
|
|
|
|
debug_evt.extra_size = 4;
|
|
|
|
|
|
EventQueue_InsertFront(debug_evt); // 高优先级插队
|
|
|
|
|
|
Uart_SendString("[UART] Mock RF Alarm\r\n");
|
2026-07-15 16:14:30 +08:00
|
|
|
|
} else if (cmd == 'p' || cmd == 'P') {
|
2026-07-30 13:46:44 +08:00
|
|
|
|
// <20><>有当手环切入 Pair 模式时,模拟对码信号才有<E6898D><E69C89>
|
2026-07-17 19:43:02 +08:00
|
|
|
|
if (AppManager_GetActiveAppID() == APP_ID_PAIR) {
|
|
|
|
|
|
debug_evt.key_event = KEY_EVENT_NONE;
|
|
|
|
|
|
debug_evt.priority = EVENT_PRIORITY_NORMAL;
|
2026-07-30 13:46:44 +08:00
|
|
|
|
debug_evt.extra_data = 0x789ABC; // 设定模拟对码<E5AFB9><E7A081>件地<E4BBB6><E59CB0>
|
2026-07-17 19:43:02 +08:00
|
|
|
|
debug_evt.extra_size = 4;
|
|
|
|
|
|
EventQueue_Push(debug_evt);
|
|
|
|
|
|
Uart_SendString("[UART] Mock RF Pair Signal\r\n");
|
|
|
|
|
|
} else {
|
|
|
|
|
|
Uart_SendString("[UART] Not in PAIR mode\r\n");
|
|
|
|
|
|
}
|
2026-07-15 16:14:30 +08:00
|
|
|
|
} else if (cmd == '1') {
|
2026-07-30 13:46:44 +08:00
|
|
|
|
// 模拟切换<E58887><E68DA2> 正常撤防 (NORMAL) 状<><E78AB6>并刷新时钟
|
2026-07-15 16:14:30 +08:00
|
|
|
|
if (AppManager_GetActiveAppID() == APP_ID_CLOCK) {
|
2026-07-15 15:57:37 +08:00
|
|
|
|
current_state = STATE_NORMAL;
|
|
|
|
|
|
UI_ShowClockPage(current_state, current_hour, current_min);
|
|
|
|
|
|
}
|
2026-07-17 19:43:02 +08:00
|
|
|
|
Uart_SendString("[UART] State: NORMAL\r\n");
|
2026-07-15 16:14:30 +08:00
|
|
|
|
} else if (cmd == '2') {
|
2026-07-30 13:46:44 +08:00
|
|
|
|
// 模拟切换<E58887><E68DA2> 已布<E5B7B2><E5B883> (ARMED) 状<><E78AB6>,<EFBFBD><EFBC8C>通门磁可触发警报
|
2026-07-15 16:14:30 +08:00
|
|
|
|
if (AppManager_GetActiveAppID() == APP_ID_CLOCK) {
|
2026-07-15 15:57:37 +08:00
|
|
|
|
current_state = STATE_ARMED;
|
2026-07-15 16:14:30 +08:00
|
|
|
|
UI_ShowClockPage(current_state, current_hour, current_min);
|
2026-07-15 15:57:37 +08:00
|
|
|
|
}
|
2026-07-17 19:43:02 +08:00
|
|
|
|
Uart_SendString("[UART] State: ARMED\r\n");
|
2026-07-15 16:14:30 +08:00
|
|
|
|
} else if (cmd == '3') {
|
2026-07-30 13:46:44 +08:00
|
|
|
|
// 模拟切换<E58887><E68DA2> 已撤<E5B7B2><E692A4> (DISARMED) 状<><E78AB6>,忽略<E5BFBD><E795A5>通报<E9809A><E68AA5>
|
2026-07-15 16:14:30 +08:00
|
|
|
|
if (AppManager_GetActiveAppID() == APP_ID_CLOCK) {
|
|
|
|
|
|
current_state = STATE_DISARMED;
|
|
|
|
|
|
UI_ShowClockPage(current_state, current_hour, current_min);
|
2026-07-15 15:57:37 +08:00
|
|
|
|
}
|
2026-07-17 19:43:02 +08:00
|
|
|
|
Uart_SendString("[UART] State: DISARMED\r\n");
|
2026-07-15 16:14:30 +08:00
|
|
|
|
} else if (cmd == 'z' || cmd == 'Z') {
|
2026-07-30 13:46:44 +08:00
|
|
|
|
inactivity_timer = 6000; // 模拟闲置 60 秒超时,强制触发主循<E4B8BB><E5BEAA>深度休眠
|
2026-07-17 19:43:02 +08:00
|
|
|
|
Uart_SendString("[UART] Force Entering Sleep mode!\r\n");
|
2026-07-30 13:46:44 +08:00
|
|
|
|
} else if (cmd == 'q' || cmd == 'Q') {
|
|
|
|
|
|
RGB_Diagnostic_Test(); // <20><><EFBFBD><EFBFBD> RGB <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɫͨ<C9AB><CDA8><EFBFBD>Ų<EFBFBD><C5B2><EFBFBD><EFBFBD><EFBFBD>
|
2026-07-16 17:52:52 +08:00
|
|
|
|
} else if (cmd == 't' || cmd == 'T') {
|
2026-07-30 13:46:44 +08:00
|
|
|
|
RF_DiagnosticMode('t'); // 触发射<E58F91><E5B084>连<EFBFBD><E8BF9E>发射诊断 (绿色爆闪)
|
2026-07-17 19:43:02 +08:00
|
|
|
|
} else if (cmd == 'r' || cmd == 'R') {
|
2026-07-30 13:46:44 +08:00
|
|
|
|
RF_DiagnosticMode('r'); // 触发 5 秒射频接收监<E694B6><E79B91>诊断
|
2026-07-29 10:16:05 +08:00
|
|
|
|
} else if (cmd == 'l' || cmd == 'L') {
|
2026-07-30 13:46:44 +08:00
|
|
|
|
Loopback_Test(); // 触发物理电气回环测试 (<28><><EFBFBD><EFBFBD> P2.1 <20><> P3.6 <20><><EFBFBD><EFBFBD>)
|
2026-07-15 15:57:37 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* =========================================================================
|
2026-07-30 13:46:44 +08:00
|
|
|
|
* 主函<EFBFBD><EFBFBD> (入口)
|
2026-07-15 15:57:37 +08:00
|
|
|
|
* ========================================================================= */
|
|
|
|
|
|
void main(void)
|
|
|
|
|
|
{
|
|
|
|
|
|
char cmd;
|
|
|
|
|
|
|
2026-07-30 13:46:44 +08:00
|
|
|
|
// ====== STC32G 特殊功能寄存器内核基<E6A0B8><E59FBA>初<EFBFBD><E5889D>化 ======
|
|
|
|
|
|
WTST = 0; // 设置程序 Flash 访问等待时间<E697B6><E997B4> 0 (<28><>高<EFBFBD><E9AB98>运<EFBFBD><E8BF90>)
|
|
|
|
|
|
EAXFR = 1; // 允<><E58581><EFBFBD><EFBFBD>问扩展特殊功能寄存<E5AF84><E5AD98> (XSFR)
|
|
|
|
|
|
CKCON = 0; // 外部总线时钟设定为最<E4B8BA><E69C80>
|
2026-07-16 17:52:52 +08:00
|
|
|
|
WDT_CONTR = 0x00; // 关闭看门狗定时器
|
|
|
|
|
|
|
2026-07-30 13:46:44 +08:00
|
|
|
|
// ====== <20><>件各模块基<E59D97>初<EFBFBD><E5889D>化 ======
|
|
|
|
|
|
GPIO_Init(); // 配置各个引脚的推挽输<E68CBD><E8BE93>/准双向模式及内部上拉 (锁存 PWR_HOLD=1)
|
|
|
|
|
|
RGB_Send(0, 0, 0, 0, 0, 0); // 【<><E38090><EFBFBD><EFBFBD>修正<E4BFAE><E6ADA3>:上电<E4B88A><E794B5><EFBFBD><EFBFBD>时间强制发<E588B6> 0 码关<E7A081><E585B3><EFBFBD><EFBFBD>条,熄灭上电暂<E794B5><E69A82>引起的随机白光<E799BD><E58589>
|
|
|
|
|
|
RF_Init(); // 初<><E5889D>化射<E58C96><E5B084>芯片各引脚控制
|
|
|
|
|
|
Delay_ms(500); // <20><><EFBFBD><EFBFBD>动延时,等待供电电<E794B5><E794B5>稳<EFBFBD><E7A8B3>
|
|
|
|
|
|
LCD_Init(); // 初<><E5889D>化 LHS114TC-IF03 (ST7789V) 屏幕控制寄存器序列并<E58897><E5B9B6><EFBFBD><EFBFBD>背光
|
|
|
|
|
|
Uart1_Init(); // 初<><E5889D>化串口 1 波特<E6B3A2><E789B9> 115200 供调试日<E8AF95><E697A5>
|
2026-07-17 19:43:02 +08:00
|
|
|
|
Uart_SendString("Wristband System Initialized!\r\n");
|
2026-07-16 17:52:52 +08:00
|
|
|
|
|
2026-07-30 13:46:44 +08:00
|
|
|
|
Self_Test(); // 执<><E689A7>上电硬件自<E4BBB6><E887AA> (PWR_HOLD锁存、P0.3 ADC按键常<E994AE><E5B8B8><EFBFBD><EFBFBD>P1.3 电池电量)
|
|
|
|
|
|
Load_Database(); // <20><> IAP Flash <20><> 254 扇区读取<E8AFBB><E58F96>有已绑定的传感器数据<E695B0><E68DAE> RAM
|
2026-07-15 15:57:37 +08:00
|
|
|
|
|
2026-07-30 13:46:44 +08:00
|
|
|
|
/* 步<> 1: 初<><E5889D>化事件<E4BA8B><E4BBB6>形缓冲区队列 */
|
2026-07-15 15:57:37 +08:00
|
|
|
|
EventQueue_Init();
|
|
|
|
|
|
|
2026-07-30 13:46:44 +08:00
|
|
|
|
/* 步<> 2+5: 初<><E5889D>化应用管理器并登<E5B9B6><E799BB>所有前台应<E58FB0><E5BA94>,默认加<E8AEA4><E58AA0> ClockApp */
|
2026-07-15 15:57:37 +08:00
|
|
|
|
AppManager_Init();
|
|
|
|
|
|
|
2026-07-30 13:46:44 +08:00
|
|
|
|
/* <20><>动并挂载后台射<E58FB0><E5B084>监控应<E68EA7><E5BA94>,开始侦<E5A78B><E4BEA6>无线传感器信<E599A8><E4BFA1> */
|
2026-07-28 18:34:28 +08:00
|
|
|
|
AppManager_AttachToBackground(&rf_monitor_app);
|
|
|
|
|
|
|
2026-07-30 13:46:44 +08:00
|
|
|
|
/* <20><><EFBFBD><EFBFBD> 1ms 系统基准定时<E5AE9A><E697B6> Timer1 */
|
2026-07-15 15:57:37 +08:00
|
|
|
|
Timer1_Init();
|
|
|
|
|
|
|
2026-07-30 13:46:44 +08:00
|
|
|
|
/* <20><>机自动加载并运<E5B9B6><E8BF90>待机时钟前台活跃应<E8B783><E5BA94> */
|
2026-07-17 19:43:02 +08:00
|
|
|
|
AppManager_StartApp(APP_ID_CLOCK);
|
|
|
|
|
|
|
|
|
|
|
|
Uart_SendString("[SYS] Event-driven framework ready\r\n");
|
2026-07-15 15:57:37 +08:00
|
|
|
|
|
2026-07-30 13:46:44 +08:00
|
|
|
|
// ====== 主循<E4B8BB><E5BEAA> ======
|
2026-07-15 15:57:37 +08:00
|
|
|
|
while (1) {
|
2026-07-30 13:46:44 +08:00
|
|
|
|
/* 0. <20><>查主<E69FA5><E4B8BB><EFBFBD><EFBFBD>按键定时标志 (<28><> 1ms <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>位,主循<E4B8BB><E5BEAA>响应清除并<E999A4><E5B9B6>理) */
|
2026-07-28 18:03:20 +08:00
|
|
|
|
if (key_scan_flag) {
|
|
|
|
|
|
key_scan_flag = 0;
|
|
|
|
|
|
Event_KeyScan_Poll();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-07-30 13:46:44 +08:00
|
|
|
|
/* 1. 串口非阻塞指令捕<E4BBA4><E68D95> -> 装配为事件方式入<E5BC8F><E585A5> */
|
2026-07-15 15:57:37 +08:00
|
|
|
|
cmd = Uart_RxChar();
|
|
|
|
|
|
if (cmd != '\0') {
|
2026-07-15 16:14:30 +08:00
|
|
|
|
Debug_ProcessCommand(cmd);
|
2026-07-15 15:57:37 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2026-07-30 13:46:44 +08:00
|
|
|
|
/* 2. 事件分发总线:循<EFBC9A><E5BEAA><EFBFBD><EFBFBD>询并处理队列<E9989F><E58897>的所有有效事<E69588><E4BA8B> */
|
2026-07-15 15:57:37 +08:00
|
|
|
|
while (!EventQueue_IsEmpty()) {
|
|
|
|
|
|
Event_Dispatcher_Loop();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-07-30 13:46:44 +08:00
|
|
|
|
/* 3. 应用调度<E8B083><E5BAA6>心:运<EFBC9A><E8BF90>当前<E5BD93><E5898D>于前台活跃状<E8B783><E78AB6>的应用(集成了 CPU 运<><E8BF90>时间超时挂起保护) */
|
2026-07-15 15:57:37 +08:00
|
|
|
|
AppManager_RunActiveApp();
|
|
|
|
|
|
|
2026-07-30 13:46:44 +08:00
|
|
|
|
/* 4. <20><>动休眠判定:常<EFBC9A><E5B8B8>无操作闲置达到 60 <20><> (6000 * 10ms = 60s) 时,切入低功耗停机休<E69CBA><E4BC91> */
|
2026-07-16 17:52:52 +08:00
|
|
|
|
if (inactivity_timer >= 6000) {
|
2026-07-15 15:57:37 +08:00
|
|
|
|
inactivity_timer = 0;
|
2026-07-30 13:46:44 +08:00
|
|
|
|
current_state = STATE_SLEEP; // 系统<E7B3BB><E7BB9F>为休眠状<E79CA0><E78AB6>
|
|
|
|
|
|
Enter_Low_Power_Sleep(); // 该函数是阻<E698AF><E998BB>的,MCU 将在此挂起<E68C82><E8B5B7>唤醒后将自动从其后继续执<E7BBAD>
|
|
|
|
|
|
current_state = STATE_NORMAL; // 唤醒后重新置为<E7BDAE><E4B8BA>常待机状<E69CBA>
|
|
|
|
|
|
AppManager_StartApp(APP_ID_CLOCK); // 重新<E9878D><E696B0><EFBFBD><EFBFBD>时钟应用以刷新画面和背光
|
2026-07-15 15:57:37 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-07-30 13:46:44 +08:00
|
|
|
|
// 唤醒源事件标志,由<EFBC8C><E794B1>应的<E5BA94><E79A84>部<EFBFBD><E983A8><EFBFBD><EFBFBD> ISR 写入
|
|
|
|
|
|
volatile u8 p0_wakeup_flag = 0; // P0 <20><>口按<E58FA3><E68C89>唤醒标志
|
|
|
|
|
|
volatile u8 p2_wakeup_flag = 0; // P2 <20><>口按<E58FA3><E68C89>唤醒标志
|
|
|
|
|
|
volatile u8 p3_wakeup_flag = 0; // P3 <20><>口射频中<E9A291><E4B8AD>唤醒标志
|
|
|
|
|
|
volatile u8 rf_wakeup_flag = 0; // 射<><E5B084>中<EFBFBD><E4B8AD>唤醒标志
|
2026-07-16 17:52:52 +08:00
|
|
|
|
|
2026-07-15 15:57:37 +08:00
|
|
|
|
/* =========================================================================
|
2026-07-30 13:46:44 +08:00
|
|
|
|
* STC32G <EFBFBD><EFBFBD>口掉电<EFBFBD><EFBFBD>部<EFBFBD><EFBFBD><EFBFBD><EFBFBD>唤醒<EFBFBD><EFBFBD><EFBFBD><EFBFBD>服务程序 (ISR)
|
2026-07-15 15:57:37 +08:00
|
|
|
|
* ========================================================================= */
|
|
|
|
|
|
|
2026-07-16 17:52:52 +08:00
|
|
|
|
/**
|
2026-07-30 13:46:44 +08:00
|
|
|
|
* @brief Port0 <EFBFBD><EFBFBD>口掉电中<EFBFBD><EFBFBD>服务函数 (<EFBFBD><EFBFBD> isr_jump.asm 引<EFBFBD><EFBFBD>定位至<EFBFBD><EFBFBD>)
|
|
|
|
|
|
* @details 负责处理 P0.1, P0.2, P0.3 按键在休眠模式下的物理触发,并立刻<EFBFBD><EFBFBD>用<EFBFBD><EFBFBD><EFBFBD><EFBFBD>防<EFBFBD><EFBFBD>反复执行<EFBFBD>
|
2026-07-16 17:52:52 +08:00
|
|
|
|
*/
|
2026-07-15 15:57:37 +08:00
|
|
|
|
void Port0_Isr(void) interrupt 13
|
|
|
|
|
|
{
|
2026-07-30 13:46:44 +08:00
|
|
|
|
EAXFR = 1; // 使能访问扩展寄存<E5AF84><E5AD98>
|
|
|
|
|
|
p0_wakeup_flag = P0INTF | 0x01;// 读取并<E58F96><E5B9B6>份 P0 <20><><EFBFBD><EFBFBD>标志寄存器<E5AD98> (0x01作安全掩<E585A8><E68EA9>)
|
|
|
|
|
|
P0INTF = 0x00; // 清除 P0 <20><>口中<E58FA3><E4B8AD><EFBFBD><EFBFBD>挂标志位
|
|
|
|
|
|
P0INTE = 0x00; // 【关<E38090><E585B3>保护】:立即关闭 P0 <20><><EFBFBD><EFBFBD>允<EFBFBD><E58581>,防<EFBC8C><E998B2>按<EFBFBD><E68C89>处于低电平期间反复触<E5A48D><E8A7A6> ISR 导致堆栈溢出
|
2026-07-15 15:57:37 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2026-07-16 17:52:52 +08:00
|
|
|
|
/**
|
2026-07-30 13:46:44 +08:00
|
|
|
|
* @brief Port2 <EFBFBD><EFBFBD>口掉电中<EFBFBD><EFBFBD>服务函数 (<EFBFBD><EFBFBD> isr_jump.asm 引<EFBFBD><EFBFBD>定位至<EFBFBD><EFBFBD>)
|
|
|
|
|
|
* @details 负责处理 P2.6 (SOS按键) <EFBFBD><EFBFBD> P2.1 (射<EFBFBD><EFBFBD>数<EFBFBD><EFBFBD><EFBFBD><EFBFBD>) 在休眠模式下的物理跳变唤醒<EFBFBD>
|
2026-07-16 17:52:52 +08:00
|
|
|
|
*/
|
2026-07-15 15:57:37 +08:00
|
|
|
|
void Port2_Isr(void) interrupt 15
|
|
|
|
|
|
{
|
2026-07-30 13:46:44 +08:00
|
|
|
|
EAXFR = 1; // 使能扩展寄存<E5AF84><E5AD98>
|
|
|
|
|
|
p2_wakeup_flag = P2INTF | 0x01;// 读取并<E58F96><E5B9B6>份 P2 <20><><EFBFBD><EFBFBD>标志寄存区的<E58CBA><E79A84>
|
|
|
|
|
|
P2INTF = 0x00; // 清除 P2 <20><>口中<E58FA3><E4B8AD><EFBFBD><EFBFBD>挂标志位
|
|
|
|
|
|
P2INTE = 0x00; // 立即关闭 P2 <20><><EFBFBD><EFBFBD>通道,防<EFBC8C><E998B2>低电平期间反复重<E5A48D><E9878D>
|
2026-07-15 15:57:37 +08:00
|
|
|
|
}
|
2026-07-17 19:43:02 +08:00
|
|
|
|
|
|
|
|
|
|
/**
|
2026-07-30 13:46:44 +08:00
|
|
|
|
* @brief Port3 <EFBFBD><EFBFBD>口掉电中<EFBFBD><EFBFBD>服务函数 (<EFBFBD><EFBFBD> isr_jump.asm 引<EFBFBD><EFBFBD>定位至<EFBFBD><EFBFBD>)
|
|
|
|
|
|
* @details 负责处理 P3.6 (新射频数<EFBFBD><EFBFBD><EFBFBD><EFBFBD>) 在休眠模式下的物理跳变唤醒<EFBFBD>
|
2026-07-17 19:43:02 +08:00
|
|
|
|
*/
|
|
|
|
|
|
void Port3_Isr(void) interrupt 16
|
|
|
|
|
|
{
|
2026-07-30 13:46:44 +08:00
|
|
|
|
EAXFR = 1; // 使能访问扩展寄存<E5AF84><E5AD98>
|
|
|
|
|
|
p3_wakeup_flag = P3INTF | 0x01;// 读取并<E58F96><E5B9B6>份 P3 <20><><EFBFBD><EFBFBD>标志寄存器<E5AD98> (0x01作安全掩<E585A8><E68EA9>)
|
|
|
|
|
|
P3INTF = 0x00; // 清除 P3 <20><>口中<E58FA3><E4B8AD><EFBFBD><EFBFBD>挂标志位
|
|
|
|
|
|
P3INTE = 0x00; // 立即关闭 P3 <20><><EFBFBD><EFBFBD>通道,防止反复重<E5A48D><E9878D>
|
2026-07-17 19:43:02 +08:00
|
|
|
|
}
|