stm32 PWR电源控制(修改主频&睡眠模式&停机模式&待机模式)

理论

1.PWR简介

PWR(Power Control)电源控制

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

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

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

2.电源框图

3.上电复位和掉电复位

4.可编程电压监测器

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

5.低功耗模式

(1)睡眠模式

进入方式:调用_WFI();或_WFE();进入睡眠模式

唤醒方式:有两种唤醒方式,WFI或WFE,常用的一种方式是中断(WFI)

作用:可以使CPU时钟进入睡眠模式,但是对其他的时钟没有影响,不会关闭震荡器,不会关闭电源,不会失去SARM相关的数据

**SLEEPONEXIT:**是否立即进入睡眠模式,0表示立即进入睡眠模式,1表示等待当前中断执行完进入睡眠模式

(2)停机模式

PDDS:用于选择进入停机模式还是待机模式,0表示进入停机模式,1表示进入待机模式

**LPDS:**设置电压调节器,0表示开启电压调节器,1表示开启低功耗模式

**SLEEPDEEP:**选择睡眠模式还是深度睡眠模式(待机/停机)

唤醒方式:任意外部中断

进入方式:对PDDS,LPDS,SLEEPDEEP,WFI进行配置

作用:可以保持RTC运行。看门狗的运行,不会失去SARM相关的数据

(3)待机模式

PDDS:用于选择进入停机模式还是待机模式,0表示进入停机模式,1表示进入待机模式

**SLEEPDEEP:**选择睡眠模式还是深度睡眠模式(待机/停机)

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

进入方式:对PDDS,SLEEPDEEP,WFI进行配置

作用:只保留RTC与看门狗,不会丢失BKP的数据,会丢失SARM的数据

6.模式选择

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

(1)睡眠模式

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

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

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

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

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

(2)停止模式

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

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

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

当一个中断或唤醒事件导致退出停止模式时,HSI被选为系统时钟(在进入停止模式后要在后面加上SystemInit();恢复主频72M)

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

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

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

(3)待机模式

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

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

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

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

API学习

1.SystemCoreClock

cpp 复制代码
extern uint32_t SystemCoreClock;          /*!< System Clock Frequency (Core Clock) */
/*
 *当前的主频
 */

2.SystemInit

cpp 复制代码
extern void SystemInit(void);
/*
 * 初始化系统的硬件设置
 */

3.PWR_EnterSTANDBYMode

cpp 复制代码
void PWR_EnterSTANDBYMode(void);
/*
 *进入待机模式
 */

4.PWR_EnterSTOPMode

cpp 复制代码
void PWR_EnterSTOPMode(uint32_t PWR_Regulator, uint8_t PWR_STOPEntry);
/*
 *停止模式的唤醒  
 */

5.PWR_WakeUpPinCmd

cpp 复制代码
void PWR_WakeUpPinCmd(FunctionalState NewState);
/*
 *使能位于PA0的WKUP引脚,WKUP引脚上升沿唤醒待机模式
 */

6.RTC_SetAlarm

cpp 复制代码
void RTC_SetAlarm(uint32_t AlarmValue);
/*
 *  写入闹钟值到RTC的ALR寄存器
 */

代码

1.修改主频

main.c

cpp 复制代码
#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"

int main(void)
{
	OLED_Init();							//OLED初始化
	
	OLED_ShowString(1, 1, "SYSCLK:");		//显示静态字符串
	OLED_ShowNum(1, 8, SystemCoreClock, 8);	//显示SystemCoreClock变量
											//SystemCoreClock的值表示当前的系统主频频率
	
	while (1)
	{
		OLED_ShowString(2, 1, "Running");	//闪烁Running,指示当前主循环运行的快慢
		Delay_ms(500);
		OLED_ShowString(2, 1, "       ");
		Delay_ms(500);
	}
}

2.睡眠模式

main.c

cpp 复制代码
#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"
#include "Serial.h"

uint8_t RxData;			//定义用于接收串口数据的变量

int main(void)
{
	OLED_Init();		//OLED初始化
	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");		//OLED闪烁Running,指示当前主循环正在运行
		Delay_ms(100);
		OLED_ShowString(2, 1, "       ");
		Delay_ms(100);
		
		__WFI();								//执行WFI指令,CPU睡眠,并等待中断唤醒
	}
}

3.停机模式

main.c

cpp 复制代码
#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"
#include "CountSensor.h"

