• 进入低功耗和唤醒


    休眠模式

    进入休眠模式

    如果使用 WFI 指令进入睡眠模式,则嵌套向量中断控制器 (NVIC) 确认的任意外设中断都会 
    将器件从睡眠模式唤醒。


    如果使用 WFE 指令进入睡眠模式,MCU 将在有事件发生时立即退出睡眠模式。唤醒事件可 
    通过以下方式产生:使能外设中断,但是不用NVIC。在内核系统控制寄存器SEVONPEND=1;SLEEPONEXIT = 0;配置外部中断为事件模式;

    退出休眠

    wfi进入休眠:任意中断退出休眠;

    WFE进入休眠如下10.2.3

    10.2.3 唤醒事件管理
    STM32F4xx 能够处理外部或内部事件来唤醒内核 (WFE)。唤醒事件可通过以下方式产生:
    ● 在外设的控制寄存器使能一个中断,但不在 NVIC 中使能,同时使能 Cortex™-M4F 系统 
    控制寄存器中的 SEVONPEND 位。当 MCU 从 WFE 恢复时,需要清除相应外设的中 
    断挂起位和外设 NVIC 中断通道挂起位(在 NVIC 中断清除挂起寄存器中)。
    ● 配置一个外部或内部 EXTI 线为事件模式。当 CPU 从 WFE 恢复时,因为对应事件线的 
    挂起位没有被置位,不必清除相应外设的中断挂起位或 NVIC 中断通道挂起位。

    M4内核系统控制寄存器(SCR)

    在m4内核的SCB系统控制块中

    需要的在2和3位

    休眠模式程序

    1. #include"wkup.h"
    2. #define WKUP_KD PAin(0) //PA0 检测是否外部WK_UP按键按下
    3. void wkup_init()
    4. {
    5. GPIO_InitTypeDef GPIO_InitStruct;
    6. EXTI_InitTypeDef EXTI_InitStruct;
    7. NVIC_InitTypeDef NVIC_InitStruct;
    8. RCC_AHB1PeriphClockCmd( RCC_AHB1Periph_GPIOA , ENABLE);
    9. RCC_APB2PeriphClockCmd( RCC_APB2Periph_SYSCFG , ENABLE);//外部中断需要sysCFG时钟
    10. GPIO_InitStruct.GPIO_Pin=GPIO_Pin_0;
    11. GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IN;//外部中断只能输入模式,没有复用模式;
    12. GPIO_InitStruct.GPIO_OType=GPIO_OType_PP;
    13. GPIO_InitStruct.GPIO_PuPd=GPIO_PuPd_DOWN;
    14. GPIO_InitStruct.GPIO_Speed=GPIO_Speed_100MHz;
    15. GPIO_Init(GPIOA, & GPIO_InitStruct);
    16. SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOA, EXTI_PinSource0);//库文件sysfg文件的函数,配置A0为外部中断
    17. EXTI_InitStruct.EXTI_Line=EXTI_Line0 ;//外部中断
    18. EXTI_InitStruct.EXTI_Mode=EXTI_Mode_Interrupt;
    19. EXTI_InitStruct.EXTI_Trigger=EXTI_Trigger_Rising;
    20. EXTI_InitStruct.EXTI_LineCmd= ENABLE;
    21. EXTI_Init( & EXTI_InitStruct);
    22. NVIC_InitStruct.NVIC_IRQChannel=EXTI0_IRQn;
    23. NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority=3;
    24. NVIC_InitStruct.NVIC_IRQChannelSubPriority=3;
    25. NVIC_InitStruct.NVIC_IRQChannelCmd=ENABLE;
    26. NVIC_Init(&NVIC_InitStruct);
    27. }
    28. void EXTI0_IRQHandler()
    29. {
    30. EXTI_ClearITPendingBit( EXTI_Line0 );
    31. printf("\r\n 激活88888888888 \r\n");
    32. }
    33. void sys_enter_sleep()
    34. {
    35. __WFI();
    36. SCB->SCR&=~(3<<1);//SLEEPDEEP SLEEPONEXIT 都等于0
    37. }

    main

    1. #include "main.h"
    2. #define tmep_len 30
    3. uint8_t temp_buf[tmep_len]={0};
    4. void test();
    5. uint8_t *mian_temp;
    6. double time_us;
    7. int main(void)
    8. {
    9. time_struct times;
    10. u8 key,flag ,i,n=5; //保存键值
    11. long long temp_32=0;
    12. static bool cnt;
    13. // delay_init(168); //初始化延时函数
    14. LED_Init(); //初始化LED端口
    15. BEEP_Init(); //初始化蜂鸣器端口
    16. //KEY_Init(); //初始化与按键连接的硬件接口
    17. LED1=!LED1;
    18. LED0=!LED0;
    19. wkup_init();//配置中断唤醒
    20. while(1)
    21. {
    22. for(i=0;i<20;i++)
    23. { temp_32=168*1000*100;
    24. while(temp_32--);
    25. LED1=!LED1;
    26. LED0=!LED0;
    27. if(i==5)
    28. {
    29. sys_enter_standby();
    30. }
    31. }
    32. }
    33. }

    停止模式

    停止模式程序

    库函数已经包装好

    1. void sys_enter_stop()
    2. {
    3. PWR_EnterSTOPMode(PWR_MainRegulator_ON, PWR_STOPEntry_WFI);//库函数
    4. }

    待机模式

    进入待机模式

     PWR_EnterSTANDBYMode(void)此库函数中已经存在PDDS和SLEPDEEP位设置;和WFI;

    进入待机模式后可以对各个控制位选择如下功能

    1、独立的看门狗 (IWDG):

    2、实时时钟 (RTC):

    3、内部 RC 振荡器 (LSI RC):

    4、外部 32.768 kHz 振荡器 (LSE OSC):

    退出待机模式

    检测到外部复位(NRST 引脚)、IWDG 复位、WKUP 引脚上升沿、RTC 闹钟、入侵事件 
    或时间戳时间时,微控制器退出待机模式

    唤醒时间,就是复位时间;应该不是复位,而是时间长;

    待机模式程序

    • PWR_EnterSTANDBYMode(void)此库函数中已经存在PDDS和SLEPDEEP位设置;和WFI;
    • 在表中多加一个备份RTC和SRAM寄存器   Enables or disables access to the backup domain (RTC registers, RTC   *   backup data registers and backup SRAM). 
    •   将电源控制/状态寄存器 (PWR_CSR) 中的 WUF 位清零 选用wakeup引脚外中断唤醒;
    1. #include"wkup.h"
    2. #define WKUP_KD PAin(0) //PA0 检测是否外部WK_UP按键按下
    3. void wkup_init()
    4. {
    5. GPIO_InitTypeDef GPIO_InitStruct;
    6. EXTI_InitTypeDef EXTI_InitStruct;
    7. NVIC_InitTypeDef NVIC_InitStruct;
    8. RCC_AHB1PeriphClockCmd( RCC_AHB1Periph_GPIOA , ENABLE);
    9. RCC_APB2PeriphClockCmd( RCC_APB2Periph_SYSCFG , ENABLE);//外部中断需要sysCFG时钟
    10. GPIO_InitStruct.GPIO_Pin=GPIO_Pin_0;
    11. GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IN;//外部中断只能输入模式,没有复用模式;
    12. GPIO_InitStruct.GPIO_OType=GPIO_OType_PP;
    13. GPIO_InitStruct.GPIO_PuPd=GPIO_PuPd_DOWN;
    14. GPIO_InitStruct.GPIO_Speed=GPIO_Speed_100MHz;
    15. GPIO_Init(GPIOA, & GPIO_InitStruct);
    16. SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOA, EXTI_PinSource0);//库文件sysfg文件的函数,配置A0为外部中断
    17. EXTI_InitStruct.EXTI_Line=EXTI_Line0 ;//外部中断
    18. EXTI_InitStruct.EXTI_Mode=EXTI_Mode_Interrupt;
    19. EXTI_InitStruct.EXTI_Trigger=EXTI_Trigger_Rising;
    20. EXTI_InitStruct.EXTI_LineCmd= ENABLE;
    21. EXTI_Init( & EXTI_InitStruct);
    22. NVIC_InitStruct.NVIC_IRQChannel=EXTI0_IRQn;
    23. NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority=3;
    24. NVIC_InitStruct.NVIC_IRQChannelSubPriority=3;
    25. NVIC_InitStruct.NVIC_IRQChannelCmd=ENABLE;
    26. NVIC_Init(&NVIC_InitStruct);
    27. }
    28. void EXTI0_IRQHandler()
    29. {
    30. EXTI_ClearITPendingBit( EXTI_Line0 );
    31. printf("\r\n 激活88888888888 \r\n");
    32. }
    33. void sys_enter_standby()
    34. {
    35. if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0)==0)
    36. {
    37. // RCC_AHB1PeriphResetCmd(0X04FF,ENABLE);//复位所有IO口
    38. RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR,ENABLE);//开启电源控制管理时钟,才能操作低功耗
    39. PWR_BackupAccessCmd(ENABLE);//备份RTC和SRAM
    40. RTC_ClearITPendingBit(RTC_IT_TS|RTC_IT_WUT|RTC_IT_ALRB|RTC_IT_ALRA|RTC_IT_TAMP1|RTC_IT_TAMP2);//禁止RTC中断和清除全部标记
    41. RTC_ITConfig(RTC_IT_TS|RTC_IT_WUT|RTC_IT_ALRB|RTC_IT_ALRA|RTC_IT_TAMP, DISABLE);
    42. PWR_ClearFlag(PWR_FLAG_WU);//清除wakup 的唤醒标志
    43. PWR_WakeUpPinCmd(ENABLE); //使能wake up脚唤醒
    44. PWR_EnterSTANDBYMode(); //进入到待机模式
    45. }
    46. }

    main

    1. #include "main.h"
    2. #define tmep_len 30
    3. uint8_t temp_buf[tmep_len]={0};
    4. void test();
    5. uint8_t *mian_temp;
    6. double time_us;
    7. int main(void)
    8. {
    9. time_struct times;
    10. u8 key,flag ,i,n=5; //保存键值
    11. uint32_t temp_32=0;
    12. static bool cnt;
    13. // delay_init(168); //初始化延时函数
    14. software_times_base_init( 168 );
    15. uart_init(115200);
    16. NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
    17. LED_Init(); //初始化LED端口
    18. BEEP_Init(); //初始化蜂鸣器端口
    19. KEY_Init(); //初始化与按键连接的硬件接口
    20. LED1=!LED1;
    21. LED0=!LED0;
    22. wkup_init();
    23. while(1)
    24. {
    25. TimesMs( × );
    26. if(times.Delay>3000)
    27. {
    28. times.Delay=0;
    29. printf("\r\n 2222222222222222222 \r\n");
    30. }
    31. key=KEY_Scan(1);
    32. if(key==1)
    33. {
    34. sys_enter_standby();
    35. LED1=!LED1;
    36. LED0=!LED0;
    37. }
    38. }
    39. }

    程序效果:进入待机后不再打印东西;中断唤醒,打印一个已经唤醒标志,并且恢复之前未完成的步骤;

  • 相关阅读:
    物联网卡有哪些神奇的功能?
    Threejs_02 父子位移+缩放改变
    含文档+PPT+源码等]精品基于PHP实现的计算机信息管理学院网站[包运行成功]计算机PHP毕业设计项目源码
    Ubuntu:VS Code IDE安装ESP-IDF【保姆级】(草稿)
    代码随想录刷题day56 583. 两个字符串的删除操作;72. 编辑距离;编辑距离总结篇
    Java中使用正则检查有效日期
    【数学建模】传染病模型笔记
    macOS Ventura 13.6.5 (22G621) Boot ISO 原版可引导镜像下载
    BIOS 中断服务 设置颜色
    MacOS 用typora和picGo配置腾讯云COS图床
  • 原文地址:https://blog.csdn.net/qq_36658033/article/details/132707161