目录
本节我们讲解的是有关待机唤醒的知识,这部分知识在51中并未涉及到,我感觉还是有点意思的,有点类似与我们手机的锁屏功能和关机功能,只是选择了不同的低功耗模式。好了,接下来我们就来介绍一下待机唤醒的相关知识吧!
https://live.csdn.net/v/embed/233022
待机唤醒1
https://live.csdn.net/v/embed/233025
待机唤醒2
在系统或电源复位以后,微控制器处于运行状态。运行状态下的 HCLK 为 CPU 提供时钟,内核执行程序代码。当 CPU 不需继续运行 时,可以利用多个低功耗模式来节省功耗,例如等待某个外部事件时。
这三种模式的功耗是逐渐降低的,特别是待机模式,功耗特别低,最低只需要 2.2uA 左右的电流。停机模式是次低功耗的,其典型的电流消耗在 350uA 左右。最后就是睡眠模式了。根据最低电源消耗,最快启动时间和可用的唤醒源等条件,选择一种最佳的低功耗模式。
F407的待机模式可实现 STM32F4 的最低功耗。该模式是在 CM4 深睡眠模式时关闭电压调节器。整个 1.2V 供电区域被断电。PLL、 HSI 和 HSE 振荡器也被断电。SRAM 和寄存器内容丢失。除备份域(RTC 寄存器、RTC 备份 寄存器和备份 SRAM)和待机电路中的寄存器外,SRAM 和寄存器内容都将丢失。而且有一个重要的点就是F407需要清零对应的RTC标志。
还是一样,不做详细介绍。
我们前面说了F407需要清除相应的标志位才能开启待机模式。
1、使能电源时钟。
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE); //使能 PWR 外设时钟
2、设置 WK_UP 引脚作为唤醒源。
PWR_WakeUpPinCmd(ENABLE); //使能唤醒管脚功能
3、设置 SLEEPDEEP 位,设置 PDDS 位,执行 WFI 指令,进入待机模式。
PWR_EnterSTANDBYMode(void);
4、最后编写 WK_UP 中断函数。
实验一的代码。
#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "key.h"
int main(void)
{
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2
delay_init(168); //初始化延时函数
uart_init(115200); //初始化串口波特率为115200
LED_Init(); //初始化LED
KEY_Init();
LED0 = 0;
while(1)
{
if(KEY_Scan(0) == KEY0_PRES){
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR,ENABLE );
PWR_BackupAccessCmd(ENABLE);//后备区域访问使能
//这里我们就直接关闭相关RTC中断
RTC_ITConfig(RTC_IT_TS|RTC_IT_WUT|RTC_IT_ALRB|RTC_IT_ALRA,DISABLE);//关闭RTC相关中断,可能在RTC实验打开了。
RTC_ClearITPendingBit(RTC_IT_TS|RTC_IT_WUT|RTC_IT_ALRB|RTC_IT_ALRA);//清楚RTC相关中断标志位。
PWR_WakeUpPinCmd(ENABLE );
PWR_ClearFlag(PWR_FLAG_WU);
PWR_EnterSTANDBYMode();
}
}
}
实验二的代码。
#include "wkup.h"
#include "led.h"
#include "delay.h"
#include "usart.h"
//系统进入待机模式
void Sys_Enter_Standby(void)
{
while(WKUP_KD); //等待WK_UP按键松开(在有RTC中断时,必须等WK_UP松开再进入待机)
RCC_AHB1PeriphResetCmd(0X04FF,ENABLE);//复位所有IO口
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);//使能PWR时钟
PWR_BackupAccessCmd(ENABLE);//后备区域访问使能
//这里我们就直接关闭相关RTC中断
RTC_ITConfig(RTC_IT_TS|RTC_IT_WUT|RTC_IT_ALRB|RTC_IT_ALRA,DISABLE);//关闭RTC相关中断,可能在RTC实验打开了。
RTC_ClearITPendingBit(RTC_IT_TS|RTC_IT_WUT|RTC_IT_ALRB|RTC_IT_ALRA);//清楚RTC相关中断标志位。
PWR_ClearFlag(PWR_FLAG_WU);//清除Wake-up 标志
PWR_WakeUpPinCmd(ENABLE);//设置WKUP用于唤醒
PWR_EnterSTANDBYMode(); //进入待机模式
}
//检测WKUP脚的信号
//返回值1:连续按下3s以上
// 0:错误的触发
u8 Check_WKUP(void)
{
u8 t=0;
u8 tx=0;//记录松开的次数
LED0=0; //亮灯DS0
while(1)
{
if(WKUP_KD)//已经按下了
{
t++;
tx=0;
}else
{
tx++;
if(tx>3)//超过90ms内没有WKUP信号
{
LED0=1;
return 0;//错误的按键,按下次数不够
}
}
delay_ms(30);
if(t>=100)//按下超过3秒钟
{
LED0=0; //点亮DS0
return 1; //按下3s以上了
}
}
}
//中断,检测到PA0脚的一个上升沿.
//中断线0线上的中断检测
void EXTI0_IRQHandler(void)
{
EXTI_ClearITPendingBit(EXTI_Line0); // 清除LINE10上的中断标志位
if(Check_WKUP())//关机?
{
Sys_Enter_Standby(); //进入待机模式
}
}
//PA0 WKUP唤醒初始化
void WKUP_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
EXTI_InitTypeDef EXTI_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);//使能GPIOA时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);//使能SYSCFG时钟
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; //PA0
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;//输入模式
GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;//下拉
GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化
//(检查是否是正常开)机
if(Check_WKUP()==0)
{
Sys_Enter_Standby(); //不是开机,进入待机模式
}
SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOA, EXTI_PinSource0);//PA0 连接到中断线0
EXTI_InitStructure.EXTI_Line = EXTI_Line0;//LINE0
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;//中断事件
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising; //上升沿触发
EXTI_InitStructure.EXTI_LineCmd = ENABLE;//使能LINE0
EXTI_Init(&EXTI_InitStructure);//配置
NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;//外部中断0
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02;//抢占优先级2
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x02;//子优先级2
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//使能外部中断通道
NVIC_Init(&NVIC_InitStructure);//配置NVIC
}
#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "wkup.h"
int main(void)
{
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2
delay_init(168); //初始化延时函数
uart_init(115200); //初始化串口波特率为115200
LED_Init(); //初始化LED
WKUP_Init(); //待机唤醒初始化
while(1)
{
LED0=!LED0;
delay_ms(250);//延时250ms
}
}
本节介绍的是低功耗模式,主要介绍了待机模式,希望对大家有所帮助,谢谢大家了!