自学内容网 自学内容网

【STM32-学习笔记-12-】PWR电源控制

PWR电源控制

一、PWR简介

  • PWR(Power Control)电源控制

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

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

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

二、STM32电源框图

image-20250116132436703

Ⅰ、上电复位和掉电复位

image-20250116133205426

Ⅱ、PVD可编程电压监测器

image-20250116133232401

三、STM32的低功耗模式

image-20250116134555295

Ⅰ、睡眠模式(Sleep Mode)

  • 进入方式

    • 使用WFI(Wait For Interrupt)指令进入睡眠模式
    • 使用WFE(Wait For Event)指令进入睡眠模式
  • 唤醒方式

    • 任一中断可以唤醒使用WFI指令进入的睡眠模式
    • 唤醒事件可以唤醒使用WFE指令进入的睡眠模式
  • 对时钟的影响

    • CPU时钟关闭,但对其他时钟(如总线时钟、外设时钟)和ADC时钟无影响
  • 电压调节器:开启

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

Ⅱ、停机模式(Stop Mode)

  • 进入方式

    • 设置PDDS(Power Down Deep Sleep)和LPDS(Low Power Deep Sleep)位
      • PDDS:用于区分是停机模式还是待机模式
        • PDDS位为0时,进入停机模式
      • LPDS:用于设置最后的电压调节器是开启还是进入低功耗模式
        • LPDS位为1时,电压调节器进入低功耗模式;当LPDS位为0时,电压调节器开启
    • 设置SLEEPDEEP
      • 用于选择睡眠模式还是深度睡眠模式(待机/停机)
        • SLEEPDEEP位为1时,选择深度睡眠模式
        • 停机模式时,需要将SLEEPDEEP位置位
    • 使用WFIWFE指令进入停机模式
  • 唤醒方式

    • 任一外部中断(需要在外部中断寄存器中设置)
  • 对时钟的影响

    • 关闭所有1.8V区域的时钟
    • HSI和HSE的振荡器关闭
  • 电压调节器:可以开启或处于低功耗模式,取决于电源控制寄存器(PWR_CR)的设定

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

Ⅲ、待机模式(Standby Mode)

  • 进入方式

    • 设置PDDS
    • 设置SLEEPDEEP
    • 使用WFIWFE指令进入待机模式
  • 唤醒方式

    • WKUP引脚的上升沿
    • RTC闹钟事件
    • NRST引脚上的外部复位
    • IWDG(Independent Watchdog)复位
  • 对时钟的影响

    • 关闭所有1.8V区域的时钟
    • HSI和HSE的振荡器关闭
  • 电压调节器:关闭

    1. 执行完WFI/WFE指令后,STM32进入待机模式,唤醒后程序从头开始运行
    2. 整个1.8V供电区域被断电,PLL、HSI和HSE也被断电,SRAM和寄存器内容丢失,只有备份的寄存器和待机电路维持供电
    3. 在待机模式下,所有的I/O引脚变为高阻态(浮空输入)
    4. WKUP引脚的上升沿、RTC闹钟事件的上升沿、NRST引脚上外部复位、IWDG复位退出待机模式

在待机模式简介中,停机模式要操控的标志位包括:

  1. PDDS位:设置停机还是待机模式。0为停机模式、设置为1为待机模式
  2. SLEEPDEEP位:设置是否进入深度睡眠模式。1 为进入

image-20250116152533193

四、PWR函数

// 重置PWR寄存器为默认值
void PWR_DeInit(void);

// 使能或失能对备份寄存器(BKP)的访问
void PWR_BackupAccessCmd(FunctionalState NewState);

// 使能或失能电源电压检测器(PVD)
void PWR_PVDCmd(FunctionalState NewState);

// 配置电源电压检测器(PVD)阈值
void PWR_PVDLevelConfig(uint32_t PWR_PVDLevel);

// 使能或失能唤醒引脚(配合待机模式使用)
void PWR_WakeUpPinCmd(FunctionalState NewState);

// 进入停止模式
void PWR_EnterSTOPMode(uint32_t PWR_Regulator, uint8_t PWR_STOPEntry);

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

// 获取PWR标志位状态
FlagStatus PWR_GetFlagStatus(uint32_t PWR_FLAG);
// 清除PWR标志位
void PWR_ClearFlag(uint32_t PWR_FLAG);

