当前位置:   article > 正文

PWR-低功耗模式-STM32F4_stm32f4 低功耗

stm32f4 低功耗

使用芯片===>STM32F429IGT6

(制作不易,希望大佬能给个赞支持下小丁)


目录

一、低功耗模式简介

1、STM32的3种低功耗模式:

2、在运行模式下降低功耗

3、待机模式详解

4、相关寄存器

二、低功耗

1、HAL库中低功耗操作函数

2、待机唤醒配置步骤

三、待机唤醒实验

1、实验内容

2、实验程序

3、实验结果

四、结束语


一、低功耗模式简介

很多单片机有低功耗模式,STM32也不例外。在系统或者电源复位后,微控制器出于运行状态之下,HCLK为CPU提供时钟,内核执行代码。当CPU不需要继续运行时,可以利用多种低功耗模式来节省功耗,例如等待某个事件触发。

1、STM32的3种低功耗模式:

低功耗模式汇总:
 

​①、睡眠模式:内核停止,外设如NVIC,系统时钟Systick仍运行。  

②、停止模式:所有时钟都已停止。1.2/1.8V内核电源工作。                          

       PLL,HIS和HSE RC振荡器功能禁止。                          

       寄存器和SRAM内容保留。

③、待机模式:1.2/1.8V内核电源关闭。                          

       只有备份寄存器和待机电路维持供电。                          

       寄存器和SRAM内容全部丢失。实现最低功耗。

2、在运行模式下降低功耗

①、降低系统时钟速度

②、不使用 APBx 和 AHBx 外设时,将对应的外设时钟关闭

3、待机模式详解

​一般情况下,用户根据最低电源消耗,最快启动时间和可用的唤醒源等条件,选择一种最佳的低功耗模式。

4、相关寄存器

①、PWR_CR电源控制寄存器

设置PDDS位进入深度睡眠时进入待机模式。

设置CWUF位,清除之前的WUF唤醒位。

②、PWR_CSR电源控制/状态寄存器

​设置EWUP,使能WKUP 引脚用于待机唤醒。

 WUF唤醒标志,用来判断是否发生唤醒事件。

 ③、特别说明(对M4和M7)


二、低功耗

1、HAL库中低功耗操作函数

  1. void HAL_PWR_EnterSTOPMode(uint32_t Regulator, uint8_t STOPEntry);//停止模式
  2. void HAL_PWR_EnterSLEEPMode(uint32_t Regulator, uint8_t SLEEPEntry);//睡眠模式
  3. void HAL_PWR_EnterSTANDBYMode(void);//待机模式
  4. void HAL_PWR_EnableWakeUpPin(uint32_t WakeUpPinPolarity);//使能唤醒模式

2、待机唤醒配置步骤

①、使能电源时钟。     因为要配置电源控制寄存器,所以必须先使能电源时钟。      

         __HAL_RCC_PWR_CLK_ENABLE();         //使能PWR时钟

② 、RTC相关处理:关闭RTC相关中断。

③、设置WK_UP引脚作为唤醒源。    

        设置PWR_CSR的EWUP位,使能WK_UP用于将CPU从待机模式唤醒。    

        void HAL_PWR_EnableWakeUpPin(uint32_t WakeUpPinPolarity)

④、设置SLEEPDEEP位,设置PDDS位,执行WFI指令,进入待机模式。    

        void HAL_PWR_EnterSTANDBYMode();


三、待机唤醒实验

1、实验内容

①、PA0引脚即WakeUp引脚,来控制待机和唤醒模式切换。

②、长按3秒进入待机模式,在待机模式下,长按3秒待机唤醒。

③、主程序主要实现着持续串口输出数据。

④、在待机模式下,数据不会输出出去。

⑤、唤醒后输出数据。

2、实验程序

main.c

  1. /**************************************************************************
  2. **作者: 小丁工程
  3. **时间: 2021.01.18
  4. ***************************************************************************/
  5. #include "sys.h"
  6. //---------------------主函数-------------------------------------------------
  7. int main(void)
  8. {
  9. int a;
  10. HAL_Init();//========================初始化HAL库
  11. Stm32_Clock_Init(360,25,2,8);//======设置时钟,180Mhz
  12. delay_init(180);//===================初始化延时函数
  13. WKUP_Init();//=======================待机唤醒初始化
  14. uart_init(115200);//=================初始化串口
  15. LED_Init();//=========================LED初始化
  16. while(1)
  17. {
  18. a++;
  19. printf("===%d===\r\n",a);
  20. if(a==10000){a=0;}
  21. delay_ms(20);
  22. }
  23. }
  24. //---------------------end-----------------------------------------------------

