APM32 MCU 低功耗模式全解析:Stop 与 Standby 模式的内核原理、外设状态及唤醒机制对比
本文深入剖析了APM32 MCU的两种低功耗模式:Stop模式和Standby模式。Stop模式通过关闭主系统时钟但保持SRAM供电,实现快速唤醒(约5μs)和程序继续执行,适用于短时休眠场景,典型功耗1.2μA。Standby模式则完全断电SRAM,系统复位后从头执行,实现极限低功耗(0.3μA),适合长时间待机。文章详细解释了两种模式的进入/退出机制、外设状态差异,特别是无时钟情况下GPIO中
在嵌入式系统设计中,功耗管理是非常重要的课题。尤其是基于 APM32(微控制单元)的设备,如何在保证功能的前提下尽可能降低功耗,是设计的关键。APM32 通常提供多种低功耗模式,常见的有 Stop 模式 和 Standby 模式。这两种模式都能极大降低功耗,但它们的工作机制、外设状态、数据保存方式和唤醒行为有显著差异。
本文围绕以下问题展开:
- 进入及退出低功耗模式的内核原理是什么?
- Stop 模式下,所有外设都停了吗?哪些外设还能跑?为什么这些外设还能跑?
- Standby 模式下 CPU 是否停了?进入 Stop 和 Standby 模式前,数据保存情况有何不同?为什么?
- 两种模式的进入机制和原理是否不同?
- Stop 模式唤醒后为何能继续执行,而 Standby 模式唤醒后为何从头开始?
- Stop 模式下 HSE/HSI 都关了,GPIO 外部中断这种形式是怎么触发的?时钟都关了,这玩意儿还有中断能够触发?
通过对这些问题的详细剖析,帮助大家全面理解 APM32 MCU 低功耗设计的核心逻辑,从“会用”到“真懂”,从“抄例程”到“自主优化”。
一、APM32 MCU 低功耗模式的基本原理
1. 低功耗模式的核心思想:动态功耗 = 翻转 × 频率 × 电压²
MCU 的功耗主要来自 时钟驱动的电路活动,包括:
- CPU 的指令执行(每条指令 → 寄存器翻转);
- 外设时钟(UART、SPI、ADC 等);
- 总线活动(AHB/APB 桥);
- 模拟模块(PLL、LDO);
可以这么说:
芯片就像个大工厂,时钟就是电铃。
电铃一响,所有工人(电路)开始干活,翻转开关 → 耗电。
关掉电铃 = 关时钟 = 省大电。
降低功耗的核心方法是 关闭或降低时钟频率,减少电路切换,从而降低 动态功耗(P = C × V² × f)。
低功耗模式通过以下手段实现节能:
| 手段 | 效果 |
|---|---|
| 关闭系统时钟(HSE/HSI/PLL) | 动态功耗 ≈ 0 |
| 降低内核电压(LDO 低功耗模式) | 静态功耗 ↓ |
| 关闭外设时钟门控 | 外设不翻转 |
| 断电 SRAM(仅 Standby) | 漏电 ↓ |
不同模式对应不同的 功耗与功能保留程度,是“鱼与熊掌”的权衡。
2. 进入及退出低功耗模式的内核原理(WFI/WFE + SLEEPDEEP + PMU 握手机制)
一句话说清:
WFI是“暂停键”,SLEEPDEEP是“深睡开关”,PMU 是“执行者”——三者配合,决定是“暂停电影”还是“关机重启”。
2.1 进入低功耗模式(汇编级 + 硬件握手)
-
软件配置
PMU->CTRL1.PDDSCFG = 1; // Standby: 断电;0: 仅停时钟 SCB->SCR.SLEEPDEEP = 1; // 通知内核:可进入 Deep Sleep -
触发指令(ARM Cortex-M 汇编行为)
WFI ; 0xBF20 → 暂停取指,等待 NVIC 中断 ; 或 WFE ; 0xBF22 → 等待事件(SEVONPEND 控制)WFI:CPU 停止取指,但 PC 指针保持。WFE:支持事件唤醒,多用于多核同步。
-
内核响应
SLEEPDEEP=1→ 内核通知 PMU:可以关闭时钟/断电。- PMU 执行:
- Stop:关闭 HSE/HSI/PLL,SRAM 保持。
- Standby:关闭 LDO,SRAM 断电。
2.2 退出低功耗模式(中断 vs 复位路径)
| 模式 | 唤醒源 | 路径 | 执行点 |
|---|---|---|---|
| Stop | EINT / RTC | NVIC 中断 | __WFI() 下一条指令 |
| Standby | WKUP / RTC | POR 复位 | ResetHandler → main() |
关键区别:
- Stop:程序流不中断,变量保留。
- Standby:系统重启,需重新初始化。
一句话总结:
WFI暂停 CPU,SLEEPDEEP授权 PMU,PDDSCFG决定断不断电 —— 三者缺一不可。
二、Stop 模式详解
1. Stop 模式下 CPU 与外设状态
| 项目 | 状态 | 说明 |
|---|---|---|
| CPU 状态 | 时钟停止,指令暂停 | 进入Deep Sleep,PC 指针保持 |
| 主系统时钟 | HSE/HSI/PLL 全关 | 动态功耗为 0 |
| 外设时钟 | 部分关闭,部分独立运行 | 依赖低速时钟源 |
| 内存状态 | SRAM 和寄存器保持 | 全局变量、栈不丢失 |
2. 哪些外设可以继续运行?(详细表格)
| 外设类型 | 运行状态 | 时钟源 | 说明 |
|---|---|---|---|
| RTC | 继续运行 | LSE (32.768kHz) / LSI (~32kHz) | 保持时间计数,可闹钟唤醒 |
| 低功耗定时器 (LPTIM) | 继续运行 | LSI / LSE | 支持定时唤醒 |
| 外部中断 (EINT) | 继续监控(异步) | 无时钟 | 关键!无时钟也能触发 |
| GPIO | 状态保持 | VDD 直供 | 可配置为唤醒源 |
| IWDG | 可运行 | LSI | 看门狗防死机 |
| 备份寄存器 | 保持 | VBAT | 20个 32bit 寄存器 |
| UART/SPI/I2C | 停止 | PCLK | 依赖主时钟 |
| ADC/DAC/TIM | 停止 | PCLK | 高速外设全停 |
3. 为什么 CPU 停了,外设还能跑?(三域分离架构)
芯片不是“一锅粥”,而是分成 三块地盘:
- CPU 地盘:靠主时钟吃饭,停了就睡大觉。
- RTC 地盘:有自己的“小发电机”(LSE/LSI),不靠大电网。
- GPIO 地盘:直接接电池(VDD),门铃一按就响!
图1:APM32 低功耗三域分离架构图
- Core Domain:依赖 HCLK,Stop 模式下时钟关。
- Backup Domain:独立时钟源,永不断电。
- I/O Domain:VDD 直供,模拟电路常开。
4. Stop 模式下 HSE/HSI 都关了,GPIO 外部中断怎么触发?
用户疑问:
“时钟都关了,EINT 怎么知道引脚跳了?这玩意儿时钟都没开怎么工作?”
4.1 打个比方:门铃不靠电表也能响
你家门铃坏了?
- 按钮 = GPIO 引脚;
- 响铃 = EINT 中断;
- 你睡觉时,把家里所有灯(HSE/HSI)都关了,但门铃线路是直通电池的!
- 有人按按钮 → 铃就响,根本不用等电表转(PCLK 采样)!
EINT 就是这个“直通电池的门铃线路”,它不靠 CPU 时钟,而是靠 模拟电路 + 异步触发器 工作。
4.2 EINT 异步唤醒通路全拆解
4.2.1 硬件组成(APM32F407 参考手册 第12.3节)
图2:EINT 异步唤醒通路(无时钟触发原理)
4.2.2 关键模块:Always-On Analog Front-End
| 特性 | 说明 |
|---|---|
| 供电 | VDD Pad 域直供,不经 LDO |
| 工作方式 | 纯模拟电路 + 异步触发 |
| 触发条件 | 边沿变化 → 直接拉高唤醒信号 |
| 无需时钟 | 不依赖 PCLK 采样 |
4.2.3 代码示例:按键唤醒 Stop 模式
void Enter_Stop_With_EINT(void)
{
// 1. 配置 PA0 为外部中断(上升沿)
EINT->RTEN |= EINT_RTEN_RTEN0; // 上升沿触发
EINT->IMASK |= EINT_IMASK_IMASK0; // 使能中断线0
// 2. 使能 PMU 时钟
RCM->APB1CLKEN |= RCM_APB1CLKEN_PMUEN;
// 3. 进入 Stop 模式
PMU->CTRL1 &= ~PMU_CTRL1_PDDSCFG; // 清除 PDDSCFG → Stop
SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
__WFI(); // CPU 暂停,HSE/HSI 全关
}
// EINT0 中断服务函数
void EINT0_IRQHandler(void)
{
if (EINT->SWINTE & EINT_SWINTE_SWINT0)
{
EINT->IPEND = EINT_IPEND_IPEND0; // 清除标志
// CPU 已恢复,从 __WFI() 下一条指令继续
}
}
按键按下 → 异步边沿检测 → 唤醒 CPU → 程序流不中断。
5. Stop 模式的唤醒机制(全流程)
-
唤醒源:RTC Alarm、LPTIM、EINT、USART RX 等。
-
信号路径:
- 外设 → 产生中断请求。
- NVIC → 检测到
SLEEPDEEP=1。 - 触发 时钟恢复序列。
-
恢复顺序:
HSE/HSI 启动 → PLL 锁定 → HCLK 恢复 → CPU 出 Sleep -
执行点:从
__WFI()下一条指令继续
三、Standby 模式详解
1. Standby 模式下 CPU 与外设状态(超详细状态矩阵)
| 项目 | 状态 | 供电来源 | 说明 |
|---|---|---|---|
| CPU 内核 | 完全停止 | Core Domain断电 | 时钟关闭,LDO 进入Standby 模式 |
| SRAM | 断电 | SRAM Domain电源开关关闭 | 数据全部丢失 |
| Flash | 断电 | VDD | 仅保留配置位 |
| 主系统时钟 | 全部关闭 | - | HSE/HSI/PLL/LSI全关(LSI 可选保留) |
| LSE (32.768kHz) | 可选运行 | VBAT / VDD | 唯一可运行的时钟源 |
| RTC | 可运行 | Backup Domain | 闹钟、时间戳、防篡改 |
| 备份寄存器 (BKP) | 保持 | VBAT | 20个 32bit 寄存器,防掉电 |
| WKUP 引脚 | 异步监控 | VDD Pad 域 | PA0、PC13、PC1 等专用唤醒引脚 |
| 普通 GPIO | 状态丢失 | - | 需重新配置 |
| 普通 EINT | 失效 | - | 仅 WKUP 引脚有效 |
| IWDG | 可运行(若预使能) | LSI | 需进入前启动 |
| LPTIM | 停止 | - | 依赖 LSI,Standby 下不可用 |
| UART/SPI/ADC | 全部停止 | - | 寄存器复位 |
关键区别:
Stop 模式是“暂停电影”,Standby 是“关机重启”!
2. 为什么进入 Standby 模式不保存数据?(硅片级漏电分析)
2.1 SRAM 就是个“漏电大户”
假设 SRAM 是一排排 小电容:
- 每存一个
1,电容就充一点电;- 即使不读写,电容也会 慢慢漏电(nA 级);
- 100KB SRAM × 10nA/KB = 1μA 漏电!
Standby 模式直接“拔掉 SRAM 电源” → 漏电 = 0 → 功耗低至 0.3μA!
2.2 电源域断电时序(APM32 内部 PMU 行为)
图3:Standby 模式电源域断电时序图
BackupSRAMPMUCPUBackupSRAMPMUCPU关闭 HSE/HSI/PLL/LSI__WFI() + PDDSCFG=11停止取指2关闭 LDO → 断电3保留 VBAT 供电4进入 Standby (<500nA)5
3. Standby 模式的唤醒机制(全链路拆解)
3.1 唤醒源一览
| 唤醒源 | 类型 | 引脚 | 触发方式 |
|---|---|---|---|
| WKUP1 | 上升沿 | PA0 | 专用唤醒引脚 |
| WKUP2 | 上升沿 | PC13 | 常用于按键 |
| WKUP3 | 上升沿 | PC1 | 可选 |
| RTC Alarm A/B | 定时 | - | 精确到秒 |
| RTC Tamper | 防篡改 | - | 外部入侵检测 |
| RTC TimeStamp | 时间戳 | - | 事件记录 |
| RTC Wakeup Timer | 周期唤醒 | - | 1Hz ~ 32kHz |
3.2 WKUP 引脚的异步检测机制(和 EINT 的区别!)
普通 EINT:Stop 模式下可用,任意 GPIO;
WKUP 引脚:Standby 模式下专用,固定引脚;
硬件原理(类似 EINT,但更“硬核”)
图4:WKUP 引脚 vs 普通 EINT 唤醒路径对比
Standby 模式
Stop 模式
关键区别:
- EINT → 触发 中断 → CPU 继续执行;
- WKUP → 触发 复位 → 系统重启;
3.3 代码示例:RTC 闹钟唤醒 Standby
void Enter_Standby_With_RTC_Alarm(void)
{
// 1. 使能 RTC 时钟
RCM->APB1CLKEN |= RCM_APB1CLKEN_PMUEN;
PMU->CTRL1 |= PMU_CTRL1_BPWEN;
RCM_EnableLSI();
/* Wait till LSE is ready */
while(RCM_ReadStatusFlag(RCM_FLAG_LSIRDY) == RESET)
{
}
/* Select the RTC Clock Source */
RCM_ConfigRTCCLK(RCM_RTCCLK_LSI);
RCM->BDCTRL |= RCM_BDCTRL_RTCCLKEN;
// 2. 配置 RTC 闹钟
RTC->CTRL &= ~RTC_CTRL_ALRAEN; // 禁用闹钟写保护
while(!(RTC->STS & RTC_STS_ALRAW**)); // 等待写就绪
RTC->ALRMAR = 0x00800000;
RTC->CTRL |= RTC_CTRL_ALRAEN | RTC_CTRL_ALRAIEN; // 使能闹钟A + 中断
// 3. 进入 Standby 模式
PMU->CTRL1 |= PMU_CTRL1_PDDSCFG;
SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
__WFI();
}
// RTC 唤醒后:系统复位,进入 main()
int main(void)
{
if (RCM_ReadStatusFlag(RCM_FLAG_LPRRST)) // 检查是否 Standby 唤醒
{
// 从备份寄存器恢复状态
uint32_t state = RTC->BKP0R;
}
SystemClock_Config(); // 必须重新初始化时钟!
GPIO_Init();
// ...
}
4. 备份域(Backup Domain)全景解析
4.1 结构图
图5:Backup Domain 结构图
4.2 关键特性
| 特性 | 说明 |
|---|---|
| 独立供电 | VBAT 电池供电,VDD 掉电不影响 |
| 防写保护 | 需解锁 RTC->WPR |
| 20个用户寄存器 | 32bit,可存状态机、计数器 |
| 篡改检测 | 外部引脚触发,记录时间戳 |
4.3 用备份寄存器保存休眠前状态
// 进入 Standby 前
RTC->BKP0R = system_state;
RTC->BKP1R = error_code;
// 唤醒后(main 中)
if (RCM_ReadStatusFlag(RCM_FLAG_LPRRST))
{
system_state = RTC->BKP0R;
error_code = RTC->BKP1R;
}
5. Standby 唤醒后系统复位全流程(从硬件到软件)
图6:RTC 闹钟唤醒 Standby 完整流程图
标志位判断:
if (RCM_ReadStatusFlag(RCM_FLAG_LPRRST)) // Standby 复位
if (RCM_ReadStatusFlag(RCM_FLAG_PORRST)) // 上电复位
6. 总结:Standby 模式核心逻辑
| 维度 | 关键点 |
|---|---|
| 本质 | 断电重启 |
| 省电原理 | SRAM 断电 + 关闭所有时钟 |
| 唤醒方式 | 复位,非中断 |
| 数据保存 | 仅备份域 |
| 适用场景 | 长时间待机(小时/天/周) |
一句话记住:
Standby = “关机省电,重启干活”。
四、Stop 模式与 Standby 模式对比(扩展表格)
| 特性 | Stop 模式 | Standby 模式 |
|---|---|---|
| CPU 状态 | 暂停(PC 保持) | 完全停止 |
| 主系统时钟 | 关闭 | 关闭 |
| 外设运行 | RTC、LPTIM、EINT 等 | 仅 RTC、WKUP |
| 内存数据 | SRAM 保持 | SRAM 断电 |
| 唤醒源 | 丰富(EINT、RTC、LPTIM 等) | 有限(WKUP、RTC) |
| 唤醒后执行 | 继续执行 | 从头开始 |
| 功耗(典型) | 1.2μA(LSE 开) | 0.3μA |
| 唤醒时间 | ~5μs | ~50μs |
| 适用场景 | 短时休眠,需快速恢复 | 长时间待机,极限省电 |
图7:Stop vs Standby 唤醒后执行流程对比
五、进入及退出两种模式的机制差异
1. 进入机制
Stop 模式(代码)
PMU->CTRL1 &= ~PMU_CTRL1_PDDSCFG; // 清除 PDDS 位
SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
__WFI();
Standby 模式(代码)
PMU->CTRL1 |= PMU_CTRL1_PDDSCFG; // 设置 PDDS 位 → Standby
PMU->CSTS |= PMU_CSTS_WKUPCFG; // 使能 WKUP
SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
__WFI();
图8:进入 Stop / Standby 寄存器配置流程图
关键区别:
PDDS位决定是否断电 SRAM。
2. 退出机制
| 模式 | 触发方式 | 执行点 |
|---|---|---|
| Stop | 中断请求 | __WFI() 下一条 |
| Standby | 复位信号 | ResetHandler |
六、总结
| 维度 | Stop 模式 | Standby 模式 |
|---|---|---|
| 功耗 | 较低(~1.2μA) | 极低(~0.3μA) |
| 唤醒速度 | 快(5μs) | 慢(50μs) |
| 数据保持 | 保持 | 丢失 |
| 适用场景 | 短时休眠,需变量 | 长时待机,极限省电 |
| 编程复杂度 | 管理时钟恢复 | 重启初始化 |
图9:低功耗模式功耗对比柱状图(示意)
功耗对比
理解 APM32 MCU 低功耗模式的内核原理和外设状态,对于设计高效节能的嵌入式系统至关重要。
- Stop 模式:适合 快速唤醒 + 数据保持
- Standby 模式:适合 极低功耗 + 长时间待机
最难理解的点——“无时钟中断”——其实是硬件模拟电路的功劳:
EINT 的边沿检测是异步的,靠施密特触发器和锁存器实现,不需要任何时钟!
。
---------------------
作者:DKENNY
链接:https://bbs.21ic.com/icview-3498722-1-1.html
来源:21ic.com
此文章已获得原创/原创奖标签,著作权归21ic所有,任何人未经允许禁止转载。
openvela 操作系统专为 AIoT 领域量身定制,以轻量化、标准兼容、安全性和高度可扩展性为核心特点。openvela 以其卓越的技术优势,已成为众多物联网设备和 AI 硬件的技术首选,涵盖了智能手表、运动手环、智能音箱、耳机、智能家居设备以及机器人等多个领域。
更多推荐



所有评论(0)