一、PWR

1.PWR简介

        PWR(Power Control)电源控制

        PWR负责管理STM32内部的电源供电部分,可以实现可编程电压监测器和低功耗模式的功能

        可编程电压监测器(PVD)可以监控VDD电源电压,当VDD下降到PVD阀值以下或上升到PVD阀值之上时,PVD会触发中断,用于执行紧急关闭任务

        低功耗模式包括睡眠模式(Sleep)、停机模式(Stop)和待机模式(Standby),可在系统空闲时,降低STM32的功耗,延长设备使用时间

2.电源框图

        将框图分为3部分,上面是模拟部分供电叫做VDDA,中间是数字部分供电,包括两块区域,VDD供电区域和1.8V供电区域,下面是后备供电叫做VBAT。

        VDDA供电区域,主要负责模拟部分的供电,其中包括A/D转换器、温度传感器、复位模块、PLL锁相环,这些电路的供电正极是VDDA,负极是VSSA,其中AD转换器还有两根参考电压的供电脚,叫做VREF+和VREF-,这两个脚在芯片内部接入了VDDA和VSSA了。

        中间部分的供电,由两部分组成,左边部分是VDD供电区,其中包括IO电路、待机电路、唤醒逻辑和独立看门狗,右边部分是VDD通过电压调节器,降压到1.8V,提供给后面一块的1.8V供电区域,1.8V区域包括CPU核心、存储器和内置数字外设。

        下部分位VBAT后备供电区域,其中包括LSE32K晶体振荡器、后备寄存器,RCC BDCR寄存器和BDCR,RCC BDCR是RCC的寄存器,叫备份域控制寄存器,也是和后备区域有关的寄存器,上面有一个低电压检测器,VDD有电时,由VDD供电,VDD没电时,由VBAT供电

3.上电复位和掉电复位

        当VDD或VDDA电压过低时,内部电路直接产生复位,复位与不复位之间设置了一个40mV的迟滞电压,大于上限PDR,解除复位,小于下限PDR时,复位。Reset是低电平有效。

4.可编程电压检测器

        阈值电压可以使用程序指定。3.3V到2.9V是PVD的检测范围,2.9到2.2是复位电路的监测范围。

5.低功耗模式

        第一列从上到下越来越省电,第三列从上到下越来越难唤醒。

        停机模式:SLEEPDEEP位为1,PDDS位为0,LPDS=0电压调节器开启,LPDS=1电压调节器进入低功耗,再调用WFI或WFE,芯片就进入了停止模式

      待机模式:SLEEPDEEP位为1,PDDS位为1,再调用WFI或WFE,芯片就进入了待机模式 

6.模式选择     

        执行WFI(Wait For Interrupt)或者WFE(Wait For Event)指令后,STM32进入低功耗模式 

7.睡眠模式

        执行完WFI/WFE指令后,STM32进入睡眠模式,程序暂停运行,唤醒后程序从暂停的地方继续运行

        SLEEPONEXIT位决定STM32执行完WFI或WFE后,是立刻进入睡眠,还是等STM32从最低优先级的中断处理程序中退出时进入睡眠

        在睡眠模式下,所有的I/O引脚都保持它们在运行模式时的状态

        WFI指令进入睡眠模式,可被任意一个NVIC响应的中断唤醒

        WFE指令进入睡眠模式,可被唤醒事件唤醒

8.停止模式

        执行完WFI/WFE指令后,STM32进入停止模式,程序暂停运行,唤醒后程序从暂停的地方继续运行

        1.8V供电区域的所有时钟都被停止,PLL、HSI和HSE被禁止,SRAM和寄存器内容被保留下来

        在停止模式下,所有的I/O引脚都保持它们在运行模式时的状态

        当一个中断或唤醒事件导致退出停止模式时,HSI被选为系统时钟

        当电压调节器处于低功耗模式下,系统从停止模式退出时,会有一段额外的启动延时

        WFI指令进入停止模式,可被任意一个EXTI中断唤醒

        WFE指令进入停止模式,可被任意一个EXTI事件唤醒

9.待机模式

        执行完WFI/WFE指令后,STM32进入待机模式,唤醒后程序从头开始运行

        整个1.8V供电区域被断电,PLL、HSI和HSE也被断电,SRAM和寄存器内容丢失,只有备份的寄存器和待机电路维持供电

        在待机模式下,所有的I/O引脚变为高阻态(浮空输入)

        WKUP引脚的上升沿、RTC闹钟事件的上升沿、NRST引脚上外部复位、IWDG复位退出待机模式

二、PWR库函数

void PWR_DeInit(void);

作用:恢复缺省配置

void PWR_BackupAccessCmd(FunctionalState NewState);

作用:使能后备区域的访问

void PWR_PVDCmd(FunctionalState NewState);

作用:使能PVD

void PWR_PVDLevelConfig(uint32_t PWR_PVDLevel);

作用:配置PVD的阈值电压

void PWR_WakeUpPinCmd(FunctionalState NewState);

作用:使能位于PA0的位置的WKUP引脚(配合待机模式使用)

void PWR_EnterSTOPMode(uint32_t PWR_Regulator, uint8_t PWR_STOPEntry);

作用:进入停止模式

void PWR_EnterSTANDBYMode(void);

作用:进入待机模式