int main(void)
{
	/*模块初始化*/
	OLED_Init();			//OLED初始化
	CountSensor_Init();		//计数传感器初始化
	
	/*开启时钟*/
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);		//开启PWR的时钟
															//停止模式和待机模式一定要记得开启
	
	/*显示静态字符串*/
	OLED_ShowString(1, 1, "Count:");
	
	while (1)
	{
		OLED_ShowNum(1, 7, CountSensor_Get(), 5);			//OLED不断刷新显示CountSensor_Get的返回值
		
		OLED_ShowString(2, 1, "Running");					//OLED闪烁Running,指示当前主循环正在运行
		Delay_ms(100);
		OLED_ShowString(2, 1, "       ");
		Delay_ms(100);
		
		PWR_EnterSTOPMode(PWR_Regulator_ON, PWR_STOPEntry_WFI);	//STM32进入停止模式,并等待中断唤醒
		SystemInit();										//唤醒后,要重新配置时钟
	}
}

4.待机模式

main.c

cpp 复制代码
#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"
#include "MyRTC.h"

int main(void)
{
	/*模块初始化*/
	OLED_Init();		//OLED初始化
	MyRTC_Init();		//RTC初始化
	
	/*开启时钟*/
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);		//开启PWR的时钟
															//停止模式和待机模式一定要记得开启
	
	/*显示静态字符串*/
	OLED_ShowString(1, 1, "CNT :");
	OLED_ShowString(2, 1, "ALR :");
	OLED_ShowString(3, 1, "ALRF:");
	
	/*使能WKUP引脚*/
	PWR_WakeUpPinCmd(ENABLE);						//使能位于PA0的WKUP引脚,WKUP引脚上升沿唤醒待机模式
	
	/*设定闹钟*/
	uint32_t Alarm = RTC_GetCounter() + 10;			//闹钟为唤醒后当前时间的后10s
	RTC_SetAlarm(Alarm);							//写入闹钟值到RTC的ALR寄存器
	OLED_ShowNum(2, 6, Alarm, 10);					//显示闹钟值
	
	while (1)
	{
		OLED_ShowNum(1, 6, RTC_GetCounter(), 10);	//显示32位的秒计数器
		OLED_ShowNum(3, 6, RTC_GetFlagStatus(RTC_FLAG_ALR), 1);		//显示闹钟标志位
		
		OLED_ShowString(4, 1, "Running");			//OLED闪烁Running,指示当前主循环正在运行
		Delay_ms(100);
		OLED_ShowString(4, 1, "       ");
		Delay_ms(100);
		
		OLED_ShowString(4, 9, "STANDBY");			//OLED闪烁STANDBY,指示即将进入待机模式
		Delay_ms(1000);
		OLED_ShowString(4, 9, "       ");
		Delay_ms(100);
		
		OLED_Clear();								//OLED清屏,模拟关闭外部所有的耗电设备,以达到极度省电
		
		PWR_EnterSTANDBYMode();						//STM32进入停止模式,并等待指定的唤醒事件(WKUP上升沿或RTC闹钟)
		/*待机模式唤醒后,程序会重头开始运行*/
	}
}

接线图

相关推荐
Wallace Zhang2 小时前
STM32F103_Bootloader程序开发11 - 实现 App 安全跳转至 Bootloader
stm32·嵌入式硬件·安全
GodKK老神灭2 小时前
STM32 CCR寄存器
stm32·单片机·嵌入式硬件
杰克逊的日记9 天前
MCU编程
单片机·嵌入式硬件
Python小老六9 天前
单片机测ntc热敏电阻的几种方法(软件)
数据库·单片机·嵌入式硬件
懒惰的bit9 天前
STM32F103C8T6 学习笔记摘要(四)
笔记·stm32·学习
HX科技10 天前
STM32给FPGA的外挂FLASH进行升级
stm32·嵌入式硬件·fpga开发·flash·fpga升级
Suagrhaha10 天前
驱动入门的进一步深入
linux·嵌入式硬件·驱动
国科安芯10 天前
基于ASP4644多通道降压技术在电力监测系统中集成应用与发展前景
嵌入式硬件·硬件架构·硬件工程
Li Zi10 天前
STM32 ADC(DMA)双缓冲采集+串口USART(DMA)直接传输12位原始数据到上位机显示并保存WAV格式音频文件 收藏住绝对实用!!!
经验分享·stm32·单片机·嵌入式硬件
进击的程序汪10 天前
触摸屏(典型 I2C + Input 子系统设备)从设备树解析到触摸事件上报
linux·网络·嵌入式硬件