STM32实现待机唤醒 寄存器版
上篇使用了库函数实现 待机唤醒
本文将使用寄存器版本实现关机模式
寄存器版本跟库函数版本实现基本一致,
可以通过查看库函数版 去看底层代码 更方便去理解寄存器版本
寄存器操作
根据上两张图可以进行操作
相关步骤
- 设置 SLEEPDEEP 位
- 使能电源时钟,设置 WK_UP 引脚作为唤醒源。
- 设置 PDDS 位,执行 WFI 指令,进入待机模式
- 最后编写 WK_UP 中断函数。
实现功能如下
使用 STM32 的待机模式了,并且可以通过 WK_UP
来唤醒 CPU,我们最终要实现这样一个功能:通过长按(3 秒)WK_UP 按键开机
实现代码
#include "WakeUp.h"
#include "Nvic.h"
#include "Led.h"
void WakeUp_Stand(void)
{
RCC->APB1ENR |= 1 << 28; //外设时钟第28为PWR
SCB->SCR |= 1 << 2; //系统控制时钟设置深睡眠
//电源控制寄存器
PWR->CR |= 1 << 2; //清除唤醒位
PWR->CR |= 1 << 1; //设置PDDS 进入深睡眠
//电压状态寄存器
PWR->CSR |= 1 << 8; //按下wkup键唤醒
}
u8 Check_WKUP(void)
{
u8 t = 0;
while(1)
{
if(WKUP_KD)
{
t++;
Delay_ms(30);
if(t >= 100)
{
Led_Show();
return 1;
}
}
else
{
Led_Show();
return 0;
}
}
}
void WKUP_Init(void)
{
RCC->APB2ENR |= 1 << 2; //先使能外设 IO PORTA 时钟
RCC->APB2ENR |= 1 << 0; //开启辅助时钟
GPIOA->CRL &= 0XFFFFFFF0; //PA0 设置成输入
GPIOA->CRL |= 0X00000008;
Ex_Config(GPIO_A,0,RTIR); //PA0 上升沿触发
//(检查是否是正常开)机
if(Check_WKUP() == 0)
WakeUp_Stand();//不是开机,进入待机模式
Nvic_Init(2,2,EXTI0_IRQn,2); //抢占 2,子优先级 2,组 2
}
void Sys_Enter_Standy(void)
{
RCC->APB2RSTR |= 0x01FC;
WakeUp_Stand();
}
//中断,检测到 PA0 脚的一个上升沿.
//中断线 0 线上的中断检测
void EXTI0_IRQHandler(void)
{
EXTI->PR = 1 << 0; //清除 LINE10 上的中断标志位
if(Check_WKUP())
{
Sys_Enter_Standy();
}//关机?
}
主函数只需调用WKUP_Init()即可。