PWR电源控制

一.PWR基本信息

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

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

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

1.电源框图

VDDA供电区域: 主要负责模拟部分供电(A/D转换器,温度传感器,复位模块,PLL);使用VDDA(正极)/VSSA(负极)供电引脚
VDD供电区域: 左边区域:I/O电路,待机电路(唤醒逻辑,IWDG);
1.8V供电区域: 通过电压调节器进入1.8V供电区域(CPU核心,储存器,内置数字外设);使用VSS/VDD引脚
**后备供电区域:**LSE 32K晶体振荡器,后备寄存器,RCC BDCR寄存器,RTC;使用VBAT供电引脚

2.低功耗模式

睡眠: WFI(等待中断),任何外设发生任意中断,芯片就会醒来

WFE(等待事件),可以是外部中断的事件模式或者没有配置NVIC的使能中断

睡眠模式会使1.8V区域时钟CPU时钟关闭其他无影响,VDD区域无影响,电压调节器开
停机: 把SLEEPDEEP置1设置PDDS=0,配置WFI,WFE,LPDS=0(电压调节器开)LPDS=1(电压调节器低功耗),外部中断才能唤醒,关闭所有1.8V区域时钟,VDD区域HSI\HSE的振荡器关闭,电压调节器开启或者处于低功耗
待机: 把SLEEPDEEP置1,设置PDDS=1,配置WFI,WFE,WKUP引脚上升沿\RTC闹钟事件\NRST引脚的外部复位\IWDG复位,1.8V的时钟关闭,VDD区域HSI\HSE的振荡器关闭,电压调节器关闭

PDDS=0停机模式

PDDS=1待机模式

3.基本流程

修改主频: 调用SystemCoreClock函数之后修改主频
睡眠模式: 调用__WFI();进入睡眠模式发送数据显示数据否则数据不会显示
停止模式: 开启PWR时钟,调用PWR_EnterSTOPMode();函数进入停止模式
待机模式: 设置闹钟,开启待机模式,使用闹钟信号唤醒待机模式

Wakeup();函数接高电平唤醒

待机模式时因为属于低功耗可能在部分显示屏上不显示数据属于正常,只要代码内部能跑就行

二.代码实现(只写main.c)

1.修改主频

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);//调用SystemCoreClock函数显示主频
	
	while(1)
	{
		//每隔500ms显示Running
        OLED_ShowString (2,1,"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_ShowString(1,1,"RxData:");
	
	Serial_Init();
	
	
	
	while(1)
	{
      if(Serial_GetRxFlag() == 1)
	  {
		  RxData = Serial_GetRxData();//串口接收接受数据赋值给RxDAta
		  Serial_SendByte (RxData);//串口发送数据
		  OLED_ShowHexNum (1,8,RxData,2);
	  }
	  
	  //发送数据之后闪烁Running
	  OLED_ShowString (2,1,"Running");
	  Delay_ms(500);
	  OLED_ShowString (2,1,"       ");
	  Delay_ms(500);
	  
	  __WFI();//启动睡眠模式
    }
}

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

main.c

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

int main(void)
{
	RCC_APB1PeriphClockCmd (RCC_APB1Periph_PWR ,ENABLE );//开启PWR时钟
	
	OLED_Init ();
	CountSensor_Init();

	OLED_ShowString(1,1,"count:");

	while(1)
	{
       OLED_ShowNum(1,7,Sensor_GetCount(),5);
		
		OLED_ShowString(2,1,"Running");
		Delay_ms(100);
		OLED_ShowString(2,1,"       ");
		Delay_ms(100);
		
		PWR_EnterSTOPMode(PWR_Regulator_ON,PWR_STOPEntry_WFI);//停止模式开启电压调制器睡眠模式选择WFI
		SystemInit ();//重新配置时钟
    }
}

4.待机模式+RTC实时时钟

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 );//开启PWR时钟
	
	OLED_ShowString (1,1,"CNT:");//秒计数器
	OLED_ShowString (2,1,"ALM:");//闹钟
	OLED_ShowString (3,1,"ALMF:");//闹钟标志位
	
//	PWR_WakeUpPinCmd(ENABLE );//开启上升沿触发
	
	uint32_t Alarm;
	Alarm = RTC_GetCounter() + 10;//闹钟时间设置秒计数器时间加10
	RTC_SetAlarm(Alarm);//闹钟值写入闹钟
	OLED_ShowNum (2,6,Alarm,10);//显示闹钟
	
	while(1)
	{
        OLED_ShowNum (1,6,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,"Standby");
		Delay_ms(1000);
		OLED_ShowString (4,9,"       ");
		Delay_ms(100);
		
		OLED_Clear ();
		
		PWR_EnterSTANDBYMode();//启动待机模式
    }
}
相关推荐
Zw-awa12 小时前
什么是IMU:两颗传感器、一件别人替代不了的事,MPU6050、IMU660RA、JY901S等模块有何区别
stm32
希和202715 小时前
江科大 51 单片机课程笔记:DS1302 实时时钟 + LCD1602 可调电子钟(小白逐行讲解)
笔记·单片机·嵌入式硬件
女神下凡15 小时前
芯参谋(107):杰理AC_中科蓝讯_开发指南
linux·服务器·网络·单片机·嵌入式硬件
shimly12345617 小时前
(done) 嵌入式硬件电路图 (11) 用 AI 看电路图与总结
嵌入式硬件
shimly12345617 小时前
(done) 嵌入式硬件电路图 (12) 学习总结与工作建议
嵌入式硬件
another heaven1 天前
【C/C++ 第一次跨越(上):用 C++11/14 停止制造新的旧代码】
c语言·c++·制造
威嵌神州1 天前
嵌入式排故实录:高并发下串口数据“超时丢包”的根因剖析与架构优化
运维·服务器·嵌入式硬件·缓存
Zw-awa2 天前
MPU6050:从原始加速度到姿态变化
stm32
another heaven2 天前
【C/C++ Ranges 是零开销抽象吗?拆开管道、惰性求值和编译期膨胀】
c语言·开发语言·c++
Code_Solitude2 天前
C语言动态内存 + 柔性数组 + 数组名退化
c语言·算法·柔性数组