你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

【经验分享】STM32 待机唤醒程序示例

[复制链接]
STMCU小助手 发布时间:2022-6-14 14:45
01. 待机模式简介
很多单片机都有低功耗模式,STM32F4 也不例外。在系统或电源复位以后,微控制器处于运行状态。运行状态下的 HCLK 为 CPU 提供时钟,内核执行程序代码。当 CPU 不需继续运行时,可以利用多个低功耗模式来节省功耗,例如等待某个外部事件时。用户需要根据最低电源消耗,最快速启动时间和可用的唤醒源等条件,选定一个最佳的低功耗模式。STM32F4 的 3 种低功耗模式我们在 5.2.4 节有粗略介绍,这里我们再回顾一下。
STM32F4 提供了 3 种低功耗模式,以达到不同层次的降低功耗的目的,这三种模式如下:
1)睡眠模式(CM4 内核停止工作,外设仍在运行);
2)停止模式(所有的时钟都停止);
3)待机模式;

02. 硬件模块
用到的硬件资源有:
1) 指示灯 DS0
2) KEY_UP 按键
3) TFTLCD 模块

03. 相关函数
stm32f4xx_pwr.c / stm32f4xx_pwr.h

  1. void PWR_EnterSTOPMode();//进入停机模式
  2. void PWR_EnterSTANDBYMode(void);//进入待机模式
  3. void PWR_WakeUpPinCmd(FunctionalState NewState);//使能Wakeup引脚唤醒
  4. FlagStatus PWR_GetFlagStatus(uint32_t PWR_FLAG);
  5. void PWR_ClearFlag(uint32_t PWR_FLAG);
复制代码

core_cm4.h

  1. __WFI();
  2. __WFE();
复制代码

04. 程序示例一
按下KEY0进入待机模式 KEY_UP唤醒

  1. #include "sys.h"
  2. #include "delay.h"
  3. #include "usart.h"
  4. #include "led.h"
  5. #include "beep.h"
  6. #include "key.h"
  7. #include "usmart.h"
  8. #include "lcd.h"
  9. #include "rtc.h"
  10. #include "rng.h"
  11. #include "key.h"


  12. int main(void)
  13. {


  14.         NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2
  15.         
  16.         delay_init(168);
  17.         
  18.         uart_init(115200);
  19.         
  20.         usmart_dev.init(84);

  21.         
  22.         LED_Init();
  23.         
  24.         KEY_Init();
  25.         
  26.         LCD_Init();
  27.         
  28.                
  29.         POINT_COLOR = RED;
  30.         
  31.         LCD_ShowString(30,50,200,16,16,"Explorer STM32F4");        
  32.         LCD_ShowString(30,70,200,16,16,"PWR TEST");        
  33.         LCD_ShowString(30,90,200,16,16,"ATOM@tom");
  34.         LCD_ShowString(30,110,200,16,16,"2020/09/10");         
  35.         

  36.         while(1)
  37.         {
  38.                 if (Key_Scan() == KEY0_PRESS)
  39.                 {
  40.                         //使能PWR时钟
  41.                         RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);
  42.                         
  43.                         //后备区域访问使能
  44.                         PWR_BackupAccessCmd(ENABLE);
  45.                         
  46.                         //关闭RTC相关中断
  47.                         RTC_ITConfig(RTC_IT_TS|RTC_IT_WUT|RTC_IT_ALRB|RTC_IT_ALRA,DISABLE);
  48.                         //清除RTC相关中断标志
  49.                         RTC_ClearITPendingBit(RTC_IT_TS|RTC_IT_WUT|RTC_IT_ALRB|RTC_IT_ALRA);
  50.                         
  51.                         //清除wake-up标志
  52.                         PWR_ClearFlag(PWR_FLAG_WU);
  53.                         
  54.                         //使能唤醒管脚功能
  55.                         PWR_WakeUpPinCmd(ENABLE);
  56.                         
  57.                         //进入待机模式
  58.                         PWR_EnterSTANDBYMode();
  59.                
  60.                 }
  61.         
  62.                 delay_ms(10);
  63.         }
  64. }
复制代码

05. 程序示例二
wkup.h

  1. #ifndef __WK_UP_H__
  2. #define __WK_UP_H__

  3. #include "sys.h"

  4. #define WKUP_KD PAin(0)


  5. //检测WKUP脚的信号
  6. u8 Check_WKUP(void);

  7. //WKUP唤醒初始化
  8. void WKUP_Init(void);

  9. //系统进入待机模式
  10. void Sys_Enter_Standby(void);


  11. #endif/*__WK_UP_H__*/
复制代码

