Fix RF noise wake-up bug by sleeping with EA=0 and checking flags directly
This commit is contained in:
@@ -152,9 +152,6 @@ extern volatile u16 key_confirm_hold;
|
|||||||
extern volatile u16 key_sos_hold;
|
extern volatile u16 key_sos_hold;
|
||||||
extern volatile u16 comb_hold;
|
extern volatile u16 comb_hold;
|
||||||
|
|
||||||
extern volatile u8 isr_p0_flag;
|
|
||||||
extern volatile u8 isr_p2_flag;
|
|
||||||
|
|
||||||
#define MAIN_Fosc 24000000UL
|
#define MAIN_Fosc 24000000UL
|
||||||
#define CLONED_ADDR 0x37A86UL
|
#define CLONED_ADDR 0x37A86UL
|
||||||
|
|
||||||
|
|||||||
11
App/main.c
11
App/main.c
@@ -38,9 +38,6 @@ volatile u16 key_confirm_hold = 0;
|
|||||||
volatile u16 key_sos_hold = 0;
|
volatile u16 key_sos_hold = 0;
|
||||||
volatile u16 comb_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 跳转至此)
|
// Port0 中断服务函数 (由 isr_jump.asm 从向量 37 @ 0x012BH 跳转至此)
|
||||||
void Port0_Isr(void) interrupt 13
|
void Port0_Isr(void) interrupt 13
|
||||||
{
|
{
|
||||||
EAXFR = 1;
|
|
||||||
isr_p0_flag = P0INTF;
|
|
||||||
P0INTF = 0x00; // 清除 P0 端口中断悬挂标志
|
|
||||||
P0INTE = 0x00; // 立即禁用,防止低电平保持期间反复触发
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Port2 中断服务函数 (由 isr_jump.asm 从向量 39 @ 0x013BH 跳转至此)
|
// Port2 中断服务函数 (由 isr_jump.asm 从向量 39 @ 0x013BH 跳转至此)
|
||||||
void Port2_Isr(void) interrupt 15
|
void Port2_Isr(void) interrupt 15
|
||||||
{
|
{
|
||||||
EAXFR = 1;
|
|
||||||
isr_p2_flag = P2INTF;
|
|
||||||
P2INTF = 0x00; // 清除 P2 端口中断悬挂标志
|
|
||||||
P2INTE = 0x00; // 立即禁用,防止低电平保持期间反复触发
|
|
||||||
}
|
}
|
||||||
|
|||||||
24
App/system.c
24
App/system.c
@@ -254,9 +254,9 @@ void Enter_Low_Power_Sleep(void)
|
|||||||
P0INTF = 0x00;
|
P0INTF = 0x00;
|
||||||
P2INTF = 0x00;
|
P2INTF = 0x00;
|
||||||
|
|
||||||
// 11. 关闭 Timer1 中断,保持 EA=1 让端口中断能唤醒
|
// 11. 关闭 Timer1 中断,将 EA 置 0,通过硬件唤醒直接向下执行
|
||||||
ET1 = 0;
|
ET1 = 0;
|
||||||
EA = 1;
|
EA = 0;
|
||||||
|
|
||||||
// 12. 写入 PCON 掉电模式位,使 MCU 进入深度 Power-Down 挂起状态
|
// 12. 写入 PCON 掉电模式位,使 MCU 进入深度 Power-Down 挂起状态
|
||||||
while (1) {
|
while (1) {
|
||||||
@@ -267,7 +267,7 @@ void Enter_Low_Power_Sleep(void)
|
|||||||
_nop_();
|
_nop_();
|
||||||
_nop_();
|
_nop_();
|
||||||
|
|
||||||
// 13. 唤醒并执行完 ISR 后,CPU 从这里继续执行,如果是真唤醒,则打破挂起循环
|
// 13. 唤醒后直接从这里继续执行,如果是真唤醒,则打破挂起循环
|
||||||
if (Wakeup_Restore() == 1) {
|
if (Wakeup_Restore() == 1) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -283,11 +283,9 @@ u8 Wakeup_Restore(void)
|
|||||||
// 确保 EAXFR=1 才能访问扩展 SFR (P0INTF/P2INTF/P0INTE/P2INTE)
|
// 确保 EAXFR=1 才能访问扩展 SFR (P0INTF/P2INTF/P0INTE/P2INTE)
|
||||||
EAXFR = 1;
|
EAXFR = 1;
|
||||||
|
|
||||||
// 读取并重置 ISR 中存下来的真实中断源,同时也要读取当前的寄存器以备万一
|
// 直接读取当前的真实悬挂标志
|
||||||
actual_p0 = isr_p0_flag | P0INTF;
|
actual_p0 = P0INTF;
|
||||||
actual_p2 = isr_p2_flag | P2INTF;
|
actual_p2 = P2INTF;
|
||||||
isr_p0_flag = 0;
|
|
||||||
isr_p2_flag = 0;
|
|
||||||
|
|
||||||
// 1. 立即禁用端口中断和唤醒,防止继续触发
|
// 1. 立即禁用端口中断和唤醒,防止继续触发
|
||||||
P0INTE = 0x00;
|
P0INTE = 0x00;
|
||||||
@@ -302,10 +300,6 @@ u8 Wakeup_Restore(void)
|
|||||||
WKTCH = 0x00;
|
WKTCH = 0x00;
|
||||||
WKTCL = 0x00;
|
WKTCL = 0x00;
|
||||||
|
|
||||||
// 2. 重新开启全局中断与 Timer1 中断
|
|
||||||
EA = 1;
|
|
||||||
ET1 = 1;
|
|
||||||
|
|
||||||
// [诊断] 打印唤醒来源
|
// [诊断] 打印唤醒来源
|
||||||
if (actual_p0 & 0x0E) {
|
if (actual_p0 & 0x0E) {
|
||||||
Uart_SendString("[WR] Woken by KEY P0 (P0INTF=0x");
|
Uart_SendString("[WR] Woken by KEY P0 (P0INTF=0x");
|
||||||
@@ -329,8 +323,7 @@ u8 Wakeup_Restore(void)
|
|||||||
u32 rx_addr;
|
u32 rx_addr;
|
||||||
u8 rx_data;
|
u8 rx_data;
|
||||||
|
|
||||||
// 关闭全局中断进行解调,防止滴答中断干扰高精度脉宽采集
|
// 全速尝试解调,由于 EA 此时仍为 0,不受滴答定时器干扰
|
||||||
EA = 0;
|
|
||||||
for (i = 0; i < 6; i++) {
|
for (i = 0; i < 6; i++) {
|
||||||
if (EV1527_Decode(&rx_addr, &rx_data)) {
|
if (EV1527_Decode(&rx_addr, &rx_data)) {
|
||||||
u8 slot;
|
u8 slot;
|
||||||
@@ -349,10 +342,9 @@ u8 Wakeup_Restore(void)
|
|||||||
}
|
}
|
||||||
Delay_ms(20);
|
Delay_ms(20);
|
||||||
}
|
}
|
||||||
EA = 1;
|
|
||||||
|
|
||||||
if (!decoded) {
|
if (!decoded) {
|
||||||
// 只是噪声或未配对的遥控器,无视,不亮屏直接返回 0 让主休眠循环继续挂起
|
// 只是噪声或未配对的遥控器,无视,不亮屏直接返回 0 让主休眠循环继续挂起(保持 EA = 0)
|
||||||
Uart_SendString("[WR] RF false alarm/noise. Re-sleeping.\r\n");
|
Uart_SendString("[WR] RF false alarm/noise. Re-sleeping.\r\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user