【STM32】PWR电源控制
【STM32】PWR电源控制
- 一、PWR
- 1.1 PWR简介
- 1.2 STM32电源框图
- 1.3 上电复位和掉电复位
- 1.4 可编程电压监测器
- 二、低功耗模式
- 2.1 睡眠模式
- 2.2 停止模式
- 2.3 待机模式
一、PWR
1.1 PWR简介
- PWR(Power Control)电源控制
- PWR负责管理STM32内部的电源供电部分,可以实现可编程电压监测器和低功耗模式的功能
- 可编程电压监测器(PVD)可以监控VDD电源电压,当VDD下降到PVD阀值以下或上升到PVD阀值之上时,PVD会触发中断,用于执行紧急关闭任务
- 低功耗模式包括睡眠模式(Sleep)、停机模式(Stop)和待机模式(Standby),可在系统空闲时,降低STM32的功耗,延长设备使用时间
1.2 STM32电源框图

1. 供电区域划分
图中把STM32的电源系统划分为四个核心供电区域,分别对应不同的功能模块,实现电源的分级管理与针对性供电:
- VDDA供电区域
- VDD供电区域
- 1.8V供电区域
- 后备供电区域(VBAT)
2. 各区域功能与模块解析
1) VDDA供电区域
- 供电对象:A/D转换器、温度传感器、复位模块、PLL(锁相环)。
- 电源范围:
VREF-(可与VSSA共地)到VREF+,电压范围从2.4V起至VDDA。 - 设计逻辑:该区域为模拟/混合信号模块供电,需保证电源的稳定性(如ADC对电源噪声敏感),因此独立划分供电,避免数字电路的干扰。
2)VDD供电区域
- 子模块1:I/O电路
负责CPU芯片的输入输出接口供电,是数字信号与外部设备交互的“门户”。 - 子模块2:待机电路(唤醒逻辑、IWDG)
- 唤醒逻辑:支持芯片从低功耗待机模式快速唤醒,保障系统响应速度。
- IWDG(独立看门狗):是一种硬件监控机制,若程序运行异常(如死循环),IWDG会触发复位,保证系统可靠性。
- 子模块3:电压调节器
是电源管理的核心单元之一,负责将VDD的输入电压转换为1.8V,为“1.8V供电区域”供电。
3)1.8V供电区域
- 供电对象:CPU核心、存储器、内置数字外设。
- 设计逻辑:CPU和高速数字模块对电源电压精度、功耗敏感,通过电压调节器将VDD降压到1.8V,既满足性能需求,又能降低功耗。
4)后备供电区域(VBAT)
- 供电对象:LSE 32K晶体振荡器、后备寄存器、RCC BDCR寄存器、RTC(实时时钟)。
- 设计逻辑:该区域由备用电池(VBAT)供电,即使主电源(VDD)掉电,也能维持RTC计时、后备寄存器数据存储,保障系统的时间连续性和关键数据不丢失。
1.3 上电复位和掉电复位

- 复位信号(Reset):低电平表示芯片处于复位状态,高电平表示复位释放,芯片开始运行。
- 上电阶段:电源电压从 0 上升,当超过 POR 阈值并经过滞后时间后,复位信号释放,芯片开始初始化运行。
- 掉电阶段:电源电压下降,当低于 PDR 阈值时,复位信号拉低,芯片进入复位状态,防止电压不足时运行异常。
- 上电时超过POR才不会复位,掉电时低于PDR就开始复位。
- 通过硬件级的复位机制,保证芯片在 “上电时电源稳定后才启动”“掉电时提前复位以保护数据”,提升系统可靠性。
1.4 可编程电压监测器

- 电压上升阶段:当 VDD/V DDA 电压上升超过 PVD 阈值时,PVD 输出电平翻转。
- 电压下降阶段:当 VDD/V DDA 电压 下降低于(PVD 阈值 - 100mV 迟滞) 时,PVD 输出电平再次翻转。
- 可用于提前检测电源电压异常(如掉电预警),让系统有时间执行备份数据、进入低功耗等保护操作,提升系统可靠性。用户可通过配置寄存器选择不同的 PVD 阈值,适配不同应用场景的电源监测需求。
二、低功耗模式

- 睡眠模式:是“轻量级”低功耗模式,仅暂停CPU运行,外设和时钟基本保持,用于短时间待机且需快速响应的场景。
- 停机模式:深度降低功耗,关闭大部分时钟和1.8V区域供电,需外部中断唤醒,适用于对功耗敏感、可容忍稍慢唤醒速度的场景。
- 待机模式:是最深的低功耗模式,几乎关闭所有电源和时钟(仅后备区域保持),需特定唤醒源(如WKUP引脚、RTC),用于极致功耗优化的场景。
| 低功耗模式 | CPU状态 | 内核外设/寄存器 | 系统时钟 | 大部分外设状态 | 特殊保持的模块 |
|---|---|---|---|---|---|
| 睡眠模式(Sleep) | 停止运行 | 保持(数据不丢) | 保持(可配置) | 正常运行(可配置关闭) | 无(或仅关闭未使用外设) |
| 停机模式(Stop) | 停止运行 | 保持(数据不丢) | 关闭 | 断电(寄存器数据保持) | RTC、IWDG(若使能) |
| 待机模式(Standby) | 完全断电 | 丢失(全部重置) | 几乎全部关闭 | 几乎全部断电 | RTC、LSE、后备寄存器、IWDG(若使能) |


