2026-07-15 16:14:30 +08:00
|
|
|
|
#include "system.h"
|
|
|
|
|
|
#include "rgb.h"
|
|
|
|
|
|
#include "ui.h"
|
|
|
|
|
|
#include "../Drivers/lcd.h"
|
2026-07-15 17:05:22 +08:00
|
|
|
|
#include "../Drivers/rf.h"
|
|
|
|
|
|
#include "app_manager.h"
|
2026-07-15 17:26:50 +08:00
|
|
|
|
#include "database.h"
|
2026-07-15 16:14:30 +08:00
|
|
|
|
|
|
|
|
|
|
void GPIO_Init(void)
|
|
|
|
|
|
{
|
|
|
|
|
|
IE = 0x00;
|
|
|
|
|
|
IE2 = 0x00;
|
|
|
|
|
|
TCON = 0x00;
|
|
|
|
|
|
TMOD &= 0xF0;
|
|
|
|
|
|
TR0 = 0;
|
|
|
|
|
|
ET0 = 0;
|
|
|
|
|
|
AUXR = 0x00;
|
|
|
|
|
|
INTCLKO = 0x00;
|
|
|
|
|
|
P_SW1 = 0x00;
|
|
|
|
|
|
P_SW2 = 0x80; // 开启 EAXFR=1,允许访问 P0PU/P2PU/P0INTE/P2INTE 等扩展 SFR 寄存器
|
|
|
|
|
|
P_SW3 = 0x00;
|
|
|
|
|
|
|
|
|
|
|
|
// 配置 P0.0 (BAT_ADC) 为高阻输入模式
|
|
|
|
|
|
P0M1 |= (1 << 0);
|
|
|
|
|
|
P0M0 &= ~(1 << 0);
|
|
|
|
|
|
|
|
|
|
|
|
// 配置 P0.1 (KEY_UP), P0.2 (KEY_CONFIRM), P0.3 (KEY_DOWN) 为准双向口模式并置 1
|
|
|
|
|
|
P0M1 &= ~((1 << 1) | (1 << 2) | (1 << 3));
|
|
|
|
|
|
P0M0 &= ~((1 << 1) | (1 << 2) | (1 << 3));
|
|
|
|
|
|
KEY_UP = 1;
|
|
|
|
|
|
KEY_CONFIRM = 1;
|
|
|
|
|
|
KEY_DOWN = 1;
|
|
|
|
|
|
|
|
|
|
|
|
// 配置 P2.3 (RGB_DIN) 为推挽输出模式
|
|
|
|
|
|
P2M1 &= ~(1 << 3);
|
|
|
|
|
|
P2M0 |= (1 << 3);
|
|
|
|
|
|
RGB_DIN = 0;
|
|
|
|
|
|
|
|
|
|
|
|
// 配置 P2.5 (MOTOR) 为推挽输出模式
|
|
|
|
|
|
P2M1 &= ~(1 << 5);
|
|
|
|
|
|
P2M0 |= (1 << 5);
|
|
|
|
|
|
MOTOR = 0;
|
|
|
|
|
|
|
|
|
|
|
|
// 配置 P2.6 (KEY_SOS) 为准双向口模式并置 1
|
|
|
|
|
|
P2M1 &= ~(1 << 6);
|
|
|
|
|
|
P2M0 &= ~(1 << 6);
|
|
|
|
|
|
KEY_SOS = 1;
|
|
|
|
|
|
|
|
|
|
|
|
// 配置 P2.2 (SHUT) 为推挽输出模式
|
|
|
|
|
|
P2M1 &= ~(1 << 2);
|
|
|
|
|
|
P2M0 |= (1 << 2);
|
|
|
|
|
|
SHUT = 1; // 默认拉高开启射频接收芯片工作
|
|
|
|
|
|
|
|
|
|
|
|
// 开启按键引脚 P0.1, P0.2, P0.3 和 P2.6 的内部上拉电阻,避免引脚抖动误唤醒
|
|
|
|
|
|
P0PU |= 0x0E;
|
|
|
|
|
|
P2PU |= 0x40;
|
|
|
|
|
|
|
|
|
|
|
|
// 配置 P2.7 (DET) 为高阻输入模式
|
|
|
|
|
|
P2M1 |= (1 << 7);
|
|
|
|
|
|
P2M0 &= ~(1 << 7);
|
|
|
|
|
|
|
|
|
|
|
|
// 配置 P3.0 (TXD), P3.1 (RXD) 和 P3.4 (SGM_CTRL)
|
|
|
|
|
|
P3M1 &= ~((1 << 0) | (1 << 1) | (1 << 4));
|
|
|
|
|
|
P3M0 &= ~(1 << 0);
|
|
|
|
|
|
P3M0 |= ((1 << 1) | (1 << 4));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void Delay_ms(u16 ms)
|
|
|
|
|
|
{
|
|
|
|
|
|
u16 i, j;
|
|
|
|
|
|
for (i = 0; i < ms; i++)
|
|
|
|
|
|
for (j = 12000; j > 0; j--);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void Delay10us(void)
|
|
|
|
|
|
{
|
|
|
|
|
|
unsigned char data i;
|
|
|
|
|
|
_nop_();
|
|
|
|
|
|
i = 30;
|
|
|
|
|
|
while (--i);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
u16 GetTimer0_Safe(void)
|
|
|
|
|
|
{
|
|
|
|
|
|
u8 h1, l, h2;
|
|
|
|
|
|
do {
|
|
|
|
|
|
h1 = TH0;
|
|
|
|
|
|
l = TL0;
|
|
|
|
|
|
h2 = TH0;
|
|
|
|
|
|
} while (h1 != h2);
|
|
|
|
|
|
return ((u16)h1 << 8) | l;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void Delay_us(u16 us)
|
|
|
|
|
|
{
|
|
|
|
|
|
u16 ticks = (u16)((u32)us * (MAIN_Fosc / 1000000UL) / 12UL);
|
|
|
|
|
|
TL0 = 0;
|
|
|
|
|
|
TH0 = 0;
|
|
|
|
|
|
TR0 = 1;
|
|
|
|
|
|
while (GetTimer0_Safe() < ticks);
|
|
|
|
|
|
TR0 = 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void Uart1_Init(void)
|
|
|
|
|
|
{
|
|
|
|
|
|
u16 reload = (u16)(65536UL - (MAIN_Fosc / 4 / 115200UL));
|
|
|
|
|
|
SCON = 0x50;
|
|
|
|
|
|
AUXR |= 0x01;
|
|
|
|
|
|
AUXR |= 0x04;
|
|
|
|
|
|
T2L = (u8)reload;
|
|
|
|
|
|
T2H = (u8)(reload >> 8);
|
|
|
|
|
|
AUXR |= 0x10;
|
|
|
|
|
|
TI = 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void Uart_SendByte(u8 dat)
|
|
|
|
|
|
{
|
|
|
|
|
|
REN = 0;
|
|
|
|
|
|
SBUF = dat;
|
|
|
|
|
|
while (!TI);
|
|
|
|
|
|
TI = 0;
|
|
|
|
|
|
RI = 0;
|
|
|
|
|
|
REN = 1;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void Uart_SendString(char *s)
|
|
|
|
|
|
{
|
|
|
|
|
|
REN = 0;
|
|
|
|
|
|
while (*s) {
|
|
|
|
|
|
SBUF = *s++;
|
|
|
|
|
|
while (!TI);
|
|
|
|
|
|
TI = 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
RI = 0;
|
|
|
|
|
|
REN = 1;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
char Uart_RxChar(void)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (RI) {
|
|
|
|
|
|
char c = SBUF;
|
|
|
|
|
|
RI = 0;
|
|
|
|
|
|
return c;
|
|
|
|
|
|
}
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void Uart_SendHex4(u8 val)
|
|
|
|
|
|
{
|
|
|
|
|
|
val &= 0x0F;
|
|
|
|
|
|
if (val < 10)
|
|
|
|
|
|
Uart_SendByte((u8)('0' + val));
|
|
|
|
|
|
else
|
|
|
|
|
|
Uart_SendByte((u8)('A' + (val - 10)));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void Uart_SendHex8(u8 val)
|
|
|
|
|
|
{
|
|
|
|
|
|
Uart_SendHex4(val >> 4);
|
|
|
|
|
|
Uart_SendHex4(val);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void Uart_SendHex20(u32 val)
|
|
|
|
|
|
{
|
|
|
|
|
|
Uart_SendHex4((u8)(val >> 16));
|
|
|
|
|
|
Uart_SendHex8((u8)(val >> 8));
|
|
|
|
|
|
Uart_SendHex8((u8)val);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void Uart_SendHex32(u32 val)
|
|
|
|
|
|
{
|
|
|
|
|
|
Uart_SendHex8((u8)(val >> 24));
|
|
|
|
|
|
Uart_SendHex8((u8)(val >> 16));
|
|
|
|
|
|
Uart_SendHex8((u8)(val >> 8));
|
|
|
|
|
|
Uart_SendHex8((u8)val);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void Uart_SendHex16(u16 val)
|
|
|
|
|
|
{
|
|
|
|
|
|
Uart_SendHex8((u8)(val >> 8));
|
|
|
|
|
|
Uart_SendHex8((u8)val);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void FormatHex(u32 val, char *buf)
|
|
|
|
|
|
{
|
|
|
|
|
|
u8 i;
|
|
|
|
|
|
buf[0] = 'A'; buf[1] = 'D'; buf[2] = 'D'; buf[3] = 'R'; buf[4] = ':';
|
|
|
|
|
|
buf[5] = ' '; buf[6] = '0'; buf[7] = 'x';
|
|
|
|
|
|
for (i = 0; i < 5; i++) {
|
|
|
|
|
|
u8 nibble = (val >> (4 * (4 - i))) & 0x0F;
|
|
|
|
|
|
if (nibble < 10)
|
|
|
|
|
|
buf[8 + i] = '0' + nibble;
|
|
|
|
|
|
else
|
|
|
|
|
|
buf[8 + i] = 'A' + (nibble - 10);
|
|
|
|
|
|
}
|
|
|
|
|
|
buf[13] = '\0';
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void Enter_Low_Power_Sleep(void)
|
|
|
|
|
|
{
|
|
|
|
|
|
// 串口打印进入休眠提示
|
|
|
|
|
|
Uart_SendString("[SYS] Entering low power sleep...\r\n");
|
|
|
|
|
|
|
|
|
|
|
|
// 1. 熄灭 FCOB 双幻彩灯条
|
|
|
|
|
|
RGB_Send(0, 0, 0, 0, 0, 0);
|
|
|
|
|
|
|
|
|
|
|
|
// 2. 向屏幕发送 Display OFF (0x28) 彻底关闭像素发光显示
|
|
|
|
|
|
WriteComm(0x28);
|
|
|
|
|
|
Delay_ms(20);
|
|
|
|
|
|
|
|
|
|
|
|
// 3. AMOLED 屏控制器写入 Sleep In (0x10) 睡眠指令
|
|
|
|
|
|
WriteComm(0x10);
|
|
|
|
|
|
Delay_ms(20);
|
|
|
|
|
|
|
|
|
|
|
|
// 4. 拉低 SGM_CTRL 彻底断开 SGM3833 负压升压芯片的供电
|
|
|
|
|
|
SGM_CTRL = 0;
|
|
|
|
|
|
|
|
|
|
|
|
// 5. 将 AMOLED 控制总线所有 IO 拉低,以防由于 IO 寄生二极管对屏幕倒灌电导致常亮
|
|
|
|
|
|
LCD_CS = 0;
|
|
|
|
|
|
LCD_RST = 0;
|
|
|
|
|
|
LCD_DCX = 0;
|
|
|
|
|
|
LCD_SCL = 0;
|
|
|
|
|
|
LCD_SDI = 0;
|
|
|
|
|
|
|
2026-07-15 17:26:50 +08:00
|
|
|
|
// 6. 休眠状态下开启接收芯片并接通天线 (SHUT=0, RF_RX=1),此时屏幕关闭没有 SGM3833 噪底干扰
|
|
|
|
|
|
RF_SetMode(1);
|
2026-07-15 16:14:30 +08:00
|
|
|
|
|
|
|
|
|
|
// 确保开启扩展寄存器访问 (EAXFR = 1),以便能正确配置端口唤醒使能扩展寄存器
|
|
|
|
|
|
P_SW2 |= 0x80;
|
|
|
|
|
|
|
|
|
|
|
|
// 7. 配置 P0.1, P0.2, P0.3 为 低电平触发 唤醒
|
|
|
|
|
|
P0IM1 |= 0x0E;
|
|
|
|
|
|
P0IM0 &= ~0x0E;
|
|
|
|
|
|
P0INTE |= 0x0E;
|
|
|
|
|
|
|
|
|
|
|
|
// 8. 配置 P2.6 (KEY_SOS) 为 低电平触发 唤醒
|
|
|
|
|
|
P2IM1 |= 0x40;
|
|
|
|
|
|
P2IM0 &= ~0x40;
|
|
|
|
|
|
P2INTE |= 0x40;
|
|
|
|
|
|
|
|
|
|
|
|
// ===== 配置端口掉电唤醒使能寄存器 PxWKUE =====
|
2026-07-15 17:26:50 +08:00
|
|
|
|
P0WKUE |= 0x0E; // 使使能 P0.1/P0.2/P0.3 掉电唤醒
|
|
|
|
|
|
P2WKUE |= 0x40; // 使使能 P2.6 掉电唤醒
|
2026-07-15 16:14:30 +08:00
|
|
|
|
|
2026-07-15 17:26:50 +08:00
|
|
|
|
// 9. 开启外部中断 2 (RF_RX_DATA) 沿触发唤醒源
|
|
|
|
|
|
EX2 = 1;
|
2026-07-15 16:14:30 +08:00
|
|
|
|
|
|
|
|
|
|
// 10. 清除端口中断的悬挂/标志位,防误触
|
|
|
|
|
|
P0INTF = 0x00;
|
|
|
|
|
|
P2INTF = 0x00;
|
|
|
|
|
|
|
2026-07-15 17:26:50 +08:00
|
|
|
|
// 11. 关闭 Timer1 中断,保持 EA=1 让端口/射频中断能唤醒
|
2026-07-15 16:14:30 +08:00
|
|
|
|
ET1 = 0;
|
2026-07-15 17:26:50 +08:00
|
|
|
|
EA = 1;
|
2026-07-15 16:14:30 +08:00
|
|
|
|
|
|
|
|
|
|
// 12. 写入 PCON 掉电模式位,使 MCU 进入深度 Power-Down 挂起状态
|
2026-07-15 17:26:50 +08:00
|
|
|
|
// 如果由于杂波伪唤醒,我们在循环中检测并重新进入休眠
|
|
|
|
|
|
while (1)
|
|
|
|
|
|
{
|
2026-07-15 17:05:22 +08:00
|
|
|
|
Uart_SendString("[SYS] Entering Power-Down mode...\r\n");
|
|
|
|
|
|
PCON |= 0x02; // PD = 1
|
|
|
|
|
|
_nop_();
|
|
|
|
|
|
_nop_();
|
|
|
|
|
|
_nop_();
|
|
|
|
|
|
_nop_();
|
|
|
|
|
|
|
2026-07-15 17:26:50 +08:00
|
|
|
|
// 13. 唤醒并执行完 ISR 后,CPU 从这里继续执行
|
|
|
|
|
|
if (Wakeup_Restore())
|
|
|
|
|
|
{
|
|
|
|
|
|
break; // 真实唤醒(按键或合法射频报警),退出休眠循环
|
2026-07-15 17:05:22 +08:00
|
|
|
|
}
|
2026-07-15 17:26:50 +08:00
|
|
|
|
|
|
|
|
|
|
// 14. 伪唤醒,重新配置唤醒源寄存器,准备下一次 Power-Down
|
|
|
|
|
|
EAXFR = 1;
|
|
|
|
|
|
RF_SetMode(1); // 重新开启接收芯片并接通天线
|
|
|
|
|
|
EX2 = 1; // 重新使能外部中断 2
|
|
|
|
|
|
P0INTF = 0x00;
|
|
|
|
|
|
P2INTF = 0x00;
|
|
|
|
|
|
P0INTE = 0x0E;
|
|
|
|
|
|
P2INTE = 0x40;
|
|
|
|
|
|
P0WKUE = 0x0E;
|
|
|
|
|
|
P2WKUE = 0x40;
|
|
|
|
|
|
ET1 = 0; // 关闭定时器 1
|
|
|
|
|
|
EA = 1;
|
2026-07-15 17:05:22 +08:00
|
|
|
|
}
|
2026-07-15 16:14:30 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2026-07-15 17:26:50 +08:00
|
|
|
|
bit Wakeup_Restore(void)
|
2026-07-15 16:14:30 +08:00
|
|
|
|
{
|
2026-07-15 17:26:50 +08:00
|
|
|
|
u8 p0_flag;
|
|
|
|
|
|
u8 p2_flag;
|
|
|
|
|
|
u16 rf_check_ms = 0;
|
|
|
|
|
|
bit rf_valid = 0;
|
|
|
|
|
|
u32 rx_addr;
|
|
|
|
|
|
u8 rx_data;
|
2026-07-15 16:14:30 +08:00
|
|
|
|
|
|
|
|
|
|
// 确保 EAXFR=1 才能访问扩展 SFR (P0INTF/P2INTF/P0INTE/P2INTE)
|
|
|
|
|
|
EAXFR = 1;
|
|
|
|
|
|
|
2026-07-15 17:26:50 +08:00
|
|
|
|
// [诊断] 在清除标志位之前先读取,判断唤醒来源
|
|
|
|
|
|
p0_flag = P0INTF;
|
|
|
|
|
|
p2_flag = P2INTF;
|
2026-07-15 16:14:30 +08:00
|
|
|
|
|
|
|
|
|
|
// 1. 立即禁用端口中断和唤醒,防止继续触发
|
|
|
|
|
|
P0INTE = 0x00;
|
|
|
|
|
|
P2INTE = 0x00;
|
|
|
|
|
|
P0WKUE = 0x00; // 清除 P0 唤醒允许
|
|
|
|
|
|
P2WKUE = 0x00; // 清除 P2 唤醒允许
|
|
|
|
|
|
P0INTF = 0x00;
|
|
|
|
|
|
P2INTF = 0x00;
|
2026-07-15 17:26:50 +08:00
|
|
|
|
EX2 = 0; // 唤醒后禁用射频中断,运行模式下不受噪底杂波干扰
|
2026-07-15 16:14:30 +08:00
|
|
|
|
|
|
|
|
|
|
// 1b. 关闭掉电唤醒定时器
|
|
|
|
|
|
WKTCH = 0x00;
|
|
|
|
|
|
WKTCL = 0x00;
|
|
|
|
|
|
|
2026-07-15 17:26:50 +08:00
|
|
|
|
// 2. 开启全局中断,但暂时保持 Timer1 关闭以防中断影响射频比值软件解码
|
|
|
|
|
|
EA = 1;
|
|
|
|
|
|
ET1 = 0;
|
2026-07-15 17:05:22 +08:00
|
|
|
|
|
2026-07-15 17:26:50 +08:00
|
|
|
|
// 3. 判断是否为按键唤醒
|
|
|
|
|
|
if ((p0_flag & 0x0E) || (p2_flag & 0x40))
|
|
|
|
|
|
{
|
|
|
|
|
|
if (p0_flag & 0x0E) {
|
|
|
|
|
|
Uart_SendString("[WR] Woken by KEY P0 (P0INTF=0x");
|
|
|
|
|
|
Uart_SendHex8(p0_flag);
|
|
|
|
|
|
Uart_SendString(")\r\n");
|
|
|
|
|
|
} else {
|
|
|
|
|
|
Uart_SendString("[WR] Woken by KEY P2 (P2INTF=0x");
|
|
|
|
|
|
Uart_SendHex8(p2_flag);
|
|
|
|
|
|
Uart_SendString(")\r\n");
|
2026-07-15 17:05:22 +08:00
|
|
|
|
}
|
2026-07-15 16:14:30 +08:00
|
|
|
|
|
2026-07-15 17:26:50 +08:00
|
|
|
|
// 运行模式屏幕开启有噪底干扰,关闭射频接收,防止无信号时在后台乱输出电平
|
|
|
|
|
|
RF_SetMode(0);
|
2026-07-15 16:14:30 +08:00
|
|
|
|
|
2026-07-15 17:26:50 +08:00
|
|
|
|
// 启动 SGM3833 PMIC 并发送脉冲使能升压
|
|
|
|
|
|
SGM_CTRL = 1;
|
|
|
|
|
|
SGM_SendPulse(27);
|
2026-07-15 16:14:30 +08:00
|
|
|
|
|
2026-07-15 17:26:50 +08:00
|
|
|
|
// 等待负压电轨充分稳定
|
|
|
|
|
|
Delay_ms(200);
|
2026-07-15 16:14:30 +08:00
|
|
|
|
|
2026-07-15 17:26:50 +08:00
|
|
|
|
// 重做屏控制器 RM69310 寄存器组 of 初始化
|
|
|
|
|
|
LCD_Init();
|
2026-07-15 16:14:30 +08:00
|
|
|
|
|
2026-07-15 17:26:50 +08:00
|
|
|
|
// 重新开启 Timer1
|
|
|
|
|
|
ET1 = 1;
|
|
|
|
|
|
inactivity_timer = 0;
|
2026-07-15 16:14:30 +08:00
|
|
|
|
|
2026-07-15 17:26:50 +08:00
|
|
|
|
// 绘制时钟主界面
|
2026-07-15 17:05:22 +08:00
|
|
|
|
current_state = STATE_NORMAL;
|
|
|
|
|
|
UI_ShowClockPage(current_state, current_hour, current_min);
|
2026-07-15 17:26:50 +08:00
|
|
|
|
Uart_SendString("[SYS] Wakeup restored by Key!\r\n");
|
|
|
|
|
|
return 1; // 真实唤醒
|
2026-07-15 17:05:22 +08:00
|
|
|
|
}
|
2026-07-15 17:26:50 +08:00
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
// 射频外部中断或者 WKT 唤醒,保持屏幕 SGM_CTRL=0 关闭状态,避免升压干扰射频
|
|
|
|
|
|
Uart_SendString("[WR] Woken by RF/WKT, decoding...\r\n");
|
|
|
|
|
|
SGM_CTRL = 0;
|
|
|
|
|
|
|
|
|
|
|
|
// 尝试解码 150ms 射频包
|
|
|
|
|
|
for (rf_check_ms = 0; rf_check_ms < 150; rf_check_ms++)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (EV1527_Decode(&rx_addr, &rx_data))
|
|
|
|
|
|
{
|
|
|
|
|
|
u8 slot;
|
|
|
|
|
|
if (Check_Sensor_ID(rx_addr, &slot))
|
|
|
|
|
|
{
|
|
|
|
|
|
// 找到了匹配的已配对传感器
|
|
|
|
|
|
if (sensor_list[slot].zone == 0 || current_state == STATE_ARMED)
|
|
|
|
|
|
{
|
|
|
|
|
|
rf_valid = 1;
|
|
|
|
|
|
captured_addr = rx_addr;
|
|
|
|
|
|
alarm_sensor_slot = slot;
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
Delay_ms(1);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 采集完/超时后,立即关闭射频接收芯片,杜绝乱输出的噪底电平
|
|
|
|
|
|
RF_SetMode(0);
|
|
|
|
|
|
|
|
|
|
|
|
if (rf_valid)
|
|
|
|
|
|
{
|
|
|
|
|
|
// 真实报警信号唤醒:开启屏幕,显示报警画面
|
|
|
|
|
|
Uart_SendString("[WR] Valid Alarm RF Decoded! Address=0x");
|
|
|
|
|
|
Uart_SendHex32(captured_addr);
|
|
|
|
|
|
Uart_SendString("\r\n");
|
|
|
|
|
|
|
|
|
|
|
|
// 启动 SGM3833 并使能升压
|
|
|
|
|
|
SGM_CTRL = 1;
|
|
|
|
|
|
SGM_SendPulse(27);
|
|
|
|
|
|
Delay_ms(200);
|
|
|
|
|
|
LCD_Init();
|
|
|
|
|
|
|
|
|
|
|
|
// 重新开启 Timer1
|
|
|
|
|
|
ET1 = 1;
|
|
|
|
|
|
inactivity_timer = 0;
|
|
|
|
|
|
|
|
|
|
|
|
// 进入报警 App
|
|
|
|
|
|
AppManager_StartApp(APP_ID_ALARM);
|
|
|
|
|
|
return 1; // 真实唤醒
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
// 伪唤醒(杂波引起的误触发,或未注册传感器):不开启屏幕,返回 0 以便主循环重新进入休眠
|
|
|
|
|
|
Uart_SendString("[WR] RF Noise or Unregistered signal, back to sleep...\r\n");
|
2026-07-15 17:05:22 +08:00
|
|
|
|
|
2026-07-15 17:26:50 +08:00
|
|
|
|
// 重新开启 Timer1
|
|
|
|
|
|
ET1 = 1;
|
|
|
|
|
|
return 0; // 假唤醒,重新进入 Power-Down
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// STC32G INT2 外部中断服务子程序 (向量 10)
|
|
|
|
|
|
// 用于从 Power-Down 模式中由射频数据脚下降沿唤醒 CPU
|
|
|
|
|
|
void INT2_Isr(void) interrupt 10
|
|
|
|
|
|
{
|
|
|
|
|
|
EX2 = 0; // 唤醒后立即关闭外部中断,避免噪底电平在唤醒后反复触发中断
|
2026-07-15 16:14:30 +08:00
|
|
|
|
}
|