函数介绍

函数功能

  • 该函数的作用是使系统进入STOP模式。STOP模式是一种低功耗模式,通常用于在不需要处理数据或执行任务时节省能源

参数说明

  1. PWR_Regulator
  • 这个参数用于指定在STOP模式下*调节器(regulator)*的状态。调节器是电源管理系统的一部分,用于控制电源的供应和管理。它有两个可选值:

    • PWR_Regulator_ON:在STOP模式下,调节器保持开启状态。这意味着电源管理系统将继续为某些关键部件供电,以确保系统能够快速从STOP模式唤醒

    • PWR_Regulator_LowPower:在STOP模式下,调节器进入低功耗模式。这种模式下,电源管理系统会尽可能减少功耗,但可能会导致系统从STOP模式唤醒的速度稍慢

  1. PWR_STOPEntry
  • 这个参数用于指定进入STOP模式的方式,具体是通过WFI(Wait For Interrupt)指令还是WFE(Wait For Event)指令。这两个指令都是ARM架构中的低功耗指令,用于使处理器进入低功耗状态,直到有中断或事件发生时唤醒处理器。它也有两个可选值:

    • PWR_STOPEntry_WFI:通过WFI指令进入STOP模式。WFI指令会使处理器进入低功耗状态,直到有中断发生时唤醒处理器

    • PWR_STOPEntry_WFE:通过WFE指令进入STOP模式。WFE指令会使处理器进入低功耗状态,直到有事件发生时唤醒处理器

五、示例

①、睡眠模式

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

int main(void)
{
uint8_t RxData;
OLED_Init();
Serial_Init();
OLED_ShowString(1,1,"RxData:");

while(1)
    {
if(Serial_GetFlag() == 1)
{
RxData = Serial_GetData();
Serial_SendByte(RxData);
OLED_ShowHexNum(1,8,RxData,2);
}

OLED_ShowString(2,1,"Running");
Delay_ms(100);
OLED_ShowString(2,1,"       ");
Delay_ms(100);

/* */__WFI();//进入睡眠模式(使用USART中断可唤醒)
    }
}

  • 程序运行到__WFI()位置时会进入睡眠模式,使用任意中断都可对其进行唤醒

②、停机模式

#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);//开启PWR的是时钟

    OLED_ShowString(1,1,"Count:");          
    while(1)
    {
OLED_ShowNum(1,7,Ret_Count(),5);
      
OLED_ShowString(2,1,"Running");
Delay_ms(100);
OLED_ShowString(2,1,"       ");
Delay_ms(100);

/**/PWR_EnterSTOPMode(PWR_Regulator_ON, PWR_STOPEntry_WFI);//调用该代码在此处进入停止模式
/**/SystemInit();//唤醒之后主频变为8MHz,需要重新启动72MHz主频
}
}

  • 进入停机模式后,需要外部中断才能将其唤醒

③、待机模式

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


int main(void)
{
    OLED_Init();
MyRTC_Init();

OLED_ShowString(1,1,"CNT:");//秒计数器
OLED_ShowString(2,1,"ALR:");//闹钟值
OLED_ShowString(3,1,"ALRF:");//闹钟标志位

/**/RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);//开启PWR时钟

uint32_t Alarm = RTC_GetCounter() + 10;
RTC_SetAlarm(Alarm);//设定闹钟

/**/PWR_WakeUpPinCmd(ENABLE);//可使用WakeUp引脚唤醒

    while(1)
    {
OLED_ShowNum(1,6,RTC_GetCounter(),10);
OLED_ShowNum(2,6,Alarm,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(1000);

OLED_Clear();

/* */PWR_EnterSTANDBYMode();//程序在此处进入待机模式(可由RTC闹钟事件唤醒)
}
}

  • 关键代码:

  •   /**/RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);//开启PWR时钟
      
      ... ...
      
      /**/PWR_WakeUpPinCmd(ENABLE);//可使用WakeUp引脚唤醒
      
      ... ...
      
      /**/PWR_EnterSTANDBYMode();//程序在此处进入待机模式(可由RTC闹钟事件唤醒)
    

原文地址:https://blog.csdn.net/qq_63040946/article/details/145222564

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!