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 更新中断标志
        }
    }
  • 相关阅读:
    Adobe Edge Animate –EdgeCommons Log和全局变量设置功能
    Adobe Edge Animate –使用EdgeCommons加载和播放音频
    Adobe Edge Animate –svg地图交互-精确的边缘及颜色置换
    Adobe Edge Animate –解决图形边缘精确检测问题-通过jquery加载svg图片
    Adobe Edge Animate –修改Edge Commons Spotlight功能,使之能支持播放中国网站视频
    Adobe Edge Animate –获取鼠标位置及跟随鼠标功能实现
    Adobe Edge Animate –使用css制作菜单
    Adobe Edge Animate –Edge Commons强势来袭,Edge团队开发成为现实
    Adobe Edge Animate –可重复使用的个性化按钮制作
    Adobe Edge Animate –弹性的方块-使用tweenmax缓动效果
  • 原文地址:https://www.cnblogs.com/killer-xc/p/6868497.html
Copyright © 2011-2022 走看看