FlagStatus PWR_GetFlagStatus(uint32_t PWR_FLAG);

void PWR_ClearFlag(uint32_t PWR_FLAG);

三、System_stm32f10x.c

这个文件里面总共有两个外部可调用的函数和一个外部可调用的变量

函数1:SystemInit()——配置时钟树,使用HSE配置主频为72M

函数2:SystemCoreClockUpdate()——更新下面的变量

变量:SystemCoreClock——主频频率的值

四、代码

1.代码1——修改主频

显示当时主频率变量,以1s为周期显示Running再清除

        在system_stm32f10x.c文件中修改110行

/* #define SYSCLK_FREQ_HSE    HSE_VALUE */
/* #define SYSCLK_FREQ_24MHz  24000000 */ 
#define SYSCLK_FREQ_36MHz  36000000 
/* #define SYSCLK_FREQ_48MHz  48000000 */
/* #define SYSCLK_FREQ_56MHz  56000000 */
/* #define SYSCLK_FREQ_72MHz  72000000 */

选择自己需要的时钟频率,取消对他的宏定义注释,其余注释。

在main.c文件中

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"


int main(void)
{
	OLED_Init();
	
	OLED_ShowString(1, 1, "SYSCLK:");
	OLED_ShowNum(1, 8, SystemCoreClock, 8);
	
	while (1)
	{
		OLED_ShowString(2, 1, "Running");
		Delay_ms(500);
		OLED_ShowString(2, 1, "       ");
		Delay_ms(500);
	}	
}

        OLED显示当前选定的时钟频率,以及对应的Running一秒闪烁一次。

2.代码2——睡眠模式+串口发送+接收

        当收到一个字节时,中断触发,置标志位,主循环查询到标志位,读取数据,并用串口发送出去,执行任务后芯片睡眠。

        在串口中所讲的模块代码不变,在main主函数中调用__WFI()即可。

main.c

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"
#include "Serial.h"

uint8_t RxData;

int main(void)
{
	OLED_Init();
	OLED_ShowString(1, 1, "RxData:");
	
	Serial_Init();
	
	while (1)
	{	
		if (Serial_GetRxFlag() == 1)   //中断方式发送数据
		{
			RxData = Serial_GetRxData();
			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();
	}	
}

        下载程序之后,首先Running快速闪烁一次,接着进入睡眠模式。接着当发送数据时RxData显示接收到的数据,然后解除睡眠模式,Running闪烁一次,当不在发送数据时,继续睡眠

3.代码3——停止模式+对射式红外传感器计次

        在代码中,只需要调用PWR函数,让其进入停止模式,但是需要注意前面所讲的当一个中断或唤醒事件导致退出停止模式时,HSI被选为系统时钟,所以如果还是需要之前的HSE时钟,那么在解除停止模式后需要调用System_Init,重置时钟频率。

main.c

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"
#include "CountSensor.h"


int main(void)
{
	OLED_Init();
	CountSensor_Init();
	OLED_ShowString(1, 1, "Count:");
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);

	while (1)
	{
		OLED_ShowNum(1, 7, CountSensor_Get(), 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();
	}	
}

4.代码4——待机模式+实时时钟

        在时钟的main函数中加入待机模式需要的WAKEUP配置,以及设置对应的PWR待机模式函数

main.c

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"
#include "MyRTC.h"

int main(void)
{
	OLED_Init();
	MyRTC_Init();
	
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);

	OLED_ShowString(1, 1, "CNT:");			//	秒计数器
	OLED_ShowString(2, 1, "ALR:");			//	闹钟值
	OLED_ShowString(3, 1, "ALRF:");			//	闹钟标志位
	
	PWR_WakeUpPinCmd(ENABLE);
	
	uint32_t Alarm = RTC_GetCounter() + 10;
	RTC_SetAlarm(Alarm);
	
	OLED_ShowNum(2, 5, Alarm, 10);
	while (1)
	{
		OLED_ShowNum(1, 5, RTC_GetCounter(), 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, "Start");	
		Delay_ms(1000);
		OLED_ShowString(4, 1, "       ");
		Delay_ms(100);
		
		OLED_Clear();
		
		PWR_EnterSTANDBYMode();
	}	
}

        OLED首先显示实时时钟以及对应的闹钟值并显示Running以及Start,接着进入待机模式,当时钟值与闹钟值相等时,OLED点亮,Running和Start显示,然后继续进入待机模式。

五、总结

        STM32的PWR(电源控制)模块是芯片功耗管理的核心,主要负责电源域管理、低功耗模式配置及电源监测保护。它可对内核、外设、备份域等不同电源域进行独立供电控制,支持睡眠、停止、待机等多种低功耗模式,通过关闭不必要的时钟或降低核心电压实现分级节能,同时具备电源电压监测、复位保护等功能,能有效优化系统能耗,提升电池供电设备的续航能力,是保障STM32在嵌入式系统中高效低耗运行的关键组件。

Logo

openvela 操作系统专为 AIoT 领域量身定制,以轻量化、标准兼容、安全性和高度可扩展性为核心特点。openvela 以其卓越的技术优势,已成为众多物联网设备和 AI 硬件的技术首选,涵盖了智能手表、运动手环、智能音箱、耳机、智能家居设备以及机器人等多个领域。

更多推荐