wkup.c

  1. #include "wkup.h"

  2. #include "led.h"
  3. #include "delay.h"

  4. //检测WKUP脚的信号
  5. u8 Check_WKUP(void)
  6. {
  7.         u8 t = 0;
  8.         
  9.         //记录松开的次数
  10.         u8 tx = 0;
  11.         LED1 = 0;
  12.         
  13.         while(1)
  14.         {
  15.                 if (WKUP_KD)
  16.                 {
  17.                         t++;
  18.                         tx = 0;
  19.                 }
  20.                 else
  21.                 {
  22.                         tx++;
  23.                         //查过90ms没有WKUP信号
  24.                         if (tx > 3)
  25.                         {
  26.                                 LED1 = 1;
  27.                                 return 0;
  28.                         }
  29.                 }
  30.         
  31.                 delay_ms(30);
  32.                
  33.                 if (t >= 100)
  34.                 {
  35.                         LED1 = 0;
  36.                         return 1;
  37.                 }
  38.         }        
  39. }

  40. //WKUP唤醒初始化
  41. void WKUP_Init(void)
  42. {

  43.         GPIO_InitTypeDef  GPIO_InitStructure;
  44.         NVIC_InitTypeDef   NVIC_InitStructure;
  45.         EXTI_InitTypeDef   EXTI_InitStructure;
  46.         
  47.         RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);//使能GPIOA时钟
  48.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);//使能SYSCFG时钟
  49.         
  50.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; //PA0
  51.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;//输入模式
  52.         GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;
  53.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
  54.         GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;//下拉
  55.         GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化        

  56.         //(检查是否是正常开)机                     
  57.         if(Check_WKUP()==0)
  58.         {
  59.                 Sys_Enter_Standby();        //不是开机,进入待机模式  
  60.         }
  61.         SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOA, EXTI_PinSource0);//PA0 连接到中断线0
  62.         

  63.         EXTI_InitStructure.EXTI_Line = EXTI_Line0;//LINE0
  64.         EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;//中断事件
  65.         EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising; //上升沿触发
  66.         EXTI_InitStructure.EXTI_LineCmd = ENABLE;//使能LINE0
  67.         EXTI_Init(&EXTI_InitStructure);//配置
  68.                
  69.         
  70.         NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;//外部中断0
  71.         NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02;//抢占优先级2
  72.         NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x02;//子优先级2
  73.         NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//使能外部中断通道
  74.         NVIC_Init(&NVIC_InitStructure);//配置NVIC
  75. }

  76. //系统进入待机模式
  77. void Sys_Enter_Standby(void)
  78. {
  79.         //等待按键松开
  80.         while(WKUP_KD)
  81.                 ;
  82.         
  83.         //复位所有的IO口
  84.         RCC_AHB1PeriphResetCmd(0x04FF, ENABLE);
  85.         
  86.         //使能PWR时钟
  87.         RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);
  88.         
  89.         //后备区域访问使能
  90.         PWR_BackupAccessCmd(ENABLE);
  91.         
  92.         //关闭RTC相关中断
  93.         RTC_ITConfig(RTC_IT_TS|RTC_IT_WUT|RTC_IT_ALRB|RTC_IT_ALRA,DISABLE);
  94.         //清除RTC相关中断标志
  95.         RTC_ClearITPendingBit(RTC_IT_TS|RTC_IT_WUT|RTC_IT_ALRB|RTC_IT_ALRA);
  96.         
  97.         //清除wake-up标志
  98.         PWR_ClearFlag(PWR_FLAG_WU);
  99.         
  100.         //使能唤醒管脚功能
  101.         PWR_WakeUpPinCmd(ENABLE);
  102.         
  103.         //进入待机模式
  104.         PWR_EnterSTANDBYMode();
  105. }

  106. //中断,检测到PA0脚的一个上升沿.         
  107. //中断线0线上的中断检测
  108. void EXTI0_IRQHandler(void)
  109. {                                                                                                  
  110.         EXTI_ClearITPendingBit(EXTI_Line0); // 清除LINE10上的中断标志位
  111.         if(Check_WKUP())//关机?
  112.         {                  
  113.                 Sys_Enter_Standby(); //进入待机模式
  114.         }
  115. }
复制代码

main.c

  1. #include "sys.h"
  2. #include "delay.h"
  3. #include "usart.h"
  4. #include "led.h"
  5. #include "beep.h"
  6. #include "key.h"
  7. #include "usmart.h"
  8. #include "lcd.h"
  9. #include "rtc.h"
  10. #include "rng.h"
  11. #include "key.h"
  12. #include "wkup.h"


  13. int main(void)
  14. {


  15.         NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2
  16.         
  17.         delay_init(168);
  18.         
  19.         uart_init(115200);
  20.         
  21.         usmart_dev.init(84);

  22.         
  23.         LED_Init();
  24.         
  25.         KEY_Init();
  26.         
  27.         LCD_Init();
  28.         
  29.         WKUP_Init();
  30.         
  31.                
  32.         POINT_COLOR = RED;
  33.         
  34.         LCD_ShowString(30,50,200,16,16,"Explorer STM32F4");        
  35.         LCD_ShowString(30,70,200,16,16,"PWR TEST");        
  36.         LCD_ShowString(30,90,200,16,16,"ATOM@tom");
  37.         LCD_ShowString(30,110,200,16,16,"2020/09/10");         

  38.         while(1)
  39.         {
  40.                 LED2 = !LED2;
  41.                
  42.                 delay_ms(250);
  43.         }
  44. }
复制代码


收藏 评论0 发布时间:2022-6-14 14:45

举报

0个回答

所属标签

相似分享

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版