#include "wkup.h"
#include "led.h"
#include "delay.h"
//////////////////////////////////////////////////////////////////////////////////
//本程序只供学习使用,未经作者许可,不得用于其它任何用途
//ALIENTEK战舰STM32开发板
//待机唤醒 代码
//正点原子@ALIENTEK
//技术论坛:www.openedv.com
//修改日期:2012/9/7
//版本:V1.0
//版权所有,盗版必究。
//Copyright(C) 广州市星翼电子科技有限公司 2009-2019
//All rights reserved
//////////////////////////////////////////////////////////////////////////////////
#if 0
void PWR_EnterSleepMode(uint8_t PWR_SLEEPEntry); //睡眠模式
void PWR_EnterSTOPMode(uint32_t PWR_Regulator, uint8_t PWR_STOPEntry); //停机模式
void PWR_EnterSTANDBYMode(void); //待机模式
#define PWR_Regulator_ON //电源不进低功耗 唤醒基本没延迟
#define PWR_Regulator_LowPower //电源进去低功耗 不过唤醒启动有一点延迟
#define PWR_STOPEntry_WFI //中断唤醒
#define PWR_STOPEntry_WFE //事件唤醒
#endif
int exitflag;
void Sys_Standby(void)
{
// NVIC_SystemLPConfig(NVIC_LP_SLEEPDEEP,ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE); //使能PWR外设时钟
PWR_WakeUpPinCmd(ENABLE); //使能唤醒管脚功能
//PWR_EnterSTANDBYMode(); //进入待命(STANDBY)模式 待机模式
// 任意中断 事件
//PWR_EnterSTOPMode(PWR_Regulator_ON, PWR_STOPEntry_WFI|PWR_STOPEntry_WFE);//停机模式模式
PWR_EnterSTOPMode(PWR_Regulator_LowPower,PWR_STOPEntry_WFI);
}
//系统进入待机模式
void Sys_Enter_Standby(void)
{
//RCC_APB2PeriphResetCmd(0X01FC,DISABLE); //复位所有IO口
Sys_Standby();
//SystemInit();//重要,由于停机下对所有时钟关闭,所以唤醒需要重新配置时钟!
}
//检测WKUP脚的信号
//返回值1:连续按下3s以上
// 0:错误的触发
u8 Check_WKUP(void)
{
u8 t=0; //记录按下的时间
LED0=0; //亮灯DS0
while(1)
{
if(WKUP_KD)
{
t++; //已经按下了
delay_ms(30);//N190729164522608323
if(t>=100) //按下超过3秒钟
{
LED0=0; //点亮DS0
return 1; //按下3s以上了
}
}else
{
LED0=1;
return 0; //按下不足3秒
}
}
}
//中断,检测到PA0脚的一个上升沿.
//中断线0线上的中断检测
//PA0 WKUP唤醒初始化
void STOP_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
EXTI_InitTypeDef EXTI_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);//使能GPIOA
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
//另外, STM32 的所有 GPIO 都引入到 EXTI 外部中断线上,使得所有的 GPIO 都能作为外部中断的输入
//源。所以如果把 GPIO 用作 EXTI 外部中断时,还需要开启 AFIO 时钟。
GPIO_InitStructure.GPIO_Pin =GPIO_Pin_0|GPIO_Pin_1; //PA.0 PA.1
GPIO_InitStructure.GPIO_Mode =GPIO_Mode_IPD;//上拉输入
GPIO_Init(GPIOC, &GPIO_InitStructure); //初始化IO
//使用外部中断方式
GPIO_EXTILineConfig(GPIO_PortSourceGPIOC, GPIO_PinSource0); //中断线0连接GPIOA.0
EXTI_InitStructure.EXTI_Line = EXTI_Line0; //设置按键所有的外部线路
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; //设外外部中断模式:EXTI线路为中断请求
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising; //上升沿触发
EXTI_InitStructure.EXTI_LineCmd = ENABLE;//使能外部中断通道
EXTI_Init(&EXTI_InitStructure); // 初始化外部中断
//使用外部中断方式
GPIO_EXTILineConfig(GPIO_PortSourceGPIOC, GPIO_PinSource1); //中断线0连接GPIOA.1
EXTI_InitStructure.EXTI_Line = EXTI_Line1; //设置按键所有的外部线路
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; //设外外部中断模式:EXTI线路为中断请求
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising ; // 下降沿触发EXTI_Trigger_Falling 上升沿触发EXTI_Trigger_Rising
EXTI_InitStructure.EXTI_LineCmd = ENABLE;//使能外部中断通道
EXTI_Init(&EXTI_InitStructure); // 初始化外部中断
NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn; //使能按键所在的外部中断通道
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02; //先占优先级2级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x02; //从优先级2级
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能外部中断通道
NVIC_Init(&NVIC_InitStructure); //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器
NVIC_InitStructure.NVIC_IRQChannel = EXTI1_IRQn; //使能按键所在的外部中断通道
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02; //先占优先级2级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x02; //从优先级2级
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能外部中断通道
NVIC_Init(&NVIC_InitStructure); //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器
}
void EXTI0_IRQHandler(void)
{
if(EXTI_GetITStatus(EXTI_Line0)!=RESET) //按压检测口中断信号出现 判断中断是否发生
{
exitflag++;
Sys_Standby(); //执行中断事件?
//LED0=0;
//SystemInit();
EXTI_ClearITPendingBit(EXTI_Line0); // 清除LINE10上的中断标志位
EXTI_ClearFlag(EXTI_Line0); // 清除LINE10上的中断标志位
}
}
// EXTI_ClearFlag// 清除LINE10上的中断标志位
//EXTI_GetFlagStatus If(EXTI_GetFlagStatus(EXTI_Line3)!-=RESET)//判断是否置位
//EXTI_GetITStatus()会先判断该中断是否使能,若使能了再判断中断标志位,
//而EXTI_GetFlagStatus()直接判断中断标志位是否置位。
//所以说方式的EXTI_GetITStatus()会好点,一般配合EXTI_ClearITPendingBit()使用
void NVIC_CoreReset(void)
{
__DSB(); /* Ensure all outstanding memory accesses included
buffered write are completed before reset */
SCB->AIRCR = (uint32_t)((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) |
(SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) |
SCB_AIRCR_VECTRESET_Msk ); /* Keep priority group unchanged */
__DSB(); /* Ensure completion of memory access */
for(;;) /* wait until reset */
{
__NOP();
}
}
void EXTI1_IRQHandler(void)
{
if(EXTI_GetITStatus(EXTI_Line1)!=RESET) //按压检测口中断信号出现
{
SystemInit();
__set_FAULTMASK(1); //关闭所有中断
NVIC_SystemReset(); //复位
NVIC_CoreReset();
RTC_WaitForLastTask();
LED0=1;
PWR_WakeUpPinCmd(ENABLE); //使能唤醒管脚功能
EXTI_ClearITPendingBit(EXTI_Line1); // 清除LINE11上的中断标志位
EXTI_ClearITPendingBit(EXTI_Line1); // 清除LINE11上的中断标志位
EXTI_ClearFlag(EXTI_Line1); // 清除LINE11上的中断标志位
}
}
上一篇:简述STM32 CAN总线的设置
下一篇:STM32 IIC OLED中英文显示
推荐阅读最新更新时间:2024-11-20 00:01