STM32 3秒开关机

电源控制相关配置库函数

2个模式进入函数
void PWR_EnterSTOPMode(uint32_t PWR_Regulator, uint8_t PWR_STOPEntry);
void PWR_EnterSTANDBYMode(void);
作用:前者进入停机状态,后者进入待机状态。

2个使能函数
void PWR_WakeUpPinCmd(FunctionalState NewState);
void PWR_BackupAccessCmd(FunctionalState NewState);
作用:前者使能WK_UP引脚唤醒(正常模式下,WK_UP引脚作为普通IO口,待机模式下设置成唤醒功能),后者使能BKP后备区域访问使能。

2个状态位函数
FlagStatus PWR_GetFlagStatus(uint32_t PWR_FLAG);
void PWR_ClearFlag(uint32_t PWR_FLAG);
作用:前者获取电源控制的状态位,后者清除相应的状态位。

2个内核指令函数
__WFI();
__WFE();
作用:CM3内核的WFI(等待中断)、WFE(等待事件)指令(定义在:core_cm3.h)。

待机模式的一般步骤

实例要求:实现同一个引脚PA0引脚(WK_UP引脚),正常模式下,长按3秒进入待机模式;待机模式下,长按3秒待机唤醒。

使能电源时钟。调用函数:RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);
设置WK_UP引脚作为唤醒源。调用函数:PWR_WakeUpPinCmd(ENABLE);
进入待机模式。调用函数:void PWR_EnterSTANDBYMode(void),执行设置SLEEPDEEP位,设置PDDS位,执行WFI指令。
#define WKUP_KD PAin(0)            //PA0 检测是否外部WK_UP按键按下
void Sys_Standby(void)
{  
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);    //使能PWR外设时钟
    PWR_WakeUpPinCmd(ENABLE);  //使能唤醒管脚功能
    PWR_EnterSTANDBYMode();      //进入待命(STANDBY)模式          
}
//系统进入待机模式
void Sys_Enter_Standby(void)
{             
    RCC_APB2PeriphResetCmd(0X01FC,DISABLE);    //复位所有IO口
    Sys_Standby();
}
//检测WKUP脚的信号
//返回值1:连续按下3s以上
//      0:错误的触发    
u8 Check_WKUP(void) 
{
    u8 t=0;    //记录按下的时间
    LED0=0; //亮灯DS0 
    while(1)
    {
        if(WKUP_KD)
        {
            t++;            //已经按下了 
            delay_ms(30);
            if(t>=100)        //按下超过3秒钟
            {
                LED0=0;         //点亮DS0 
                return 1;     //按下3s以上了
            }
        }else 
        { 
            LED0=1;
            return 0; //按下不足3秒
        }
    }

//中断,检测到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_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE);//使能GPIOA和复用功能时钟
 
    GPIO_InitStructure.GPIO_Pin =GPIO_Pin_0;     //PA.0
    GPIO_InitStructure.GPIO_Mode =GPIO_Mode_IPD;//上拉输入
    GPIO_Init(GPIOA, &GPIO_InitStructure);    //初始化IO
    //使用外部中断方式
    GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, 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);    // 初始化外部中断
 
    NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn; //使能按键所在的外部中断通道
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; //先占优先级2级
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2; //从优先级2级
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能外部中断通道
    NVIC_Init(&NVIC_InitStructure); //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器
 
    if(Check_WKUP()==0) Sys_Standby();    //不是开机,进入待机模式  
    
}
 int main(void)
 {     
  
    delay_init();             //延时函数初始化      
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置中断优先级分组为组2:2位抢占优先级,2位响应优先级
    uart_init(115200);         //串口初始化为115200
     LED_Init();                 //LED端口初始化         
    WKUP_Init(); //待机唤醒初始化
    LCD_Init();     //LCD初始化
    POINT_COLOR=RED;
     
    LCD_ShowString(30,50,200,16,16,"Warship STM32");    
    LCD_ShowString(30,70,200,16,16,"WKUP TEST");    
    LCD_ShowString(30,90,200,16,16,"ATOM@ALIENTEK");
    LCD_ShowString(30,110,200,16,16,"2014/1/14");
     
    while(1)
    {
        LED0=!LED0;
        delay_ms(250);
    }
 }
STM32控制程序分析

WKUP_Init()函数:初始化GPIO、外部中断等准备工作。

由于WK_UP键有两个功能:正常模式下,长按3秒进入待机模式;待机模式下,长按3秒退出待机模式。

本案例中的实现是:

正常模式下,将WK_UP键设置成外部中断,一旦按下,进入中断处理函数,在中断处理函数中进行3秒的时间判断是否进入待机模式;
void WKUP_Init(void)
{    
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE);//使能GPIOA和复用功能时钟
 
    GPIO_InitStructure.GPIO_Pin =GPIO_Pin_0;     //PA.0
    GPIO_InitStructure.GPIO_Mode =GPIO_Mode_IPD;//上拉输入
    GPIO_Init(GPIOA, &GPIO_InitStructure);    //初始化IO
        //使用外部中断方式
    GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource0);    //中断线0连接GPIOA.0
 
    EXTI_Init(&EXTI_InitStructure);    // 初始化外部中断
 
    NVIC_Init(&NVIC_InitStructure); //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器
    
}
void EXTI0_IRQHandler(void)
{                                                          
    EXTI_ClearITPendingBit(EXTI_Line0); // 清除LINE10上的中断标志位          
    if(Check_WKUP())//关机?
    {          
        Sys_Enter_Standby();  
    }

待机模式下,设置WK_UP键用来退出待机模式,一旦按下,退出待机模式,重新执行main主函数,在主函数中进行3秒的时间判断,如果没有3秒,重新进入待机模式,否则继续正常执行。
void WKUP_Init(void)
{    
        //初始化过程
    if(Check_WKUP()==0) Sys_Standby();    //不是开机,进入待机模式  
    
}
而其中进入待机模式的程序代码块,就是之前的待机模式的一般步骤:

void Sys_Standby(void)
{  
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);    //使能PWR外设时钟
    PWR_WakeUpPinCmd(ENABLE);  //使能唤醒管脚功能
    PWR_EnterSTANDBYMode();      //进入待命(STANDBY)模式          

}

  • 7
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值