文章目录
- PWR电源控制
- 一、PWR简介
- 二、STM32电源框图
- Ⅰ、上电复位和掉电复位
- Ⅱ、PVD可编程电压监测器
- 三、STM32的低功耗模式
- Ⅰ、睡眠模式(Sleep Mode)
- Ⅱ、停机模式(Stop Mode)
- Ⅲ、待机模式(Standby Mode)
- 四、PWR函数
- 函数介绍
- 五、示例
- ①、睡眠模式
- ②、停机模式
- ③、待机模式
PWR电源控制
一、PWR简介
PWR(Power Control)电源控制
PWR负责管理STM32内部的电源供电部分,可以实现可编程电压监测器和低功耗模式的功能
可编程电压监测器(PVD)可以监控VDD电源电压,当VDD下降到PVD阀值以下或上升到PVD阀值之上时,PVD会触发中断,用于执行紧急关闭任务
低功耗模式包括睡眠模式(
Sleep
)、停机模式(Stop
)和待机模式(Standby
),可在系统空闲时,降低STM32的功耗,延长设备使用时间
二、STM32电源框图
Ⅰ、上电复位和掉电复位
Ⅱ、PVD可编程电压监测器
三、STM32的低功耗模式
Ⅰ、睡眠模式(Sleep Mode)
进入方式:
- 使用
WFI
(Wait For Interrupt)指令进入睡眠模式- 使用
WFE
(Wait For Event)指令进入睡眠模式唤醒方式:
- 任一中断可以唤醒使用
WFI
指令进入的睡眠模式- 唤醒事件可以唤醒使用
WFE
指令进入的睡眠模式对时钟的影响:
- CPU时钟关闭,但对其他时钟(如总线时钟、外设时钟)和ADC时钟无影响
电压调节器:开启
- 执行完WFI/WFE指令后,STM32进入睡眠模式,程序暂停运行,唤醒后程序从暂停的地方继续运行
- SLEEPONEXIT位决定STM32执行完WFI或WFE后,是立刻进入睡眠,还是等STM32从最低优先级的中断处理程序中退出时进入睡眠
- 在睡眠模式下,所有的I/O引脚都保持它们在运行模式时的状态
- WFI指令进入睡眠模式,可被任意一个NVIC响应的中断唤醒
- WFE指令进入睡眠模式,可被唤醒事件唤醒
Ⅱ、停机模式(Stop Mode)
进入方式:
- 设置
PDDS
(Power Down Deep Sleep)和LPDS
(Low Power Deep Sleep)位
PDDS
:用于区分是停机模式还是待机模式
- 当
PDDS
位为0时,进入停机模式LPDS
:用于设置最后的电压调节器是开启还是进入低功耗模式
- 当
LPDS
位为1时,电压调节器进入低功耗模式;当LPDS
位为0时,电压调节器开启- 设置
SLEEPDEEP
位
- 用于选择睡眠模式还是深度睡眠模式(待机/停机)
- 当
SLEEPDEEP
位为1时,选择深度睡眠模式- 停机模式时,需要将
SLEEPDEEP
位置位- 使用
WFI
或WFE
指令进入停机模式唤醒方式:
- 任一外部中断(需要在外部中断寄存器中设置)
对时钟的影响:
- 关闭所有1.8V区域的时钟
- HSI和HSE的振荡器关闭
电压调节器:可以开启或处于低功耗模式,取决于电源控制寄存器(PWR_CR)的设定
- 执行完WFI/WFE指令后,STM32进入停止模式,程序暂停运行,唤醒后程序从暂停的地方继续运行
- 1.8V供电区域的所有时钟都被停止,PLL、HSI和HSE(唤醒后须重新启动)被禁止,SRAM和寄存器内容被保留下来
- 在停止模式下,所有的I/O引脚都保持它们在运行模式时的状态
- 当一个中断或唤醒事件导致退出停止模式时,HSI被选为系统时钟(使用
SystemInit();
则可重新启用72MHz的时钟)- 当电压调节器处于低功耗模式下,系统从停止模式退出时,会有一段额外的启动延时
- WFI指令进入停止模式,可被任意一个EXTI中断唤醒
- WFE指令进入停止模式,可被任意一个EXTI事件唤醒
Ⅲ、待机模式(Standby Mode)
进入方式:
- 设置
PDDS
位- 设置
SLEEPDEEP
位- 使用
WFI
或WFE
指令进入待机模式唤醒方式:
- WKUP引脚的上升沿
- RTC闹钟事件
- NRST引脚上的外部复位
- IWDG(Independent Watchdog)复位
对时钟的影响:
- 关闭所有1.8V区域的时钟
- HSI和HSE的振荡器关闭
电压调节器:关闭
- 执行完WFI/WFE指令后,STM32进入待机模式,唤醒后程序从头开始运行
- 整个1.8V供电区域被断电,PLL、HSI和HSE也被断电,SRAM和寄存器内容丢失,只有备份的寄存器和待机电路维持供电
- 在待机模式下,所有的I/O引脚变为高阻态(浮空输入)
- WKUP引脚的上升沿、RTC闹钟事件的上升沿、NRST引脚上外部复位、IWDG复位退出待机模式
在待机模式简介中,停机模式要操控的标志位包括:
PDDS
位:设置停机还是待机模式。0为停机模式、设置为1为待机模式SLEEPDEEP
位:设置是否进入深度睡眠模式。1 为进入
四、PWR函数
// 重置PWR寄存器为默认值
void PWR_DeInit(void);// 使能或失能对备份寄存器(BKP)的访问
void PWR_BackupAccessCmd(FunctionalState NewState);// 使能或失能电源电压检测器(PVD)
void PWR_PVDCmd(FunctionalState NewState);// 配置电源电压检测器(PVD)阈值
void PWR_PVDLevelConfig(uint32_t PWR_PVDLevel);// 使能或失能唤醒引脚(配合待机模式使用)
void PWR_WakeUpPinCmd(FunctionalState NewState);// 进入停止模式
void PWR_EnterSTOPMode(uint32_t PWR_Regulator, uint8_t PWR_STOPEntry);// 进入待机模式
void PWR_EnterSTANDBYMode(void);// 获取PWR标志位状态
FlagStatus PWR_GetFlagStatus(uint32_t PWR_FLAG);
// 清除PWR标志位
void PWR_ClearFlag(uint32_t PWR_FLAG);
函数介绍
函数功能
- 该函数的作用是使系统进入STOP模式。STOP模式是一种低功耗模式,通常用于在不需要处理数据或执行任务时节省能源
参数说明
PWR_Regulator
这个参数用于指定在STOP模式下*调节器(
regulator
)*的状态。调节器是电源管理系统的一部分,用于控制电源的供应和管理。它有两个可选值:
PWR_Regulator_ON
:在STOP模式下,调节器保持开启状态。这意味着电源管理系统将继续为某些关键部件供电,以确保系统能够快速从STOP模式唤醒
PWR_Regulator_LowPower
:在STOP模式下,调节器进入低功耗模式。这种模式下,电源管理系统会尽可能减少功耗,但可能会导致系统从STOP模式唤醒的速度稍慢
PWR_STOPEntry
这个参数用于指定进入STOP模式的方式,具体是通过WFI(Wait For Interrupt)指令还是WFE(Wait For Event)指令。这两个指令都是ARM架构中的低功耗指令,用于使处理器进入低功耗状态,直到有中断或事件发生时唤醒处理器。它也有两个可选值:
PWR_STOPEntry_WFI
:通过WFI指令进入STOP模式。WFI指令会使处理器进入低功耗状态,直到有中断发生时唤醒处理器
PWR_STOPEntry_WFE
:通过WFE指令进入STOP模式。WFE指令会使处理器进入低功耗状态,直到有事件发生时唤醒处理器
五、示例
①、睡眠模式
#include "stm32f10x.h" // Device header
#include "Delay.h"
#include "OLED.h"
#include "Serial.h"int main(void)
{uint8_t RxData;OLED_Init();Serial_Init(); OLED_ShowString(1,1,"RxData:");while(1){if(Serial_GetFlag() == 1){RxData = Serial_GetData();Serial_SendByte(RxData);OLED_ShowHexNum(1,8,RxData,2);}OLED_ShowString(2,1,"Running");Delay_ms(100);OLED_ShowString(2,1," ");Delay_ms(100);/* */__WFI();//进入睡眠模式(使用USART中断可唤醒)}
}
- 程序运行到
__WFI()
位置时会进入睡眠模式,使用任意中断都可对其进行唤醒
②、停机模式
#include "stm32f10x.h" // Device header
#include "Delay.h"
#include "OLED.h"
#include "CountSensor.h"int main(void)
{OLED_Init();CountSensor_Init();/**/RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);//开启PWR的是时钟OLED_ShowString(1,1,"Count:"); while(1){OLED_ShowNum(1,7,Ret_Count(),5);OLED_ShowString(2,1,"Running");Delay_ms(100);OLED_ShowString(2,1," ");Delay_ms(100);/**/PWR_EnterSTOPMode(PWR_Regulator_ON, PWR_STOPEntry_WFI);//调用该代码在此处进入停止模式
/**/SystemInit();//唤醒之后主频变为8MHz,需要重新启动72MHz主频}
}
- 进入停机模式后,需要外部中断才能将其唤醒
③、待机模式
#include "stm32f10x.h" // Device header
#include "Delay.h"
#include "OLED.h"
#include "MyRTC.h"int main(void)
{OLED_Init();MyRTC_Init();OLED_ShowString(1,1,"CNT:");//秒计数器OLED_ShowString(2,1,"ALR:");//闹钟值OLED_ShowString(3,1,"ALRF:");//闹钟标志位/**/RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);//开启PWR时钟 uint32_t Alarm = RTC_GetCounter() + 10;RTC_SetAlarm(Alarm);//设定闹钟/**/PWR_WakeUpPinCmd(ENABLE);//可使用WakeUp引脚唤醒while(1){OLED_ShowNum(1,6,RTC_GetCounter(),10);OLED_ShowNum(2,6,Alarm,10);OLED_ShowNum(3,6,RTC_GetFlagStatus(RTC_FLAG_ALR),1);OLED_ShowString(4,1,"Running");Delay_ms(100);OLED_ShowString(4,1," ");Delay_ms(100);OLED_ShowString(4,9,"STANDBY");Delay_ms(1000);OLED_ShowString(4,9," ");Delay_ms(1000);OLED_Clear();/* */PWR_EnterSTANDBYMode();//程序在此处进入待机模式(可由RTC闹钟事件唤醒)}
}
-
关键代码:
-
/**/RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);//开启PWR时钟... .../**/PWR_WakeUpPinCmd(ENABLE);//可使用WakeUp引脚唤醒... .../* */ PWR_EnterSTANDBYMode();//程序在此处进入待机模式(可由RTC闹钟事件唤醒)