13:STM32----PWR

目录

一:PWR

1:简历

2:电源框图

3:低功耗模式

4:模式选择

5:低功耗模式注意事项

A:睡眠模式

B:停止模式

C:待机模式

二 : 案例

A:修改主频

1:连接图

2:代码

B:睡眠模式+串口发送+接收 

1:连接图

2:代码

C:停止模式+对射式红外传感器计次 

1:连接图

2:函数介绍​​​​​​​

3:代码

D: 待机模式+实时时钟

1:连接图

2:代码


一:PWR

1:简历

        PWR(Power Control)电源控制

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

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

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

2:电源框图

VDD :  右边部分是VDD通过电压调节器,降压到1.8V ;   电压调节器,它的作用是给1.8V区域供电

3:低功耗模式

HSL和HSE : HSI内部高速时钟和HSE外部高速时钟

关闭电路通常有两个做法 :  一个是关闭时钟,另一个是关闭电源

关闭时钟-------所有的运算和涉及时序的操作都会暂停,  但是寄存器和存储器里面保存的数据还可以维持,不会消失

关闭电源--------就是电路直接断电 ,  电路的操作和数据都会直接丢失 .   所以关闭电源,比关闭时钟更省电

电压调节器:  电压调节器是把VDD的电压降低到了1.8V,  然后电压调节器给1.8V区域的供电   ;   电压调节器相当于1.8V供电区域的电池;  关闭电压调节器 , 1.8V供电区域的都不能使用;

睡眠 :       WFI--------任何外设发生任何中断时,芯片都会立刻醒来  ,  因为中断发生了,所以醒来之后的第一件事一般就是处理中断函数

        WFE------等待事件 ,  对应的唤醒条件是: 唤醒事件  ,  这个事件可以是外部中断配置为事件模式 ;  也可以是使能到中断,但是没有配置NVIC ,  调用WFE进入的睡眠模式 ,产生唤醒事件时,会立刻醒来 , 醒来之后,一般不需要进中断函数  ,  直接从睡的地方继续运行

        睡眠模式只是把1.8V区域的CPU时钟关闭

4:模式选择

5:低功耗模式注意事项

A:睡眠模式

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

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

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

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

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

B:停止模式

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

           HSL和HSE : HSI内部高速时钟和HSE外部高速时钟

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

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

        当一个中断或唤醒事件导致退出停止模式时,HSI被选为系统时钟  -------- 你程序刚上电,是72MHz的主频 , 但是进入停止模式,再唤醒之后  ,  就变成8MHz的主频了;  所以,我们一般在停止模式唤醒后 , 第一时间就是重新启动HSE,配置主频为72MHz ,  我们只需要再调用一下Systemlnit就行

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

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

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

C:待机模式

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

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

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

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

        它并不会主动关闭LSI和LSE两个低速时钟 , 因为这两个时钟还要维持RTC和独立看门狗的运行

二 : 案例

A:修改主频

1:连接图

2:代码

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

/*STM32默认的是72KH的主频
#define SYSCLK_FREQ_72MHz  72000000*/
int main(void)
{
	OLED_Init();
	OLED_ShowString(1, 1, "SystemCoreClock:");
	OLED_ShowSignedNum(2,1,SystemCoreClock,8);
	
	while (1)
	{
		OLED_ShowString(3, 1, "Running:");
		Delay_ms(500);
		OLED_ShowString(3, 1, "        ");
		Delay_ms(500);
	}
}

        主要是在 : 2个文件中操作 ,  ( 如果文件上面有🔑的话 , 需要线解除只读模式),  文件主要给我们提供了一个可以调用的全局变量, 和2个函数 ;   

        修改主频 : 默认使用的是72000000HZ的主频 , 

        注意修改主频要谨慎,  一些计算都和主频相关 ,  主频修改后计算也要进行更改

        

        选择外部8M晶振作为锁相环输入 ,  锁相环执行9倍频输出的72M,选择为SYSCLK

        SystemCoreClock------系统的全局变量 , 用于显示系统的主频

B:睡眠模式+串口发送+接收 

1:连接图

2:代码

        在串口发送+接收的代码上进行改进的.   详情参考 : 09:STM32-------USART串口通信+串口数据包----B:串口发送+接收----4:串口发送+接收 -----中断代码

