Fix RF noise wake-up bug by sleeping with EA=0 and checking flags directly

This commit is contained in:
Antigravity IDE
2026-07-15 17:16:56 +08:00
parent 601e01e954
commit 7292fd0fcb
3 changed files with 8 additions and 30 deletions

View File

@@ -152,9 +152,6 @@ extern volatile u16 key_confirm_hold;
extern volatile u16 key_sos_hold;
extern volatile u16 comb_hold;
extern volatile u8 isr_p0_flag;
extern volatile u8 isr_p2_flag;
#define MAIN_Fosc 24000000UL
#define CLONED_ADDR 0x37A86UL

View File

@@ -38,9 +38,6 @@ volatile u16 key_confirm_hold = 0;
volatile u16 key_sos_hold = 0;
volatile u16 comb_hold = 0;
volatile u8 isr_p0_flag = 0;
volatile u8 isr_p2_flag = 0;
/* =========================================================================
* 串口调试指令解析与事件派发封装
* ========================================================================= */
@@ -197,17 +194,9 @@ void main(void)
// Port0 中断服务函数 (由 isr_jump.asm 从向量 37 @ 0x012BH 跳转至此)
void Port0_Isr(void) interrupt 13
{
EAXFR = 1;
isr_p0_flag = P0INTF;
P0INTF = 0x00; // 清除 P0 端口中断悬挂标志
P0INTE = 0x00; // 立即禁用,防止低电平保持期间反复触发
}
// Port2 中断服务函数 (由 isr_jump.asm 从向量 39 @ 0x013BH 跳转至此)
void Port2_Isr(void) interrupt 15
{
EAXFR = 1;
isr_p2_flag = P2INTF;
P2INTF = 0x00; // 清除 P2 端口中断悬挂标志
P2INTE = 0x00; // 立即禁用,防止低电平保持期间反复触发
}

View File

@@ -254,9 +254,9 @@ void Enter_Low_Power_Sleep(void)
P0INTF = 0x00;
P2INTF = 0x00;
// 11. 关闭 Timer1 中断,保持 EA=1 让端口中断能唤醒
// 11. 关闭 Timer1 中断, EA 置 0通过硬件唤醒直接向下执行
ET1 = 0;
EA = 1;
EA = 0;
// 12. 写入 PCON 掉电模式位,使 MCU 进入深度 Power-Down 挂起状态
while (1) {
@@ -267,7 +267,7 @@ void Enter_Low_Power_Sleep(void)
_nop_();
_nop_();
// 13. 唤醒并执行完 ISR 后CPU 从这里继续执行,如果是真唤醒,则打破挂起循环
// 13. 唤醒后直接从这里继续执行,如果是真唤醒,则打破挂起循环
if (Wakeup_Restore() == 1) {
break;
}
@@ -283,11 +283,9 @@ u8 Wakeup_Restore(void)
// 确保 EAXFR=1 才能访问扩展 SFR (P0INTF/P2INTF/P0INTE/P2INTE)
EAXFR = 1;
// 读取并重置 ISR 中存下来的真实中断源,同时也要读取当前的寄存器以备万一
actual_p0 = isr_p0_flag | P0INTF;
actual_p2 = isr_p2_flag | P2INTF;
isr_p0_flag = 0;
isr_p2_flag = 0;
// 直接读取当前的真实悬挂标志
actual_p0 = P0INTF;
actual_p2 = P2INTF;
// 1. 立即禁用端口中断和唤醒,防止继续触发
P0INTE = 0x00;
@@ -302,10 +300,6 @@ u8 Wakeup_Restore(void)
WKTCH = 0x00;
WKTCL = 0x00;
// 2. 重新开启全局中断与 Timer1 中断
EA = 1;
ET1 = 1;
// [诊断] 打印唤醒来源
if (actual_p0 & 0x0E) {
Uart_SendString("[WR] Woken by KEY P0 (P0INTF=0x");
@@ -329,8 +323,7 @@ u8 Wakeup_Restore(void)
u32 rx_addr;
u8 rx_data;
// 关闭全局中断进行解调,防止滴答中断干扰高精度脉宽采集
EA = 0;
// 全速尝试解调,由于 EA 此时仍为 0不受滴答定时器干扰
for (i = 0; i < 6; i++) {
if (EV1527_Decode(&rx_addr, &rx_data)) {
u8 slot;
@@ -349,10 +342,9 @@ u8 Wakeup_Restore(void)
}
Delay_ms(20);
}
EA = 1;
if (!decoded) {
// 只是噪声或未配对的遥控器,无视,不亮屏直接返回 0 让主休眠循环继续挂起
// 只是噪声或未配对的遥控器,无视,不亮屏直接返回 0 让主休眠循环继续挂起(保持 EA = 0
Uart_SendString("[WR] RF false alarm/noise. Re-sleeping.\r\n");
return 0;
}