2026-07-09 17:42:55 +08:00
|
|
|
|
# 编码实现 - 电源管理与休眠唤醒 (Docs/60_coding/mod-power.md)
|
2026-07-09 10:31:36 +08:00
|
|
|
|
|
2026-07-09 17:42:55 +08:00
|
|
|
|
本文件对应低功耗休眠、关屏切断 PMIC 以及外部中断唤醒的具体编码实现。
|
2026-07-09 10:31:36 +08:00
|
|
|
|
|
|
|
|
|
|
## 1. 对应代码源文件
|
|
|
|
|
|
|
2026-07-09 17:42:55 +08:00
|
|
|
|
* [App/main.c](file:///c:/workfile/105/stc32g12k128/App/main.c) (定义电源控制引脚使能、超时判断及进入 Power-Down 和中断唤醒的实现)
|
2026-07-09 10:31:36 +08:00
|
|
|
|
|
|
|
|
|
|
## 2. 关键代码片段与逻辑实现
|
|
|
|
|
|
|
2026-07-09 17:42:55 +08:00
|
|
|
|
### 2.1 供电引脚初始化
|
2026-07-10 10:04:40 +08:00
|
|
|
|
系统初始化时,配置 `SHUT`(控制 SGM3833 供电的引脚 `P2.7`)为推挽输出,并拉高以打开屏幕供电:
|
2026-07-09 10:31:36 +08:00
|
|
|
|
```c
|
2026-07-10 10:04:40 +08:00
|
|
|
|
sbit SHUT = P2^7; // Pin 28
|
2026-07-09 17:42:55 +08:00
|
|
|
|
|
2026-07-09 13:06:01 +08:00
|
|
|
|
void Power_Init(void) {
|
2026-07-10 10:04:40 +08:00
|
|
|
|
// P2.7 (SHUT) 配置为推挽输出
|
|
|
|
|
|
P2M1 &= ~(1 << 7);
|
|
|
|
|
|
P2M0 |= (1 << 7);
|
2026-07-09 10:31:36 +08:00
|
|
|
|
|
2026-07-09 17:42:55 +08:00
|
|
|
|
// 拉高引脚,开启 SGM3833 负压供电
|
2026-07-10 10:04:40 +08:00
|
|
|
|
SHUT = 1;
|
2026-07-09 17:42:55 +08:00
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### 2.2 进入低功耗睡眠 (Enter_Low_Power_Sleep)
|
|
|
|
|
|
在 10 秒无按键操作发生后,关闭屏幕显示,断电,配置中断,并进入 Power-Down 挂起状态:
|
|
|
|
|
|
```c
|
|
|
|
|
|
void Enter_Low_Power_Sleep(void) {
|
|
|
|
|
|
// 1. 给 AMOLED 发送 Sleep In 命令
|
|
|
|
|
|
LCD_WriteCmd(0x10);
|
|
|
|
|
|
|
|
|
|
|
|
// 2. 切断 SGM3833 电源,停止输出负压
|
2026-07-10 10:04:40 +08:00
|
|
|
|
SHUT = 0;
|
2026-07-09 17:42:55 +08:00
|
|
|
|
|
2026-07-10 10:04:40 +08:00
|
|
|
|
// 3. 配置引脚中断 (P2.0, P2.3, P3.6, P3.7) 允许唤醒
|
|
|
|
|
|
// 允许 P2 / P3 端口中断以供按键唤醒
|
|
|
|
|
|
P2IM1 &= ~0x09; P2IM0 &= ~0x09; P2INTE |= 0x09; // P2.0 (UP), P2.3 (SOS)
|
|
|
|
|
|
P3IM1 &= ~0xC0; P3IM0 &= ~0xC0; P3INTE |= 0xC0; // P3.6 (DOWN), P3.7 (CONFIRM)
|
2026-07-09 17:42:55 +08:00
|
|
|
|
|
2026-07-10 10:04:40 +08:00
|
|
|
|
// 4. 配置射频接收脚 P0.0 (RF_RX_DATA) 为 INT2/外部中断 2 唤醒
|
2026-07-09 17:42:55 +08:00
|
|
|
|
EX2 = 1; // 使能外部中断2
|
|
|
|
|
|
|
|
|
|
|
|
// 5. 写入 PCON.1 使单片机进入 Power-Down 深度睡眠状态
|
|
|
|
|
|
PCON |= 0x02; // MCU 挂起,主时钟停振,直到外部中断唤醒
|
|
|
|
|
|
_nop_();
|
|
|
|
|
|
_nop_();
|
2026-07-09 10:31:36 +08:00
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
2026-07-09 17:42:55 +08:00
|
|
|
|
### 2.3 中断唤醒与恢复 (Wakeup_Restore)
|
|
|
|
|
|
当产生按键或射频中断后,单片机被唤醒,首先执行外部中断 ISR,退出低功耗并重新使能 OLED:
|
|
|
|
|
|
```c
|
2026-07-10 10:04:40 +08:00
|
|
|
|
// 外部中断服务子程序 (以按键 P3 端口中断为例)
|
|
|
|
|
|
void Port3_Isr(void) interrupt 38 {
|
|
|
|
|
|
P3INTF = 0x00; // 清除 P3 中断标志
|
2026-07-09 17:42:55 +08:00
|
|
|
|
Wakeup_Restore();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void Wakeup_Restore(void) {
|
2026-07-10 10:04:40 +08:00
|
|
|
|
if (SHUT == 1) return; // 已经在工作状态,直接返回
|
2026-07-09 17:42:55 +08:00
|
|
|
|
|
2026-07-10 10:04:40 +08:00
|
|
|
|
// 1. 拉高 SHUT 重新使能 SGM3833 供电
|
|
|
|
|
|
SHUT = 1;
|
2026-07-09 17:42:55 +08:00
|
|
|
|
|
|
|
|
|
|
// 2. 延时约 50ms 等待升压/负压输出稳定
|
|
|
|
|
|
Delay50ms();
|
|
|
|
|
|
|
|
|
|
|
|
// 3. 重新对 RM69310 屏幕控制器做初始化序列
|
|
|
|
|
|
LCD_Init();
|
|
|
|
|
|
|
|
|
|
|
|
// 4. 重置无按键操作的超时计时器
|
|
|
|
|
|
inactivity_timer = 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
2026-07-09 11:03:18 +08:00
|
|
|
|
|
2026-07-09 17:42:55 +08:00
|
|
|
|
<!-- Checked and verified with SGM3833 boost/inverting PMIC removal and LCD_PWR_CTRL update changes V2 -->
|