#include "config.h" #include "rgb.h" #include "event.h" #include "app_manager.h" #include "database.h" #include "ui.h" #include "system.h" #include "../Drivers/rf.h" #include "../Drivers/lcd.h" /* ========================================================================= * 绯荤粺鍏ㄥ眬鍙橀噺瀹氫箟 * ========================================================================= */ SystemState current_state = STATE_NORMAL; // 绯荤粺鏁翠綋鐨勫綋鍓嶈繍琛岀姸鎬侊紝榛樿や负姝e父鏃堕挓寰呮満椤 u8 menu_select = 0; // 涓昏彍鍗曞綋鍓嶉変腑鐨勮岄珮浜绱㈠紩 (0~2) u32 captured_addr = 0; // 閰嶅规垨鎶ヨ︽椂锛屾崟鑾峰埌鐨勪紶鎰熷櫒 24 浣 EV1527 灏勯戠墿鐞嗗湴鍧 u8 captured_type = 0; // 姝e湪瀵圭爜鎴栬Е鍙戣︽姤鐨勪紶鎰熷櫒璁惧囩被鍨 (0:闂ㄧ, 1:PIR...) u8 alarm_sensor_slot = 0; // 瑙﹀彂璀︽姤鐨勪紶鎰熷櫒鍦 sensor_list 鏁扮粍涓鐨勭储寮曟Ы浣嶅彿 // 浼犳劅鍣ㄥ瓨鍌ㄥ垪琛ㄦ暟鎹搴擄紝浣嶄簬鍗曠墖鏈哄栭儴 XDATA 瀛樺偍绌洪棿锛屾诲叡 16 涓妲戒綅 Sensor_Slot xdata sensor_list[16]; // 鍏ㄥ眬婊寸瓟涓庡畾鏃朵腑鏂璁℃暟鍙橀噺锛屼綅浜 volatile 闃叉㈣缂栬瘧鍣ㄤ紭鍖 volatile u16 ms_tick = 0; // 瀹氭椂涓鏂 1ms 鍩哄噯婊寸瓟绱鍔犲櫒 volatile u16 inactivity_timer = 0; // 鐢ㄦ埛闂茬疆璁℃椂鍣锛岀敤浜庢棤鎿嶄綔鍒ゅ畾锛堝崟浣: 10ms锛 volatile u32 pair_timeout_ms = 0; // 浼犳劅鍣ㄩ厤瀵瑰圭爜瓒呮椂姣绉掕℃椂鍣 (涓婇檺 30000ms 鍗 30s) volatile u16 alarm_timer_ms = 0; // 鍏ヤ镜鎶ヨ﹂┈杈鹃渿鍔ㄦ椂搴忚℃暟鍣 volatile u16 motor_timer_ms = 0; // 鐙绔嬮┈杈鹃渿鍔ㄦ椂闀胯℃暟鍣 volatile bit alarm_flash_flag = 0; // 鎶ヨ︽椂绾㈡嗗懆鏈熸ч棯鐑佷寒鐏鏍囧織浣 // 鐗╃悊鎸夐敭鎵鎻忎笌娑堟姈闀挎寜璁℃暟鍣 (10ms 鎵鎻忎竴娆) volatile u16 key_scan_timer = 0; // 10ms 鎵鎻忓懆鏈熷垎棰戝櫒 volatile u16 key_up_hold = 0; // 鈻 (KEY_UP) 鎸変笅鏃堕暱绱鍔 volatile u16 key_down_hold = 0; // 鈻 (KEY_DOWN) 鎸変笅鏃堕暱绱鍔 volatile u16 key_confirm_hold = 0; // 鈻 (KEY_CONFIRM) 鎸変笅鏃堕暱绱鍔 volatile u16 key_sos_hold = 0; // SOS 鎸変笅鏃堕暱绱鍔 volatile u16 comb_hold = 0; // 鈻 + 鈻 缁勫悎閿鎸変笅鏃堕暱绱鍔 /* ========================================================================= * 涓插彛璋冭瘯鎸囦护瑙f瀽涓庝簨浠舵淳鍙戝皝瑁 * ========================================================================= */ /** * @brief 瑙f瀽閫氳繃涓插彛 1 鍙戦佹潵鐨勯敭鐩樺強娴嬭瘯妯℃嫙鎸囦护 * @param cmd 鎺ユ敹鍒扮殑 ASCII 瀛楃﹀懡浠 * @details 璐熻矗灏嗗瓧绗︽寚浠よ浆鍖栧瑰簲鐨勭郴缁熸寜閿鎴栧皠棰戜簨浠讹紝骞舵帹鍏ヤ簨浠堕槦鍒椾互娴嬭瘯杞浠舵灦鏋勶細 * - 'u'/'U': 妯℃嫙鐭鎸/闀挎寜 鈻 閿銆 * - 'd'/'D': 妯℃嫙鐭鎸/闀挎寜 鈻 閿銆 * - 's'/'S': 妯℃嫙鐭鎸/闀挎寜 SOS 鐗╃悊閿锛堜紭鍏堟彃鍏ラ槦棣栵級銆 * - 'c'/'C': 妯℃嫙缁勫悎閿瑙﹀彂銆 * - 'a'/'A': 妯℃嫙鏃犵嚎浼犳劅鍣ㄥ叆渚佃Е鍙戣︽姤淇″彿锛屽湴鍧鍥哄畾涓 0x123456锛寊one=1銆 * - 'p'/'P': 妯℃嫙瀵圭爜鏈熼棿鎹曡幏鐨 24 浣嶆棤绾垮圭爜淇″彿锛屽湴鍧鍥哄畾涓 0x789ABC銆 * - '1'/'2'/'3': 妯℃嫙绯荤粺鐨勬e父銆佸凡甯冮槻銆佸凡鎾ら槻鐘舵佸垏鎹銆 * - 'z'/'Z': 妯℃嫙瓒呮椂锛屽己琛屼娇闂茬疆璁℃暟鍣ㄧ疆 6000锛岃Е鍙戣嚜鍔ㄦ繁搴︿紤鐪犮 * - 't'/'T': 瑙﹀彂灞忓箷涓庢棤绾挎帶鍒跺紩鑴氭祴璇曘 */ /** * @brief 串口调试专属:RGB 物理颜色通道排查测试 * @details 依次发送纯红、纯绿、纯蓝的数据流,每个颜色亮起 2 秒,帮助肉眼校对物理灯珠的实际颜色映射关系 */ void RGB_Diagnostic_Test(void) { Uart_SendString("\r\n=== RGB LED Color Channel Test Starting ===\r\n"); // 1. 尝试发送红色控制数据 (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); // 熄灭 RGB_Send(0, 0, 0, 0, 0, 0); Delay_ms(300); // 2. 尝试发送绿色控制数据 (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); // 熄灭 RGB_Send(0, 0, 0, 0, 0, 0); Delay_ms(300); // 3. 尝试发送蓝色控制数据 (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); // 彻底熄灭 RGB_Send(0, 0, 0, 0, 0, 0); Uart_SendString("=== RGB LED Color Channel Test Ended ===\r\n"); } void Debug_ProcessCommand(char cmd) { SystemEvent debug_evt; inactivity_timer = 0; // 鏀跺埌鎸囦护锛岀珛鍗抽噸缃鐢ㄦ埛鐨勬棤鎿嶄綔闂茬疆璁℃椂鍣 debug_evt.extra_data = 0; debug_evt.extra_size = 0; if (cmd == 'u') { debug_evt.key_event = KEY_EVENT_UP_CLICK; debug_evt.priority = EVENT_PRIORITY_NORMAL; EventQueue_Push(debug_evt); // 鍘嬪叆闃熷熬 Uart_SendString("[UART] KEY_UP Clicked\r\n"); } else if (cmd == 'U') { debug_evt.key_event = KEY_EVENT_UP_LONG; debug_evt.priority = EVENT_PRIORITY_NORMAL; EventQueue_Push(debug_evt); Uart_SendString("[UART] KEY_UP Long Pressed\r\n"); } else if (cmd == 'd') { debug_evt.key_event = KEY_EVENT_DOWN_CLICK; debug_evt.priority = EVENT_PRIORITY_NORMAL; EventQueue_Push(debug_evt); Uart_SendString("[UART] KEY_DOWN Clicked\r\n"); } else if (cmd == 'D') { debug_evt.key_event = KEY_EVENT_DOWN_LONG; debug_evt.priority = EVENT_PRIORITY_NORMAL; EventQueue_Push(debug_evt); Uart_SendString("[UART] KEY_DOWN Long Pressed\r\n"); } else if (cmd == 's') { debug_evt.key_event = KEY_EVENT_SOS_CLICK; debug_evt.priority = EVENT_PRIORITY_URGENT; EventQueue_InsertFront(debug_evt); // 绱фヤ簨浠舵彃鍏ラ槦棣 Uart_SendString("[UART] KEY_SOS Clicked\r\n"); } else if (cmd == 'S') { debug_evt.key_event = KEY_EVENT_SOS_LONG; debug_evt.priority = EVENT_PRIORITY_URGENT; EventQueue_InsertFront(debug_evt); Uart_SendString("[UART] KEY_SOS Long Pressed\r\n"); } else if (cmd == 'c' || cmd == 'C') { debug_evt.key_event = KEY_EVENT_UP_DOWN_COMB; debug_evt.priority = EVENT_PRIORITY_NORMAL; EventQueue_Push(debug_evt); Uart_SendString("[UART] KEY_UP+DOWN Combined\r\n"); } else if (cmd == 'a' || cmd == 'A') { u32 mock_addr = 0x123456; // 璁惧畾妯℃嫙鐨勬姤璀﹀皠棰戞簮鍦板潃 u8 mock_slot; // 濡傛灉鏈鍦版暟鎹搴撲腑娌℃湁鍖归厤璇ュ皠棰戯紝鍒欏己鍒剁櫥璁拌繘 1 鍙烽槻鍖 if (!Check_Sensor_ID(mock_addr, &mock_slot)) { Add_Sensor_With_Zone(mock_addr, 0, 1); } debug_evt.key_event = KEY_EVENT_NONE; debug_evt.priority = EVENT_PRIORITY_HIGH; // 鍏ヤ镜鎶ヨ﹁句负 HIGH 浼樺厛绾 debug_evt.extra_data = mock_addr; debug_evt.extra_size = 4; EventQueue_InsertFront(debug_evt); // 楂樹紭鍏堢骇鎻掗槦 Uart_SendString("[UART] Mock RF Alarm\r\n"); } else if (cmd == 'p' || cmd == 'P') { // 鍙鏈夊綋鎵嬬幆鍒囧叆 Pair 妯″紡鏃讹紝妯℃嫙瀵圭爜淇″彿鎵嶆湁鏁 if (AppManager_GetActiveAppID() == APP_ID_PAIR) { debug_evt.key_event = KEY_EVENT_NONE; debug_evt.priority = EVENT_PRIORITY_NORMAL; debug_evt.extra_data = 0x789ABC; // 璁惧畾妯℃嫙瀵圭爜纭浠跺湴鍧 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"); } } else if (cmd == '1') { // 妯℃嫙鍒囨崲鑷 姝e父鎾ら槻 (NORMAL) 鐘舵佸苟鍒锋柊鏃堕挓 if (AppManager_GetActiveAppID() == APP_ID_CLOCK) { current_state = STATE_NORMAL; UI_ShowClockPage(current_state, current_hour, current_min); } Uart_SendString("[UART] State: NORMAL\r\n"); } else if (cmd == '2') { // 妯℃嫙鍒囨崲鑷 宸插竷闃 (ARMED) 鐘舵侊紝鏅閫氶棬纾佸彲瑙﹀彂璀︽姤 if (AppManager_GetActiveAppID() == APP_ID_CLOCK) { current_state = STATE_ARMED; UI_ShowClockPage(current_state, current_hour, current_min); } Uart_SendString("[UART] State: ARMED\r\n"); } else if (cmd == '3') { // 妯℃嫙鍒囨崲鑷 宸叉挙闃 (DISARMED) 鐘舵侊紝蹇界暐鏅閫氭姤璀 if (AppManager_GetActiveAppID() == APP_ID_CLOCK) { current_state = STATE_DISARMED; UI_ShowClockPage(current_state, current_hour, current_min); } Uart_SendString("[UART] State: DISARMED\r\n"); } else if (cmd == 'z' || cmd == 'Z') { inactivity_timer = 6000; // 妯℃嫙闂茬疆 60 绉掕秴鏃讹紝寮哄埗瑙﹀彂涓诲惊鐜娣卞害浼戠湢 Uart_SendString("[UART] Force Entering Sleep mode!\r\n"); } else if (cmd == 'q' || cmd == 'Q') { RGB_Diagnostic_Test(); // 启动 RGB 物理颜色通道排查测试 } else if (cmd == 't' || cmd == 'T') { RF_DiagnosticMode('t'); // 瑙﹀彂灏勯戣繛缁鍙戝皠璇婃柇 (缁胯壊鐖嗛棯) } else if (cmd == 'r' || cmd == 'R') { RF_DiagnosticMode('r'); // 瑙﹀彂 5 绉掑皠棰戞帴鏀剁洃鍚璇婃柇 } else if (cmd == 'l' || cmd == 'L') { Loopback_Test(); // 瑙﹀彂鐗╃悊鐢垫皵鍥炵幆娴嬭瘯 (鐭璺 P2.1 鍜 P3.6 鑷妫) } } /* ========================================================================= * 涓诲嚱鏁 (鍏ュ彛) * ========================================================================= */ void main(void) { char cmd; // ====== STC32G 鐗规畩鍔熻兘瀵勫瓨鍣ㄥ唴鏍稿熀纭鍒濆嬪寲 ====== WTST = 0; // 璁剧疆绋嬪簭 Flash 璁块棶绛夊緟鏃堕棿涓 0 (鏈楂橀熻繍琛) EAXFR = 1; // 鍏佽歌块棶鎵╁睍鐗规畩鍔熻兘瀵勫瓨鍣 (XSFR) CKCON = 0; // 澶栭儴鎬荤嚎鏃堕挓璁惧畾涓烘渶蹇 WDT_CONTR = 0x00; // 鍏抽棴鐪嬮棬鐙楀畾鏃跺櫒 // ====== 纭浠跺悇妯″潡鍩虹鍒濆嬪寲 ====== GPIO_Init(); // 閰嶇疆鍚勪釜寮曡剼鐨勬帹鎸借緭鍑/鍑嗗弻鍚戞ā寮忓強鍐呴儴涓婃媺 (閿佸瓨 PWR_HOLD=1) RGB_Send(0, 0, 0, 0, 0, 0); // 銆愰栬佷慨姝c戯細涓婄數绗涓鏃堕棿寮哄埗鍙戦 0 鐮佸叧闂鐏鏉★紝鐔勭伃涓婄數鏆傛佸紩璧风殑闅忔満鐧藉厜锛 RF_Init(); // 鍒濆嬪寲灏勯戣姱鐗囧悇寮曡剼鎺у埗 Delay_ms(500); // 杞鍚鍔ㄥ欢鏃讹紝绛夊緟渚涚數鐢靛圭ǔ瀹 LCD_Init(); // 鍒濆嬪寲 LHS114TC-IF03 (ST7789V) 灞忓箷鎺у埗瀵勫瓨鍣ㄥ簭鍒楀苟寮鍚鑳屽厜 Uart1_Init(); // 鍒濆嬪寲涓插彛 1 娉㈢壒鐜 115200 渚涜皟璇曟棩蹇 Uart_SendString("Wristband System Initialized!\r\n"); Self_Test(); // 鎵ц屼笂鐢电‖浠惰嚜妫 (PWR_HOLD閿佸瓨銆丳0.3 ADC鎸夐敭甯告併丳1.3 鐢垫睜鐢甸噺) Load_Database(); // 浠 IAP Flash 绗 254 鎵囧尯璇诲彇鎵鏈夊凡缁戝畾鐨勪紶鎰熷櫒鏁版嵁鑷 RAM /* 姝ラ 1: 鍒濆嬪寲浜嬩欢鐜褰㈢紦鍐插尯闃熷垪 */ EventQueue_Init(); /* 姝ラ 2+5: 鍒濆嬪寲搴旂敤绠$悊鍣ㄥ苟鐧昏版墍鏈夊墠鍙板簲鐢锛岄粯璁ゅ姞杞 ClockApp */ AppManager_Init(); /* 鍚鍔ㄥ苟鎸傝浇鍚庡彴灏勯戠洃鎺у簲鐢锛屽紑濮嬩睛鍚鏃犵嚎浼犳劅鍣ㄤ俊鍙 */ AppManager_AttachToBackground(&rf_monitor_app); /* 鍚鍔 1ms 绯荤粺鍩哄噯瀹氭椂鍣 Timer1 */ Timer1_Init(); /* 寮鏈鸿嚜鍔ㄥ姞杞藉苟杩愯屽緟鏈烘椂閽熷墠鍙版椿璺冨簲鐢 */ AppManager_StartApp(APP_ID_CLOCK); Uart_SendString("[SYS] Event-driven framework ready\r\n"); // ====== 涓诲惊鐜 ====== while (1) { /* 0. 妫鏌ヤ富寰鐜鎸夐敭瀹氭椂鏍囧織 (鐢 1ms 涓鏂缃浣嶏紝涓诲惊鐜鍝嶅簲娓呴櫎骞跺勭悊) */ if (key_scan_flag) { key_scan_flag = 0; Event_KeyScan_Poll(); } /* 1. 涓插彛闈為樆濉炴寚浠ゆ崟鑾 -> 瑁呴厤涓轰簨浠舵柟寮忓叆闃 */ cmd = Uart_RxChar(); if (cmd != '\0') { Debug_ProcessCommand(cmd); } /* 2. 浜嬩欢鍒嗗彂鎬荤嚎锛氬惊鐜杞璇㈠苟澶勭悊闃熷垪涓鐨勬墍鏈夋湁鏁堜簨浠 */ while (!EventQueue_IsEmpty()) { Event_Dispatcher_Loop(); } /* 3. 搴旂敤璋冨害涓蹇冿細杩愯屽綋鍓嶅勪簬鍓嶅彴娲昏穬鐘舵佺殑搴旂敤锛堥泦鎴愪簡 CPU 杩愯屾椂闂磋秴鏃舵寕璧蜂繚鎶わ級 */ AppManager_RunActiveApp(); /* 4. 自动休眠判定:常态无操作闲置达到 60 秒 (6000 * 10ms = 60s) 时,切入低功耗停机休眠 */ if (inactivity_timer >= 6000) { inactivity_timer = 0; current_state = STATE_SLEEP; // 系统置为休眠状态 // 强保电源锁存,复位所有按键状态计数(在 main.c 本地清除,杜绝 extern 重定位空间踩踏风险) PWR_HOLD = 1; key_up_hold = 0; key_down_hold = 0; key_confirm_hold = 0; key_sos_hold = 0; comb_hold = 0; Enter_Low_Power_Sleep(); // 该函数是阻塞的,MCU 将在此挂起。唤醒后将自动从其后继续执行 // 唤醒后的再次强拉高锁存与计数清零 PWR_HOLD = 1; key_up_hold = 0; key_down_hold = 0; key_confirm_hold = 0; key_sos_hold = 0; comb_hold = 0; current_state = STATE_NORMAL; // 唤醒后重新置为正常待机状态 AppManager_StartApp(APP_ID_CLOCK); // 重新开启时钟应用以刷新画面和背光 } } } // 鍞ら啋婧愪簨浠舵爣蹇楋紝鐢卞瑰簲鐨勫栭儴涓鏂 ISR 鍐欏叆 volatile u8 p0_wakeup_flag = 0; // P0 绔鍙f寜閿鍞ら啋鏍囧織 volatile u8 p2_wakeup_flag = 0; // P2 绔鍙f寜閿鍞ら啋鏍囧織 volatile u8 p3_wakeup_flag = 0; // P3 绔鍙e皠棰戜腑鏂鍞ら啋鏍囧織 volatile u8 rf_wakeup_flag = 0; // 灏勯戜腑鏂鍞ら啋鏍囧織 /* ========================================================================= * STC32G 绔鍙f帀鐢靛栭儴涓鏂鍞ら啋涓鏂鏈嶅姟绋嬪簭 (ISR) * ========================================================================= */ /** * @brief Port0 绔鍙f帀鐢典腑鏂鏈嶅姟鍑芥暟 (鐢 isr_jump.asm 寮曞煎畾浣嶈嚦姝) * @details 璐熻矗澶勭悊 P0.1, P0.2, P0.3 鎸夐敭鍦ㄤ紤鐪犳ā寮忎笅鐨勭墿鐞嗚Е鍙戯紝骞剁珛鍒荤佺敤涓鏂闃叉㈠弽澶嶆墽琛屻 */ void Port0_Isr(void) interrupt 13 { EAXFR = 1; // 浣胯兘璁块棶鎵╁睍瀵勫瓨鍖 p0_wakeup_flag = P0INTF | 0x01;// 璇诲彇骞跺囦唤 P0 涓鏂鏍囧織瀵勫瓨鍣ㄥ (0x01浣滃畨鍏ㄦ帺鐮) P0INTF = 0x00; // 娓呴櫎 P0 绔鍙d腑鏂鎮鎸傛爣蹇椾綅 P0INTE = 0x00; // 銆愬叧閿淇濇姢銆戯細绔嬪嵆鍏抽棴 P0 涓鏂鍏佽革紝闃叉㈡寜閿澶勪簬浣庣數骞虫湡闂村弽澶嶈Е鍙 ISR 瀵艰嚧鍫嗘爤婧㈠嚭 } /** * @brief Port2 绔鍙f帀鐢典腑鏂鏈嶅姟鍑芥暟 (鐢 isr_jump.asm 寮曞煎畾浣嶈嚦姝) * @details 璐熻矗澶勭悊 P2.6 (SOS鎸夐敭) 涓 P2.1 (灏勯戞暟鎹鑴) 鍦ㄤ紤鐪犳ā寮忎笅鐨勭墿鐞嗚烦鍙樺敜閱掋 */ void Port2_Isr(void) interrupt 15 { EAXFR = 1; // 浣胯兘鎵╁睍瀵勫瓨鍖 p2_wakeup_flag = P2INTF | 0x01;// 璇诲彇骞跺囦唤 P2 涓鏂鏍囧織瀵勫瓨鍖虹殑鍊 P2INTF = 0x00; // 娓呴櫎 P2 绔鍙d腑鏂鎮鎸傛爣蹇椾綅 P2INTE = 0x00; // 绔嬪嵆鍏抽棴 P2 涓鏂閫氶亾锛岄槻姝浣庣數骞虫湡闂村弽澶嶉噸鍏 } /** * @brief Port3 绔鍙f帀鐢典腑鏂鏈嶅姟鍑芥暟 (鐢 isr_jump.asm 寮曞煎畾浣嶈嚦姝) * @details 璐熻矗澶勭悊 P3.6 (鏂板皠棰戞暟鎹鑴) 鍦ㄤ紤鐪犳ā寮忎笅鐨勭墿鐞嗚烦鍙樺敜閱掋 */ void Port3_Isr(void) interrupt 16 { EAXFR = 1; // 浣胯兘璁块棶鎵╁睍瀵勫瓨鍖 p3_wakeup_flag = P3INTF | 0x01;// 璇诲彇骞跺囦唤 P3 涓鏂鏍囧織瀵勫瓨鍣ㄥ (0x01浣滃畨鍏ㄦ帺鐮) P3INTF = 0x00; // 娓呴櫎 P3 绔鍙d腑鏂鎮鎸傛爣蹇椾綅 P3INTE = 0x00; // 绔嬪嵆鍏抽棴 P3 涓鏂閫氶亾锛岄槻姝㈠弽澶嶉噸鍏 }