HAL_PWR
一、PWR 简介
PWR(Power Control,电源控制模块)是 STM32 内核级核心外设,无需单独时钟使能,主要负责芯片电源域管理、内核电压调节、系统复位管控、电压监测、低功耗模式切换、唤醒机制,是电池供电设备、低功耗物联网设备、长时间待机设备开发的核心模块。
普通外设负责功能实现,而 PWR 负责功耗管控。芯片运行时的主频上限、外设供电、休眠待机、掉电保存、低压保护等功能,全部依赖 PWR 模块配置,合理使用 PWR 可以极大降低设备静态功耗,大幅提升设备续航能力。
1、学习 PWR 的核心意义
解决嵌入式设备静态功耗高、待机续航短的核心问题
熟练掌握 STM32 三大官方低功耗模式:睡眠、停机、待机
掌握 PVD 电压监测、备份域保护、上电/掉电复位等电源保护功能
实现按键、外部中断、RTC、串口等多种方式的低功耗唤醒功能
适配不同系统主频,通过电压调压档位实现性能与功耗平衡
2、STM32 电源系统整体框架
STM32 芯片电源整体划分为三个独立供电域,PWR 模块对各供电域进行权限管控、状态切换,不同电源域独立工作、互不干扰:
主电源域 VDD:为内核、片上外设、SRAM、Flash 供电,芯片正常工作的核心电源域,断电后程序停止运行、数据丢失 。
备份电源域 VBAT:独立供电域,由纽扣电池/备用电源供电,专门为 RTC 时钟、备份寄存器供电,主电源断电后数据不丢失、时钟继续运行 。
内核可调电压域 VCORE:PWR 专属调压域,通过配置不同电压档位,适配不同系统主频,主频越高所需内核电压越高 。
二、PWR 模块详解
1、PWR模块框图

