zoukankan      html  css  js  c++  java
  • 转:Stm32学习笔记:按键单击、双击、长按功能实现

    由于项目产品的需要,只能设置一个按键,但是需要实现短按(即单击)切换工作模式、长按开关机、双击暂停等复用功能。下图是三种情况下的按键波形。按键未按下时是高电平,按下去是低电平。按键单击时,判断时间门槛设置为50~2000ms;长按门槛为持续按下2000ms。双击可以视为时间间隔很短的俩次有效单击,从第一次单击上升沿到第二次单击上升沿延时门槛为100~500ms。 
    这里写图片描述

    //按键按下去会出现下降沿,设置按键IO口所在的外部端口为下降沿触发中断。
    void EXTIX_Init(void)
    {
    EXTI_InitTypeDef EXTI_InitStructure;
    NVIC_InitTypeDef NVIC_InitStructure;
    KEY_Init(); //①按键端口初始化
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE); //②开启 AFIO 时钟
                                                        //GPIOE.2 中断线以及中断初始化配置,下降沿触发
    GPIO_EXTILineConfig(GPIO_PortSourceGPIOE,GPIO_PinSource2);//③
    EXTI_InitStructure.EXTI_Line=EXTI_Line2;
    EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
    EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; //下降沿触发
    EXTI_InitStructure.EXTI_LineCmd = ENABLE;
    EXTI_Init(&EXTI_InitStructure); //④初始化中断线参数
    
    NVIC_InitStructure.NVIC_IRQChannel = EXTI2_IRQn; //使能按键外部中断通道
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02; //抢占优先级 2,
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x02; //子优先级 2
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能外部中断通道
    NVIC_Init(&NVIC_InitStructure);//⑤初始化 NVIC
    }

    中断服务函数

    //⑥外部中断 2 服务程序
    void EXTI2_IRQHandler(void)
    {
        if(GPIO_ReadInputPin(GPIOE,GPIO_PIN_2)==0) //按键 KEY2
        {
            key_fall_flag = 1;//生成按键按下标志
        }
        EXTI_ClearITPendingBit(EXTI_Line2); //清除 LINE2 上的中断标志位
    }

    1ms定时器中断服务函数

    void TIM3_IRQHandler(void) //TIM3 中断
    {
        if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET) //检查 TIM3 更新中断发生与否
        {
            if(key_fall_flag==1)//发生按键按下事件
            {
                if(GPIO_ReadInputPin(GPIOB,GPIO_PIN_4)==0)//按键持续按下
                 {         
                    if(key_holdon_ms <= 2000)  
                     {
                        key_holdon_ms++; 
                     } 
                     else //按键按下到2000ms就判断长按时间成立,生成长按标志 
                     { 
                       key_holdon_ms = 0; 
                       short_key_flag=0;//清短按键标志
                       key_long_down = 1;//长按键标志置位
                       key_fall_flag = 0;//清按键按下标志 
                      } 
                 } 
              else //按键抬起
              { 
                   if(key_holdon_ms>50)//按下时间大于50ms,生成单击标志
                    {  
                       key_holdon_ms=0;
                       short_key_flag=1;
                       key_long_down =0;
                       key_fall_flag=0;
    
                 //距离上次单击时间在100~500ms之间,则认为发生连击事件
                      if(keyupCnt>100 && keyupCnt<500)
                      { 
                           doubleClick = TRUE;
                           short_key_flag=0;
                      } 
                      keyUpFlag = TRUE;//单击抬起按键后,生成按键抬起标志 
                    } 
                   else  //按键持续时间小于50ms,忽略 
                      {    
                           key_holdon_ms=0; 
                           short_key_flag=0;
                           long_key_flag=0;
                            key_fall_flag=0;
                     } 
              }
    
            }
        if(keyUpFlag)//单击抬起后,启动计数,计数到500ms  
             keyupCnt++;
        if(keyupCnt>500)
          { 
              keyupCnt = 0;
              keyUpFlag = FALSE;
          }
    
        }
    
            TIM_ClearITPendingBit(TIM3, TIM_IT_Update ); //清除 TIM3 更新中断标志
        }
    }
  • 相关阅读:
    模板 无源汇上下界可行流 loj115
    ICPC2018JiaozuoE Resistors in Parallel 高精度 数论
    hdu 2255 奔小康赚大钱 最佳匹配 KM算法
    ICPC2018Beijing 现场赛D Frog and Portal 构造
    codeforce 1175E Minimal Segment Cover ST表 倍增思想
    ICPC2018Jiaozuo 现场赛H Can You Solve the Harder Problem? 后缀数组 树上差分 ST表 口胡题解
    luogu P1966 火柴排队 树状数组 逆序对 离散化
    luogu P1970 花匠 贪心
    luogu P1967 货车运输 最大生成树 倍增LCA
    luogu P1315 观光公交 贪心
  • 原文地址:https://www.cnblogs.com/killer-xc/p/6868497.html
Copyright © 2011-2022 走看看