Compare commits
2 Commits
d01121e3ae
...
d7cb2ae37f
| Author | SHA1 | Date | |
|---|---|---|---|
| d7cb2ae37f | |||
| 8367524eec |
@@ -184,6 +184,9 @@ void main(void)
|
||||
/* 步骤 2+5: 初始化应用管理器并登记所有前台应用,默认加载 ClockApp */
|
||||
AppManager_Init();
|
||||
|
||||
/* 启动并挂载后台射频监控应用,开始侦听无线传感器信号 */
|
||||
AppManager_AttachToBackground(&rf_monitor_app);
|
||||
|
||||
/* 启动 1ms 系统基准定时器 Timer1 */
|
||||
Timer1_Init();
|
||||
|
||||
@@ -219,6 +222,8 @@ void main(void)
|
||||
inactivity_timer = 0;
|
||||
current_state = STATE_SLEEP; // 系统置为休眠状态
|
||||
Enter_Low_Power_Sleep(); // 该函数是阻塞的,MCU 将在此挂起。唤醒后将自动从其后继续执行
|
||||
current_state = STATE_NORMAL; // 唤醒后重新置为正常待机状态
|
||||
AppManager_StartApp(APP_ID_CLOCK); // 重新开启时钟应用以刷新画面和背光
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
126
App/system.c
126
App/system.c
@@ -271,7 +271,7 @@ void Power_Off(void)
|
||||
MOTOR = 0;
|
||||
|
||||
// 关断屏幕背光与 RGB 灯光
|
||||
SGM_CTRL = 0;
|
||||
SGM_CTRL = 1; // 高电平断电,关闭背光灭屏
|
||||
RGB_Send(0, 0, 0, 0, 0, 0);
|
||||
|
||||
// 拉低 PWR_HOLD 切断电源锁存使总电源关闭
|
||||
@@ -288,15 +288,81 @@ void Power_Off(void)
|
||||
*/
|
||||
void Enter_Low_Power_Sleep(void)
|
||||
{
|
||||
Uart_SendString("[SYS] Entering Sleep mode...\r\n");
|
||||
SGM_CTRL = 0; // 熄灭背光
|
||||
Uart_SendString("[SYS] Entering low power sleep...\r\n");
|
||||
|
||||
// 1. 关闭/熄灭 RGB 灯
|
||||
RGB_Send(0, 0, 0, 0, 0, 0);
|
||||
|
||||
// 配置 PCON 挂起单片机
|
||||
PCON |= 0x02; // PD = 1 掉电停机模式
|
||||
// 2. 向 LCD 芯片写入 Display OFF 指令 (0x28) 关显示
|
||||
WriteComm(0x28);
|
||||
Delay_ms(20);
|
||||
|
||||
// 3. 向 LCD 芯片写入 Sleep In 指令 (0x10) 关内部电荷泵
|
||||
WriteComm(0x10);
|
||||
Delay_ms(20);
|
||||
|
||||
// 4. 关闭背光(高电平断电,关闭背光灭屏)
|
||||
SGM_CTRL = 1;
|
||||
|
||||
// 5. 屏幕接口防漏电处理
|
||||
LCD_CS = 1;
|
||||
LCD_RST = 1;
|
||||
LCD_DCX = 0;
|
||||
LCD_SCL = 0;
|
||||
LCD_SDI = 0;
|
||||
|
||||
// 6. 射频设置为关闭接收模式(低功耗,SHUT=0, RF_SetMode(0))
|
||||
RF_SetMode(0);
|
||||
|
||||
// 使能访问扩展特殊功能寄存器
|
||||
P_SW2 |= 0x80;
|
||||
|
||||
// 7. 配置 Port0 中断唤醒源 (KEY_UP=P0.1, KEY_CONFIRM=P0.2, KEY_DOWN=P0.3)
|
||||
P0IM1 |= 0x0E;
|
||||
P0IM0 &= ~0x0E; // 下降沿触发
|
||||
P0INTF = 0x00; // 清除挂起的中断标志
|
||||
P0INTE |= 0x0E; // 开启 P0.1, P0.2, P0.3 中断允许
|
||||
P0WKUE |= 0x0E; // 使能 P0.1, P0.2, P0.3 掉电唤醒
|
||||
|
||||
// 8. 配置 Port2 中断唤醒源 (SOS=P2.6)
|
||||
P2IM1 |= 0x40;
|
||||
P2IM0 &= ~0x40; // 下降沿触发
|
||||
P2INTF = 0x00; // 清除挂起标志
|
||||
P2INTE |= 0x40; // 开启 P2.6 中断允许
|
||||
P2WKUE |= 0x40; // 使能 P2.6 掉电唤醒
|
||||
|
||||
// 9. 配置 Port3 中断唤醒源 (RF_RX_DATA=P3.6)
|
||||
P3IM1 |= 0x40;
|
||||
P3IM0 |= 0x40; // 双边沿触发
|
||||
P3INTF = 0x00; // 清除挂起标志
|
||||
P3INTE |= 0x40; // 开启 P3.6 中断允许
|
||||
P3WKUE |= 0x40; // 使能 P3.6 掉电唤醒
|
||||
|
||||
// 确保引脚上拉和输入使能,防止因浮空产生的功耗泄漏
|
||||
P2PU |= 0x40;
|
||||
P2IE |= 0x40;
|
||||
P3PU &= ~0x40;
|
||||
P3IE |= 0x40;
|
||||
|
||||
// 清零各个唤醒检测标志位
|
||||
P0INTF = 0x00;
|
||||
P2INTF = 0x00;
|
||||
P3INTF = 0x00;
|
||||
|
||||
p0_wakeup_flag = 0;
|
||||
p2_wakeup_flag = 0;
|
||||
p3_wakeup_flag = 0;
|
||||
rf_wakeup_flag = 0;
|
||||
|
||||
// 10. 关闭系统滴答定时器 Timer1 中断,防止休眠时被定时器误唤醒
|
||||
ET1 = 0;
|
||||
EA = 1; // 开启全局中断
|
||||
|
||||
// 配置 PCON 挂起单片机,切入停机 (Power Down) 模式
|
||||
PCON |= 0x02; // PD = 1
|
||||
_nop_(); _nop_(); _nop_(); _nop_();
|
||||
|
||||
// 被唤醒后继续执行
|
||||
// ====== 被外部中断唤醒后,在此处继续运行 ======
|
||||
Wakeup_Restore();
|
||||
}
|
||||
|
||||
@@ -305,8 +371,52 @@ void Enter_Low_Power_Sleep(void)
|
||||
*/
|
||||
void Wakeup_Restore(void)
|
||||
{
|
||||
SGM_CTRL = 1; // 恢复背光
|
||||
Uart_SendString("[SYS] System Woken Up!\r\n");
|
||||
EAXFR = 1;
|
||||
// 1. 立即关闭所有掉电外部中断允许与唤醒允许,防止重入
|
||||
P0INTE = 0x00;
|
||||
P2INTE = 0x00;
|
||||
P3INTE = 0x00;
|
||||
P0WKUE = 0x00;
|
||||
P2WKUE = 0x00;
|
||||
P3WKUE = 0x00;
|
||||
P0INTF = 0x00;
|
||||
P2INTF = 0x00;
|
||||
P3INTF = 0x00;
|
||||
|
||||
// 2. 清零掉电唤醒定时器
|
||||
WKTCH = 0x00;
|
||||
WKTCL = 0x00;
|
||||
|
||||
// 3. 开启全局中断并重启系统滴答定时器
|
||||
EA = 1;
|
||||
ET1 = 1;
|
||||
|
||||
// 4. 恢复射频芯片工作模式
|
||||
RF_SetMode(1);
|
||||
|
||||
// 打印唤醒调试日志
|
||||
if ((p0_wakeup_flag & 0x0E) || (p2_wakeup_flag & 0x40)) {
|
||||
Uart_SendString("[WR] Woken by KEY (P0=");
|
||||
Uart_SendHex8(p0_wakeup_flag);
|
||||
Uart_SendString(", P2=");
|
||||
Uart_SendHex8(p2_wakeup_flag);
|
||||
Uart_SendString(")\r\n");
|
||||
} else if ((p3_wakeup_flag & 0x40) || rf_wakeup_flag) {
|
||||
rf_wakeup_flag = 1;
|
||||
Uart_SendString("[WR] Woken by RF (P3.6)!\r\n");
|
||||
} else {
|
||||
Uart_SendString("[WR] Woken by TIMER/Other\r\n");
|
||||
}
|
||||
|
||||
// 5. 恢复屏幕供电与背光(低电平上电,恢复背光亮屏)
|
||||
SGM_CTRL = 0;
|
||||
|
||||
// 6. 延时 200ms 等待液晶稳压板上电稳定后,重新对 LCD 寄存器初始化
|
||||
Delay_ms(200);
|
||||
LCD_Init();
|
||||
|
||||
// 7. 充零闲置计时器
|
||||
inactivity_timer = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user