#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, 3);
		}
			OLED_ShowString(2, 1, "Running:");
			Delay_ms(500);
			OLED_ShowString(2, 1, "         ");
			Delay_ms(500);
		__WFI();
	}
}

        WFI--------任何外设发生任何中断时,芯片都会立刻醒来  ,  因为中断发生了,所以醒来之后的第一件事一般就是处理中断函数

        首先,睡眠模式,这是可以的 ,  CPU时钟关闭,程序不再执行 .  但是外设的时钟不会 关 .   USART便件电路还是可以接收数据的 ,  USART收到数据后,产生中断,唤醒CPU

        停机模式 : 这个模式下,所有1.8V区域的时钟都关了 ,  CPU和外设都不能运行 , 那自然USART也收不到数据,产生不了中断 ,所以这个模式不行

C:停止模式+对射式红外传感器计次 

1:连接图

2:函数介绍

        睡眠模式其实都只是内核的操作,  睡眠模式涉及的几个寄存器 , 也都在内核里 跟PWR外设关系不大.  

        停止模式 : 涉及到内核之外的电路操作,  这就需要用到PWR外设了

在stm32f10x_pwr.h文件中----启用或禁用对RTC和备份寄存器的访问。

void PWR_BackupAccessCmd(FunctionalState NewState);

        使能后备区域的访问

在stm32f10x_pwr.h文件中----启用或禁用唤醒引脚功能

void PWR_WakeUpPinCmd(FunctionalState NewState);

        使能位于PAO位置的WKUP引脚

在stm32f10x_pwr.h文件中----进入STOP模式

void PWR_EnterSTOPMode(uint32_t PWR_Regulator, uint8_t PWR_STOPEntry);
 

        进入停止模式

在stm32f10x_pwr.h文件中----待机模式

void PWR_EnterSTANDBYMode(void)

 在stm32f10x_pwr.h文件中----关于标志位的函数

FlagStatus PWR_GetFlagStatus(uint32_t PWR_FLAG);
void PWR_ClearFlag(uint32_t PWR_FLAG);

PWR_GetFlagStatus  :  获取标志位

PWR_ClearFlag :  清除标志位

3:代码

在对射式红外传感器计次的代码上进行更改 .  详情参考 : 02:STM32--EXTI外部中断----A:对外式红外传感计数器

#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);

	OLED_ShowString(1, 1, "Count:");
	
	while (1)
	{
		OLED_ShowNum(1, 7, CountSensor_Get(), 5);
		OLED_ShowString(2, 1, "Running:");
		Delay_ms(500);
		OLED_ShowString(2, 1, "         ");
		Delay_ms(500);
		
		PWR_EnterSTOPMode(PWR_Regulator_ON,PWR_STOPEntry_WFI);//进入停止模式
		/*
		当一个中断或唤醒事件导致退出停止模式时,HSI被选为系统时钟
		你程序刚上电,是72MHz的主频 ,但是进入停止模式,再唤醒之后
		就变成8MHz的主频了; 所以,我们一般在停止模式唤醒后 
		第一时间就是重新启动HSE,配置主频为72MHz ,我们只需要再调用一下Systemlnit就行
		*/
		SystemInit();
	}
}

          当一个中断或唤醒事件导致退出停止模式时,HSI被选为系统时钟  -------- 你程序刚上电,是72MHz的主频 , 但是进入停止模式,再唤醒之后  ,  就变成8MHz的主频了;  所以,我们一般在停止模式唤醒后 , 第一时间就是重新启动HSE,配置主频为72MHz ,  我们只需要再调用一下Systemlnit就行

        这个代码可以使用外部中断触发唤醒 ,  所以我们可以让它进入更为省电的停止模式 .  在停止模式下1.8V区域的时钟关闭 , CPU和外设都没有时钟了 , 但是外部中断的工作是不需要时钟的

D: 待机模式+实时时钟

1:连接图

2:代码

对实时时钟的代码进行改进     详情参考 : 12:STM32---RTC实时时钟----B:实时时钟

#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:");
	//开启WAUP--PA0的引脚触发
	PWR_WakeUpPinCmd(ENABLE);
	
	uint32_t Alarm = RTC_GetCounter() + 10;   //写RTC计数器
	RTC_SetAlarm(Alarm);   //设置RTC的闹钟
	OLED_ShowNum(2, 6, Alarm, 10);
	
	while (1)
	{
		OLED_ShowNum(1, 6, RTC_GetCounter(), 10);
		/*
		之后,随着CNT的增大 , CNT会和ALR(RTC_SetAlarm)相等 , 然后触发闹钟标志位置1
		*/
		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(100);
		
		OLED_Clear();
		//进入待机模式
		PWR_EnterSTANDBYMode();
	}
}

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值