一、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

  1. void HAL_PWR_ConfigPVD(PWR_PVDTypeDef *sConfigPVD);
    功能:配置 PVD 阈值与中断边沿。
    参数:
    sConfigPVD:PVD 配置结构体指针。
  2. void HAL_PWR_EnablePVD(void);
    功能:使能 PVD 电压监测。
  3. void HAL_PWR_DisablePVD(void);
    功能:关闭 PVD 电压监测。

PVD 中断服务与回调函数

  1. void HAL_PWR_PVD_IRQHandler(void)
    功能:PVD 中断入口函数
    CubeMX 生成工程会自动在 stm32f1xx_it.c 中实现,用户不要手动修改
    内部会自动清中断标志,最终调用 HAL_PWR_PVDCallback
  2. void HAL_PWR_PVDCallback(void)
    功能:PVD 中断回调(弱函数,用户重写)
    中断上下文,代码务必简短,禁止 HAL_Delay、长循环
    通过 HAL_PWR_GetFlagStatus(PWR_FLAG_PVDO) 判断当前电压状态

唤醒引脚 API

  1. void HAL_PWR_EnableWakeUpPin(uint32_t WakeUpPinx)
    功能:使能待机模式唤醒引脚(F103 仅 PA0/WKUP 一个引脚)。
    参数:
    WakeUpPinx:固定传 PWR_WAKEUP_PIN1。
  2. void HAL_PWR_DisableWakeUpPin(uint32_t WakeUpPinx)
    功能:禁用唤醒引脚。
    HAL_PWR_DisableWakeUpPin(PWR_WAKEUP_PIN1);

低功耗模式 API

  1. 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();   // 唤醒后恢复滴答时钟
  1. 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时钟
  1. void HAL_PWR_EnterSTANDBYMode(void)
    功能:进入 STANDBY 待机模式(F103 最低功耗)
    特点:
    唤醒 = 系统复位,所有变量、外设状态清空
    仅备份域、WKUP 引脚供电
    示例:
HAL_PWR_EnableWakeUpPin(PWR_WAKEUP_PIN1);
HAL_PWR_EnterSTANDBYMode();

休眠辅助 API

  1. void HAL_PWR_EnableSleepOnExit(void)
    功能:开启「中断退出后自动进入睡眠」
    中断服务函数执行完毕,CPU 自动进入 SLEEP 模式
    适合纯中断驱动、主循环空闲的系统
    示例:
    HAL_PWR_EnableSleepOnExit();
  2. void HAL_PWR_DisableSleepOnExit(void)
    功能:关闭中断退出自动睡眠。
  3. void HAL_PWR_EnableSEVOnPend(void)
    功能:使能「中断挂起时生成事件 SEV」,配合 WFE 事件唤醒使用
    多用于复杂事件驱动、多内核场景,普通项目极少使用
  4. 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、低功耗模式选型原则

频繁唤醒、实时性高:优先选择 睡眠模式。
长时间待机、需保留程序状态:优先选择 停机模式。
超长时间待机、电池供电、无需保留变量:优先选择 待机模式。

Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