2、VDDA供电区域
供电对象:ADC、温度传感器、复位模块、PLL 锁相环
关键特性:
为提高 ADC 转换精度,提供独立的电源与地(V_DDA/V_SSA),可单独滤波降噪。
V_REF+/V_REF-为 ADC 提供参考电压(范围 2.4V~V_DDA)。
必须与数字电源V_DD共地,否则会导致 ADC 工作异常。
3、VDD供电区域
供电对象:
I/O 电路:所有 GPIO 的驱动电路。
待机电路:唤醒逻辑、独立看门狗(IWDG)。
电压调节器:将外部V_DD(通常 3.3V)降压为 1.8V,为 CPU 核心、存储器和内置数字外设供电。
关键特性:
是芯片最核心的供电域,决定了 CPU 主频上限和大部分外设的工作状态。
v低功耗模式下,电压调节器可切换为低功耗模式以降低静态电流。
4、后备供电区域
供电对象: RTC 实时时钟、LSE 32kHz 晶振、后备寄存器、RCC 备份域控制寄存器。
关键特性:
由独立的V_BAT引脚供电(通常接纽扣电池),主电源V_DD掉电后仍能维持 RTC 运行和备份寄存器数据不丢失。
主电源正常时,由V_DD自动切换供电,无需额外电池。
5、PWR 核心功能概述
PWR 模块不参与电压转换,仅负责电源逻辑控制与功耗管理,是系统级管理外设,核心功能包含以下六大类:
内核电压缩放控制:配置 VCORE 电压档位,匹配系统时钟主频,兼顾性能与功耗
PVD 可编程电压监测:实时监测主电源电压,低压触发中断,实现设备低压保护、数据保存
备份域读写控制:解锁/锁定备份域,保护 RTC 和备份寄存器数据,防止误改写
系统复位管理:管控上电复位、掉电复位、备份域复位标志
三大低功耗模式管控:控制芯片进入睡眠、停机、待机模式,实现分级降功耗
多源唤醒机制:支持外部引脚、EXTI中断、RTC闹钟、RTC周期唤醒等多种唤醒方式
6、STM32 三大低功耗模式(核心重点)
STM32 所有低功耗场景均由 PWR 模块实现,三种模式功耗逐级降低、唤醒代价逐级升高,适配不同应用场景:
| 低功耗模式 | 功耗等级 | 内核状态 | 外设/SRAM状态 | 唤醒方式 | 唤醒后果 | 适用场景 |
|---|---|---|---|---|---|---|
| 睡眠模式 SLEEP | 低功耗 | 内核停止运行 | 全部外设、SRAM保持运行 | 任意中断、定时器 | 程序继续执行,无复位 | 短时空闲、频繁唤醒、实时性要求高 |
| 停机模式 STOP | 极低功耗 | 内核时钟关闭 | 大部分外设关闭,保留唤醒外设、SRAM数据 | EXTI中断、RTC、WKUP引脚 | 程序继续执行,变量不丢失 | 长时间待机、中度节能、需保留运行状态 |
| 待机模式 STANDBY | 最低功耗 | 内核完全断电 | 所有外设关闭、SRAM数据清空 | WKUP引脚、RTC闹钟 | 等同于软复位,程序从头运行 | 电池长期待机、超低功耗设备、无需保留变量 |
7、内核电压档位(电压缩放机制)
VCORE 内核电压决定芯片最大支持主频,PWR 可配置三种电压档位,主频越高,所需内核电压越高,功耗也随之升高:
Range0 高性能档位:电压最高,支持最大系统主频,性能最强,功耗最高,适合高速运算场景
Range1 均衡档位:默认常用档位,兼顾主频与功耗,适配绝大多数常规项目
Range2 低功耗档位:电压最低,仅支持低频运行,大幅降低功耗,适合纯低功耗待机场景
三、PWR编程模块
1、PWR外设功能
可编程电压检测器 PVD(电源低压监测 + 中断)。
低功耗模式:睡眠 (SLEEP)、停机 (STOP)、待机 (STANDBY)。
备份域电源管理、唤醒引脚管理。
电压调节器模式(正常 / 低功耗)。
2、PWR句柄特性
区别于 SPI、I2C、UART 等外设,PWR 无独立句柄结构体。
PWR属于全局系统配置,整个芯片仅有一个电源管理模块,无需实例化句柄,所有操作直接调用全局 HAL_PWR 函数即可。
3、 PVD 配置结构体
/**
* @brief PVD 初始化结构体
*/
typedef struct
{
uint32_t PVDLevel; /* 参考 @ref PWR_PVD_detection_level */
uint32_t Mode; /* 中断触发沿 @ref PWR_PVD_Edge */
} PWR_PVDTypeDef;
4、核心HAL API函数汇总
PVD电压检测API
- void HAL_PWR_ConfigPVD(PWR_PVDTypeDef *sConfigPVD);
功能:配置 PVD 阈值与中断边沿。
参数:
sConfigPVD:PVD 配置结构体指针。 - void HAL_PWR_EnablePVD(void);
功能:使能 PVD 电压监测。 - void HAL_PWR_DisablePVD(void);
功能:关闭 PVD 电压监测。
PVD 中断服务与回调函数
- void HAL_PWR_PVD_IRQHandler(void)
功能:PVD 中断入口函数
CubeMX 生成工程会自动在 stm32f1xx_it.c 中实现,用户不要手动修改
内部会自动清中断标志,最终调用 HAL_PWR_PVDCallback - void HAL_PWR_PVDCallback(void)
功能:PVD 中断回调(弱函数,用户重写)
中断上下文,代码务必简短,禁止 HAL_Delay、长循环
通过 HAL_PWR_GetFlagStatus(PWR_FLAG_PVDO) 判断当前电压状态
唤醒引脚 API
- void HAL_PWR_EnableWakeUpPin(uint32_t WakeUpPinx)
功能:使能待机模式唤醒引脚(F103 仅 PA0/WKUP 一个引脚)。
参数:
WakeUpPinx:固定传 PWR_WAKEUP_PIN1。 - void HAL_PWR_DisableWakeUpPin(uint32_t WakeUpPinx)
功能:禁用唤醒引脚。
HAL_PWR_DisableWakeUpPin(PWR_WAKEUP_PIN1);
低功耗模式 API
- void HAL_PWR_EnterSLEEPMode(uint32_t Regulator, uint8_t SLEEPEntry)
功能:进入 SLEEP 睡眠模式。
参数:
Regulator:固定填 PWR_MAINREGULATOR_ON(F103 睡眠无调压选项)。
SLEEPEntry:进入方式。
PWR_SLEEPENTRY_WFI:等待中断唤醒(最常用)。
PWR_SLEEPENTRY_WFE:等待事件唤醒。
示例:
HAL_SuspendTick(); // 关闭SysTick,防止频繁唤醒
HAL_PWR_EnterSLEEPMode(PWR_MAINREGULATOR_ON, PWR_SLEEPENTRY_WFI);
HAL_ResumeTick(); // 唤醒后恢复滴答时钟
- void HAL_PWR_EnterSTOPMode(uint32_t Regulator, uint8_t STOPEntry)
功能:进入 STOP 停机模式(低功耗首选)。
参数
Regulator 调压器模式
PWR_LOWPOWERREGULATOR_ON:低功耗调压,功耗更低(推荐)
PWR_NORMALREGULATOR_ON:正常调压,唤醒更快
STOPEntry
PWR_STOPENTRY_WFI:中断唤醒(常用)
PWR_STOPENTRY_WFE:事件唤醒
示例:
HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI);
SystemClock_Config(); // 唤醒后必须重新配置72MHz时钟
- void HAL_PWR_EnterSTANDBYMode(void)
功能:进入 STANDBY 待机模式(F103 最低功耗)
特点:
唤醒 = 系统复位,所有变量、外设状态清空
仅备份域、WKUP 引脚供电
示例:
HAL_PWR_EnableWakeUpPin(PWR_WAKEUP_PIN1);
HAL_PWR_EnterSTANDBYMode();
休眠辅助 API
- void HAL_PWR_EnableSleepOnExit(void)
功能:开启「中断退出后自动进入睡眠」
中断服务函数执行完毕,CPU 自动进入 SLEEP 模式
适合纯中断驱动、主循环空闲的系统
示例:
HAL_PWR_EnableSleepOnExit(); - void HAL_PWR_DisableSleepOnExit(void)
功能:关闭中断退出自动睡眠。 - void HAL_PWR_EnableSEVOnPend(void)
功能:使能「中断挂起时生成事件 SEV」,配合 WFE 事件唤醒使用
多用于复杂事件驱动、多内核场景,普通项目极少使用 - void HAL_PWR_DisableSEVOnPend(void)
功能:关闭该功能。
5、常用状态标志位
PWR_FLAG_WU:唤醒标志,芯片从低功耗唤醒后置1,需手动清零。
PWR_FLAG_SB:待机模式标志,芯片进入待机后置1。
PWR_FLAG_PVDO:低压监测标志,电源电压低于阈值后置1。
6、PVD电压档位枚举(PVD Level)
/** @defgroup PWR_PVD_detection_level PVD 监测电压等级
#define PWR_PVDLEVEL_0 PWR_CR_PLS_LEV0 /* PVD 阈值 2.0 V */
#define PWR_PVDLEVEL_1 PWR_CR_PLS_LEV1 /* PVD 阈值 2.2 V */
#define PWR_PVDLEVEL_2 PWR_CR_PLS_LEV2 /* PVD 阈值 2.4 V */
#define PWR_PVDLEVEL_3 PWR_CR_PLS_LEV3 /* PVD 阈值 2.5 V */
#define PWR_PVDLEVEL_4 PWR_CR_PLS_LEV4 /* PVD 阈值 2.6 V */
#define PWR_PVDLEVEL_5 PWR_CR_PLS_LEV5 /* PVD 阈值 2.7 V */
#define PWR_PVDLEVEL_6 PWR_CR_PLS_LEV6 /* PVD 阈值 2.8 V */
#define PWR_PVDLEVEL_7 PWR_CR_PLS_LEV7 /* PVD 阈值 2.9 V */
*/
7、其他特性
PWR模块默认开启,无需手动开启时钟。
停机模式唤醒不重置程序,待机模式唤醒等同于重启。
备份域数据主电源断电不丢失,可用于存储掉电保存参数。
五、PWR应用实例
1、PVD 可编程电压检测(中断告警)
功能:监测系统供电电压,低于 2.4V 触发中断,LED 点亮告警;电压恢复后 LED 熄灭。
CubeMX 配置:
PB5:GPIO_Output。
实例代码:
#include "main.h"
PWR_PVDTypeDef sPvdConfig;
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
// PVD 参数配置
sPvdConfig.PVDLevel = PWR_PVDLEVEL_2; // 2.4V 检测阈值
sPvdConfig.Mode = PWR_PVD_MODE_IT_FALLING;
HAL_PWR_ConfigPVD(&sPvdConfig);
HAL_PWR_EnablePVD(); // 开启PVD硬件检测
__HAL_PWR_PVD_EXTI_ENABLE_IT(); // 使能PVD中断
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_5, GPIO_PIN_SET); // LED默认熄灭
while (1)
{
// 主循环空闲,逻辑在中断回调
}
}
// PVD 中断回调函数
void HAL_PWR_PVDCallback(void)
{
if(__HAL_PWR_GET_FLAG(PWR_FLAG_PVDO))
{
// 电压低于阈值:点亮LED告警
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_5, GPIO_PIN_RESET);
}
else
{
// 电压恢复正常:熄灭LED
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_5, GPIO_PIN_SET);
}
}
2、SLEEP 睡眠模式 + 外部中断唤醒
CPU 进入睡眠,按下 PA0 按键(外部中断)唤醒,翻转 LED。
CubeMX 配置:
PA0:GPIO_EXTI0,下降沿触发,开启 NVIC。
PB5:GPIO_Output。
实例代码:
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
while (1)
{
// 关闭SysTick,避免1ms中断频繁唤醒
HAL_SuspendTick();
// 进入睡眠模式,WFI 等待中断唤醒
HAL_PWR_EnterSLEEPMode(PWR_MAINREGULATOR_ON, PWR_SLEEPENTRY_WFI);
// 唤醒后恢复滴答时钟
HAL_ResumeTick();
// 翻转LED
HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_5);
}
}
// 外部中断回调
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
if(GPIO_Pin == GPIO_PIN_0)
{
// 仅做唤醒,业务逻辑放主循环
}
}
3、STOP 停机模式(低功耗)
运行 2 秒后进入停机,PA0 按键唤醒,唤醒后必须重配时钟。
CubeMX 配置:
PA0 配置为外部中断下降沿,开启 NVIC。
实例代码:
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_5, GPIO_PIN_SET);
while (1)
{
HAL_Delay(2000); // 正常运行2秒
// 进入停机模式:低功耗调压器 + 中断唤醒
HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI);
// 唤醒后时钟变为HSI,必须重新配置为72MHz
SystemClock_Config();
HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_5);
}
}
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
if(GPIO_Pin == GPIO_PIN_0)
{
// 中断唤醒触发
}
}
4、STANDBY 待机模式(最低功耗)
上电延时 1 秒后进入待机,PA0 (WKUP 引脚) 唤醒,唤醒等价系统复位。
CubeMX 配置:
SYS:勾选System Wae-Up (PA0 为 WKUP 引脚)。
实例代码:
#include "main.h"
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
// 每次上电/唤醒都会执行此处,翻转LED区分状态
HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_5);
HAL_Delay(1000); // 亮/灭保持1秒
// 1. 使能 PA0(WKUP) 待机唤醒功能
HAL_PWR_EnableWakeUpPin(PWR_WAKEUP_PIN1);
// 2. 进入 STANDBY 待机模式
HAL_PWR_EnterSTANDBYMode();
// ========== 以下代码永远不会执行 ==========
// 待机唤醒 = 系统复位,直接回到main函数开头
while (1)
{
}
}
六、其它要点(工程避坑+核心总结)
1、低功耗通用避坑要点
必须清除唤醒标志:每次唤醒后不清除 WU/SB 标志,芯片将无法再次进入低功耗模式。
停机唤醒需重配时钟:部分STM32芯片停机唤醒后时钟默认变回HSI,需重新配置系统时钟。
休眠前关闭冗余外设:ADC、串口、定时器等未关闭会导致静态功耗偏高,无法达到最低功耗。
IO状态影响功耗:休眠前将未使用IO设置为上拉/下拉,避免浮空漏电增加功耗。
2、备份域核心要点
备份域默认锁定,未解锁无法修改RTC时钟和备份寄存器数据。
仅待机、停机模式保留备份域数据,硬件复位不清除备份域数据。
电池供电异常会导致RTC时间错乱,需做供电检测。
3、电压调压要点
超频运行必须提升电压档位,电压不足会导致芯片死机、运行不稳定。
低频待机场景可降低电压档位,有效降低静态功耗。
CubeMX自动适配的电压档位可满足99%常规场景,无需手动修改。
4、低功耗模式选型原则
频繁唤醒、实时性高:优先选择 睡眠模式。
长时间待机、需保留程序状态:优先选择 停机模式。
超长时间待机、电池供电、无需保留变量:优先选择 待机模式。
更多推荐
所有评论(0)