• 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:代码

    1. #include "stm32f10x.h" // Device header
    2. #include "Delay.h"
    3. #include "OLED.h"
    4. /*STM32默认的是72KH的主频
    5. #define SYSCLK_FREQ_72MHz 72000000*/
    6. int main(void)
    7. {
    8. OLED_Init();
    9. OLED_ShowString(1, 1, "SystemCoreClock:");
    10. OLED_ShowSignedNum(2,1,SystemCoreClock,8);
    11. while (1)
    12. {
    13. OLED_ShowString(3, 1, "Running:");
    14. Delay_ms(500);
    15. OLED_ShowString(3, 1, " ");
    16. Delay_ms(500);
    17. }
    18. }

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

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

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

            

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

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

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

    1:连接图

    2:代码

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

    1. #include "stm32f10x.h" // Device header
    2. #include "Delay.h"
    3. #include "OLED.h"
    4. #include "Serial.h"
    5. uint8_t RxData;
    6. int main(void)
    7. {
    8. OLED_Init();
    9. OLED_ShowString(1, 1, "RxData:");
    10. serial_init();
    11. while (1)
    12. {
    13. if (Serial_GetRxFlag() == 1)
    14. {
    15. RxData = Serial_GetRxData();
    16. Serial_SendByte(RxData);
    17. OLED_ShowHexNum(1, 8, RxData, 3);
    18. }
    19. OLED_ShowString(2, 1, "Running:");
    20. Delay_ms(500);
    21. OLED_ShowString(2, 1, " ");
    22. Delay_ms(500);
    23. __WFI();
    24. }
    25. }

            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:对外式红外传感计数器

    1. #include "stm32f10x.h" // Device header
    2. #include "Delay.h"
    3. #include "OLED.h"
    4. #include "CountSensor.h"
    5. int main(void)
    6. {
    7. OLED_Init();
    8. CountSensor_Init();
    9. RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);
    10. OLED_ShowString(1, 1, "Count:");
    11. while (1)
    12. {
    13. OLED_ShowNum(1, 7, CountSensor_Get(), 5);
    14. OLED_ShowString(2, 1, "Running:");
    15. Delay_ms(500);
    16. OLED_ShowString(2, 1, " ");
    17. Delay_ms(500);
    18. PWR_EnterSTOPMode(PWR_Regulator_ON,PWR_STOPEntry_WFI);//进入停止模式
    19. /*
    20. 当一个中断或唤醒事件导致退出停止模式时,HSI被选为系统时钟
    21. 你程序刚上电,是72MHz的主频 ,但是进入停止模式,再唤醒之后
    22. 就变成8MHz的主频了; 所以,我们一般在停止模式唤醒后
    23. 第一时间就是重新启动HSE,配置主频为72MHz ,我们只需要再调用一下Systemlnit就行
    24. */
    25. SystemInit();
    26. }
    27. }

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

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

    D: 待机模式+实时时钟

    1:连接图

    2:代码

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

    1. #include "stm32f10x.h" // Device header
    2. #include "Delay.h"
    3. #include "OLED.h"
    4. #include "MYRTC.h"
    5. int main(void)
    6. {
    7. OLED_Init();
    8. MYRTC_init();
    9. RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);
    10. OLED_ShowString(1, 1, "CNT :");
    11. OLED_ShowString(2, 1, "ALR :");
    12. OLED_ShowString(3, 1, "ALRF:");
    13. //开启WAUP--PA0的引脚触发
    14. PWR_WakeUpPinCmd(ENABLE);
    15. uint32_t Alarm = RTC_GetCounter() + 10; //写RTC计数器
    16. RTC_SetAlarm(Alarm); //设置RTC的闹钟
    17. OLED_ShowNum(2, 6, Alarm, 10);
    18. while (1)
    19. {
    20. OLED_ShowNum(1, 6, RTC_GetCounter(), 10);
    21. /*
    22. 之后,随着CNT的增大 , CNT会和ALR(RTC_SetAlarm)相等 , 然后触发闹钟标志位置1
    23. */
    24. OLED_ShowNum(3, 6, RTC_GetFlagStatus(RTC_FLAG_ALR), 1); //闹钟
    25. OLED_ShowString(4, 1, "Running");
    26. Delay_ms(100);
    27. OLED_ShowString(4, 1, " ");
    28. Delay_ms(100);
    29. OLED_ShowString(4, 9, "STANDBY");
    30. Delay_ms(1000);
    31. OLED_ShowString(4, 9, " ");
    32. Delay_ms(100);
    33. OLED_Clear();
    34. //进入待机模式
    35. PWR_EnterSTANDBYMode();
    36. }
    37. }

  • 相关阅读:
    深入理解 python 虚拟机:字节码教程(2)——控制流是如何实现的?
    GIS 制图:交互式地图的类型和应用
    集合、List、Set、Map、Collections、queue、deque
    [UDS] --- DiagnosticSessionControl 0x10 service
    外包干了3个月,技术确实退步明显
    计算机网络笔记
    【一周安全资讯1118】北京高院发布《侵犯公民个人信息犯罪审判白皮书》;工银金融勒索案的事件响应服务商MoxFive是谁?
    全景描绘云原生技术图谱,首个《云原生应用引擎技术发展白皮书》发布
    【深度学习】 Python 和 NumPy 系列教程(十六):Matplotlib详解:2、3d绘图类型(2)3D散点图(3D Scatter Plot)
    基于昇思MindQuantum, 实现微分方程求解
  • 原文地址:https://blog.csdn.net/m0_74739916/article/details/133276765