打印
[应用相关]

STM32-PWR低功耗

[复制链接]
203|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
tpgf|  楼主 | 2024-11-11 16:54 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
一、概述
PWR(Power Control)电源控制,PWR负责管理STM32内部的电源供电部分,可以实现可编程电压监测器和低功耗模式的功能
可编程电压监测(PVD)可以监控VDD电源电压,当VDD下降到PVD阀值以下或上升到PVD阀值之上时,PVD会触发中断,用于执行紧急关闭任务
低功耗模式包括睡眠模式(Sleep)、停机模式(Stop)和待机模式(Standby),可在系统空闲时,降低STM32的功耗,延长设备使用时间
1、电源框图
1.8V供电区域有CPU核心存储器和内置数字外设(如USART、I2C、SPI等),通过电压调节器进行控制着电压。

低电压检测器进行检测VDD电压的,当检测到VDD断电时,开关会切换到VBT来供电。



2、上电复位和掉电复位
当VDD/VDDA低于指定的限位电压VPOR/VPDR时,系统保持为复位状态,而无需外部复位电路



3、可编程电压监测器PVD:
用户可以利用PVD对VDD电压与电源控制寄存器(PWR_CR)中的PLS[2:0]位进行比较来监控电源,这几位选择监控电压的阀值。

通过设置PVDE位来使能PVD。

电源控制/状态寄存器(PWR_CSR)中的PVDO标志用来表明VDD是高于还是低于PVD的电压阀值。该事件在内部连接到外部中断的第16线,如果该中断在外部中断寄存器中是使能的,该事件就会产生中断。当VDD下降到PVD阀值以下和(或)当VDD上升到PVD阀值之上时,根据外部中断第16线的上升/下降边沿触发设置,就会产生PVD中断。例如,这一特性可用于用于执行紧急关闭任务。



4、低功耗模式
睡眠模式是浅睡眠状态,停机和待机深睡眠状态。



5、 模式选择
具体内容可以查看手册。



睡眠模式:

执行完WFI/WFE指令后,STM32进入睡眠模式,程序暂停运行,唤醒后程序从暂停的地方继续运行
SLEEPONEXIT位决定STM32执行完WFI或WFE后,是立刻进入睡眠,还是等STM32从最低优先级的中断处理程序中退出时进入睡眠 在睡眠模式下,所有的I/O引脚都保持它们在运行模式时的状态
WFI指令进入睡眠模式,可被任意一个NVIC响应的中断唤醒
WFE指令进入睡眠模式,可被唤醒事件唤醒
停机模式:

执行完WFI/WFE指令后,STM32进入停止模式,程序暂停运行,唤醒后程序从暂停的地方继续运行 1.8V供电区域的所有时钟都被停止,PLL、HSI和HSE被禁止,SRAM和寄存器内容被保留下来
在停止模式下,所有的I/O引脚都保持它们在运行模式时的状态
当一个中断或唤醒事件导致退出停止模式时,HSI被选为系统时钟 。当电压调节器处于低功耗模式下,系统从停止模式退出时,会有一段额外的启动延时
WFI指令进入停止模式,可被任意一个EXTI中断唤醒
WFE指令进入停止模式,可被任意一个EXTI事件唤醒
待机模式:

执行完WFI/WFE指令后,STM32进入待机模式,唤醒后程序从头开始运行 整个1.8V供电区域被断电,PLL、HSI和HSE也被断电,SRAM和寄存器内容丢失,只有备份的寄存器和待机电路维持供电
在待机模式下,所有的I/O引脚变为高阻态
WKUP引脚的上升沿、RTC闹钟事件的上升沿、NRST引脚上外部复位、IWDG复位退出待机模式
二、睡眠模式代码
利用的是串口接收中断唤醒的。

main.c:

#include  "stm32f10x.h"                  // Device header
#include  "OLED.h"
#include  "delay.h"
#include  "Serial.h"
#include  "stdio.h"

extern char String[16];
uint16_t Serial_Rxdata;
int main(void)
{
       

   OLED_Init();
        Serial_Init();

        OLED_ShowString(1,1,"RXData:");
       
        while(1)
        {
         if(Serial_GetRxFlag()==1)
                        {
                                Serial_Rxdata=Serial_GetRxData();
                                Serial_SendByte(Serial_Rxdata);
                                OLED_ShowHexNum(1,8,Serial_Rxdata,2);
                               
                        }
                        OLED_ShowString(2,1,"Running");
                        Delay_ms(100);
                        OLED_ShowString(2,1,"       ");
                        Delay_ms(100);
                       
                        __WFI();    //默认使用的是立即睡眠
        }
       
}

三、停机模式代码
利用对射红外传感器进行外部中断唤醒。

main.c:

#include  "stm32f10x.h"                  // Device header
#include  "OLED.h"
#include  "LED.h"
#include  "delay.h"
#include  "CountSensor.h"


uint16_t CountSensor_GetNum=0;

int main(void)
{
       
   OLED_Init();
       
   LED_Init();
       
        CountSensor_Init();
       
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR,ENABLE);
       
        OLED_ShowString(1,1,"Count:");
        while(1)
        {
     CountSensor_GetNum=CountSensor_Get();
     OLED_ShowNum(1,8,CountSensor_GetNum,4);
          OLED_ShowString(2,1,"Running");
          Delay_ms(200);
          OLED_ShowString(2,1,"       ");
          Delay_ms(200);
          LED1_ON();
          PWR_EnterSTOPMode(PWR_Regulator_ON, PWR_STOPEntry_WFI);
          //当一个中断或唤醒事件导致退出停止模式时,HSI(8MHz)被选为系统时钟
          SystemInit();
               
        }
       
}

四、待机模式代码
利用RTC闹钟和WKUP引脚来进行唤醒。

main.c:

#include  "stm32f10x.h"                  // Device header
#include  "OLED.h"
#include  "LED.h"
#include  "delay.h"
#include  "MyRTC.h"


Time_Value Time_Data={2024,11,1,19,30,0};

//在编程中数字以0开头往往表示八进制

int main(void)
{
       
        uint32_t Alarm;
       
       
   OLED_Init();
        MyRTC_Init(&Time_Data);
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR,ENABLE);
       
        OLED_ShowString(1,1,"CNT:");
        OLED_ShowString(2,1,"ALR:");
        OLED_ShowString(3,1,"ALRF:");
        LED_Init();
       
        Alarm=RTC_GetCounter()+10;
        RTC_SetAlarm(Alarm);
        OLED_ShowNum(2,6,Alarm,10);
        PWR_WakeUpPinCmd(ENABLE);
        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(1000);
                 OLED_ShowString(4,1,"       ");
                 Delay_ms(100);
                //待机模式下,程序从头开始运行
                //OLED_Clear();
                LED1_ON();
                 PWR_EnterSTANDBYMode();
        }
       
}

————————————————

                            版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

原文链接:https://blog.csdn.net/m0_69808624/article/details/143579816

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

1931

主题

15650

帖子

12

粉丝