当前位置: 首页 > news >正文

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

extern uint32_t SystemCoreClock;          /*!< System Clock Frequency (Core Clock) */
/**当前的主频*/

2.SystemInit

extern void SystemInit(void);
/** 初始化系统的硬件设置*/

3.PWR_EnterSTANDBYMode

void PWR_EnterSTANDBYMode(void);
/**进入待机模式*/

4.PWR_EnterSTOPMode

void PWR_EnterSTOPMode(uint32_t PWR_Regulator, uint8_t PWR_STOPEntry);
/**停止模式的唤醒  */

5.PWR_WakeUpPinCmd

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

6.RTC_SetAlarm

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

代码

1.修改主频

main.c

#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

#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

#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

#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;			//闹钟为唤醒后当前时间的后10sRTC_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闹钟)/*待机模式唤醒后,程序会重头开始运行*/}
}

接线图

 

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 无限边界:现代整合安全如何保护云
  • Unity 设计模式 之 创造型模式-【工厂方法模式】【抽象工厂模式】
  • RTMP协议在无人机巡检中的应用场景
  • Haproxy搭建Web集群
  • 一个基于Java SSM框架(Spring、SpringMVC、MyBatis)的沙县小吃点餐系统
  • 【网站架构部署与优化】web服务与http协议
  • RockTrack:A 3D Robust Multi-Camera-Ken Multi-Object Tracking Framework
  • Oracle事物
  • 计算机人工智能前沿进展-大语言模型方向-2024-09-18
  • Hexo框架学习——从安装到配置
  • HTB-Blue(永恒之蓝漏洞复现)
  • 更换UFS绑定固件与“工程固件”的区别 小米10s机型更换cpu绑定包对比 写入以及修复基带
  • 【C++】猜数字小游戏
  • Hotohiko Sakamoto算法,以及用其计算星期几【算法 15】
  • Vue 中阻止点击事件穿透
  • ES6语法详解(一)
  • JavaScript 是如何工作的:WebRTC 和对等网络的机制!
  • js
  • js对象的深浅拷贝
  • JS专题之继承
  • LeetCode刷题——29. Divide Two Integers(Part 1靠自己)
  • PyCharm搭建GO开发环境(GO语言学习第1课)
  • Solarized Scheme
  • spring-boot List转Page
  • web标准化(下)
  • 阿里云购买磁盘后挂载
  • 配置 PM2 实现代码自动发布
  • 扫描识别控件Dynamic Web TWAIN v12.2发布,改进SSL证书
  • 使用权重正则化较少模型过拟合
  • 手机app有了短信验证码还有没必要有图片验证码?
  • 小程序01:wepy框架整合iview webapp UI
  • shell使用lftp连接ftp和sftp,并可以指定私钥
  • 整理一些计算机基础知识!
  • ​Linux·i2c驱动架构​
  • ​卜东波研究员:高观点下的少儿计算思维
  • $ is not function   和JQUERY 命名 冲突的解说 Jquer问题 (
  • (173)FPGA约束:单周期时序分析或默认时序分析
  • (2)MFC+openGL单文档框架glFrame
  • (7) cmake 编译C++程序(二)
  • (Bean工厂的后处理器入门)学习Spring的第七天
  • (C#)Windows Shell 外壳编程系列4 - 上下文菜单(iContextMenu)(二)嵌入菜单和执行命令...
  • (七)Activiti-modeler中文支持
  • (转) Android中ViewStub组件使用
  • (转)利用ant在Mac 下自动化打包签名Android程序
  • .NET Conf 2023 回顾 – 庆祝社区、创新和 .NET 8 的发布
  • .net on S60 ---- Net60 1.1发布 支持VS2008以及新的特性
  • .Net转Java自学之路—基础巩固篇十三(集合)
  • .vimrc 配置项
  • /proc/vmstat 详解
  • @angular/cli项目构建--Dynamic.Form
  • [3D游戏开发实践] Cocos Cyberpunk 源码解读-高中低端机性能适配策略
  • [5] CUDA线程调用与存储器架构
  • [android] 看博客学习hashCode()和equals()
  • [Big Data - Kafka] kafka学习笔记:知识点整理
  • [BJDCTF2020]The mystery of ip1