2.1 睡眠模式
- 执行完WFI/WFE指令后,STM32进入睡眠模式,程序暂停运行,唤醒后程序从暂停的地方继续运行
- SLEEPONEXIT位决定STM32执行完WFI或WFE后,是立刻进入睡眠,还是等STM32从最低优先级的中断处理程序中退出时进入睡眠
- 在睡眠模式下,所有的I/O引脚都保持它们在运行模式时的状态
- WFI指令进入睡眠模式,可被任意一个NVIC响应的中断唤醒
- WFE指令进入睡眠模式,可被唤醒事件唤醒
WFI 模式实现代码
#include "stm32f10x.h"// 初始化NVIC中断(用于WFI唤醒)
void NVIC_Init_For_WFI(void) {NVIC_InitTypeDef NVIC_InitStructure;// 配置某中断(如外部中断EXTI0)NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_Init(&NVIC_InitStructure);
}// 配置睡眠模式(SLEEP-ON-EXIT使能)
void Sleep_Mode_Config(void) {// 使能SLEEPONEXIT位:执行完中断服务程序后进入睡眠SCB->SCR |= SCB_SCR_SLEEPONEXIT_Msk;// 选择睡眠模式为“深度睡眠禁用”(即普通睡眠模式)PWR->CR &= ~PWR_CR_PDDS;PWR->CR |= PWR_CR_CWUF; // 清除唤醒标志
}int main(void) {// 系统初始化(时钟、外设等)SystemInit();NVIC_Init_For_WFI();Sleep_Mode_Config();while(1) {// 执行WFI指令进入睡眠,被任意NVIC中断唤醒后继续执行__WFI();// 唤醒后从这里继续运行}
}// 中断服务程序(示例:EXTI0中断)
void EXTI0_IRQHandler(void) {if(EXTI_GetITStatus(EXTI_Line0) != RESET) {// 中断处理逻辑EXTI_ClearITPendingBit(EXTI_Line0);}
}
2.2 停止模式
- 执行完WFI/WFE指令后,STM32进入停止模式,程序暂停运行,唤醒后程序从暂停的地方继续运行
- 1.8V供电区域的所有时钟都被停止,PLL、HSI和HSE被禁止,SRAM和寄存器内容被保留下来
- 在停止模式下,所有的I/O引脚都保持它们在运行模式时的状态
- 当一个中断或唤醒事件导致退出停止模式时,HSI被选为系统时钟
- 当电压调节器处于低功耗模式下,系统从停止模式退出时,会有一段额外的启动延时
- WFI指令进入停止模式,可被任意一个EXTI中断唤醒
- WFE指令进入停止模式,可被任意一个EXTI事件唤醒
停止模式(WFI 唤醒,EXTI 中断触发)
#include "stm32f10x.h"// 初始化EXTI中断(用于唤醒停止模式)
void EXTI_Init_For_Stop(void) {GPIO_InitTypeDef GPIO_InitStructure;EXTI_InitTypeDef EXTI_InitStructure;NVIC_InitTypeDef NVIC_InitStructure;// 使能GPIO和AFIO时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE);// 配置GPIO为输入模式(如GPIOA0)GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; // 上拉输入GPIO_Init(GPIOA, &GPIO_InitStructure);// 配置EXTI中断EXTI_InitStructure.EXTI_Line = EXTI_Line0;EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising; // 上升沿触发中断EXTI_InitStructure.EXTI_LineCmd = ENABLE;EXTI_Init(&EXTI_InitStructure);// 配置NVIC中断NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_Init(&NVIC_InitStructure);
}// 停止模式配置
void Stop_Mode_Config(void) {// 使能深度睡眠SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;// 选择停止模式(PDDS=0,LPDS=1)PWR->CR |= PWR_CR_LPDS;PWR->CR &= ~PWR_CR_PDDS;PWR->CR |= PWR_CR_CWUF; // 清除唤醒标志
}int main(void) {// 系统初始化(时钟、外设等)SystemInit();EXTI_Init_For_Stop();Stop_Mode_Config();while(1) {// 执行WFI指令进入停止模式,被EXTI0中断唤醒后继续执行__WFI();// 唤醒后从这里继续运行}
}// EXTI0中断服务程序
void EXTI0_IRQHandler(void) {if(EXTI_GetITStatus(EXTI_Line0) != RESET) {// 中断处理逻辑EXTI_ClearITPendingBit(EXTI_Line0);}
}
2.3 待机模式
- 执行完WFI/WFE指令后,STM32进入待机模式,唤醒后程序从头开始运行
- 整个1.8V供电区域被断电,PLL、HSI和HSE也被断电,SRAM和寄存器内容丢失,只有备份的寄存器和待机电路维持供电
- 在待机模式下,所有的I/O引脚变为高阻态(浮空输入)
- WKUP引脚的上升沿、RTC闹钟事件的上升沿、NRST引脚上外部复位、IWDG复位退出待机模式
待机模式WKUP引脚 实现代码
#include "stm32f10x.h"void Standby_Mode_Config(void) {RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;PWR->CR |= PWR_CR_PDDS; // 选择待机模式PWR_WakeUpPinCmd(ENABLE); // 使能WKUP引脚唤醒PWR->CR |= PWR_CR_CWUF; // 清除唤醒标志__WFI(); // 进入待机模式
}int main(void) {SystemInit();Standby_Mode_Config();// 唤醒后从头执行,需重新初始化while(1) {// 应用逻辑}
}
有关【STM32】PWR电源控制 就到这,希望对你有所帮助,感谢观看!
码文不易,留个赞再走吧~