wkup.c

  1. #include "wkup.h"
  2. //系统进入待机模式
  3. void Sys_Enter_Standby(void)
  4. {
  5. __HAL_RCC_AHB1_FORCE_RESET(); //复位所有IO口
  6. while(WKUP_KD); //等待WK_UP按键松开(在有RTC中断时,必须等WK_UP松开再进入待机)
  7. __HAL_RCC_PWR_CLK_ENABLE(); //使能PWR时钟
  8. __HAL_RCC_BACKUPRESET_FORCE(); //复位备份区域
  9. HAL_PWR_EnableBkUpAccess(); //后备区域访问使能
  10. //STM32F4,当开启了RTC相关中断后,必须先关闭RTC中断,再清中断标志位,然后重新设置
  11. //RTC中断,再进入待机模式才可以正常唤醒,否则会有问题.
  12. __HAL_PWR_CLEAR_FLAG(PWR_FLAG_SB);
  13. __HAL_RTC_WRITEPROTECTION_DISABLE(&RTC_Handler);//关闭RTC写保护
  14. //关闭RTC相关中断,可能在RTC实验打开了
  15. __HAL_RTC_WAKEUPTIMER_DISABLE_IT(&RTC_Handler,RTC_IT_WUT);
  16. __HAL_RTC_TIMESTAMP_DISABLE_IT(&RTC_Handler,RTC_IT_TS);
  17. __HAL_RTC_ALARM_DISABLE_IT(&RTC_Handler,RTC_IT_ALRA|RTC_IT_ALRB);
  18. //清除RTC相关中断标志位
  19. __HAL_RTC_ALARM_CLEAR_FLAG(&RTC_Handler,RTC_FLAG_ALRAF|RTC_FLAG_ALRBF);
  20. __HAL_RTC_TIMESTAMP_CLEAR_FLAG(&RTC_Handler,RTC_FLAG_TSF);
  21. __HAL_RTC_WAKEUPTIMER_CLEAR_FLAG(&RTC_Handler,RTC_FLAG_WUTF);
  22. __HAL_RCC_BACKUPRESET_RELEASE(); //备份区域复位结束
  23. __HAL_RTC_WRITEPROTECTION_ENABLE(&RTC_Handler); //使能RTC写保护
  24. __HAL_PWR_CLEAR_FLAG(PWR_FLAG_WU); //清除Wake_UP标志
  25. HAL_PWR_EnableWakeUpPin(PWR_WAKEUP_PIN1); //设置WKUP用于唤醒
  26. HAL_PWR_EnterSTANDBYMode(); //进入待机模式
  27. }
  28. //检测WKUP脚的信号
  29. //返回值1:连续按下3s以上
  30. // 0:错误的触发
  31. u8 Check_WKUP(void)
  32. {
  33. u8 t=0;
  34. u8 tx=0;//记录松开的次数
  35. LED0=0; //亮灯DS0
  36. while(1)
  37. {
  38. if(WKUP_KD)//已经按下了
  39. {
  40. t++;
  41. tx=0;
  42. }else
  43. {
  44. tx++;
  45. if(tx>3)//超过90ms内没有WKUP信号
  46. {
  47. LED0=1;
  48. return 0;//错误的按键,按下次数不够
  49. }
  50. }
  51. delay_ms(30);
  52. if(t>=100)//按下超过3秒钟
  53. {
  54. LED0=0; //点亮DS0
  55. return 1; //按下3s以上了
  56. }
  57. }
  58. }
  59. //外部中断线0中断服务函数
  60. void EXTI0_IRQHandler(void)
  61. {
  62. HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_0);
  63. }
  64. //中断线0中断处理过程
  65. //此函数会被HAL_GPIO_EXTI_IRQHandler()调用
  66. //GPIO_Pin:引脚
  67. void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
  68. {
  69. if(GPIO_Pin==GPIO_PIN_0)//PA0
  70. {
  71. if(Check_WKUP())//关机
  72. {
  73. Sys_Enter_Standby();//进入待机模式
  74. }
  75. }
  76. }
  77. //PA0 WKUP唤醒初始化
  78. void WKUP_Init(void)
  79. {
  80. GPIO_InitTypeDef GPIO_Initure;
  81. __HAL_RCC_GPIOA_CLK_ENABLE(); //开启GPIOA时钟
  82. GPIO_Initure.Pin=GPIO_PIN_0; //PA0
  83. GPIO_Initure.Mode=GPIO_MODE_IT_RISING; //中断,上升沿
  84. GPIO_Initure.Pull=GPIO_PULLDOWN; //下拉
  85. GPIO_Initure.Speed=GPIO_SPEED_FAST; //快速
  86. HAL_GPIO_Init(GPIOA,&GPIO_Initure);
  87. //检查是否是正常开机
  88. if(Check_WKUP()==0)
  89. {
  90. Sys_Enter_Standby();//不是开机,进入待机模式
  91. }
  92. HAL_NVIC_SetPriority(EXTI0_IRQn,0x02,0x02);//抢占优先级2,子优先级2
  93. HAL_NVIC_EnableIRQ(EXTI0_IRQn);
  94. }

wkup.h

  1. #ifndef __WKUP_H
  2. #define __WKUP_H
  3. #include "sys.h"
  4. #define WKUP_KD HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0) //PA0 检测是否外部WK_UP按键按下
  5. u8 Check_WKUP(void); //检测WKUP脚的信号
  6. void WKUP_Init(void); //PA0 WKUP唤醒初始化
  7. void Sys_Enter_Standby(void); //系统进入待机模式
  8. #endif

3、实验结果

①、程序开始为待机状态,下载成功后没有数据输出。

②、长按WakeUp按键3s后,程序输出。

③、再长按WakeUp按键3s后,程序停止。

④、再次长按WakeUp按键3s后,程序从头输出。


四、结束语

 

低功耗在生活中非常重要,希望能帮助到你。

例程及相关资料参考于

        原子光盘、《STM32F4xx中文参考手册》-第x章 低功耗模式

侵删

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/代码探险家/article/detail/940717
推荐阅读
相关标签
  

闽ICP备14008679号