OSAL 的按键 长按短按的实现

时间:2022-11-30 18:00:33
长按短按一般是用来扩展按键功能,让人机界面更好用。其实现在做的最好的人机界面还是触摸屏上,iOS中对一个图标长按就激活了应用删除。除了长按,触摸屏还有短按、滑动,更牛逼的是手势操作,我现在累死累活做了个按键的长按短按处理,才发现触摸屏的使用有多牛逼,在用触摸屏的时候根本不用学,自然而然就会用触摸屏,这尼玛才是科技和人的结合啊!!!
 
当然,这一篇还是描述怎么做按键长按短按的,擦!
 
长短按的定义
  • 长按是指按下按键超过一定时间,这里以2s为时间阈值。
  • 短按是指从按下按键到弹起按键,不到0.5s。
实现
根据上面对长按短按的定义,可以这样设计:
按键按下的瞬间触发中断,然后每隔100ms轮询,如果超过2000ms,按键都是按下的,则发出长按消息,如果弹起,并且按下时间没超过500ms,则为短按。
 
OSAL的按键已经有轮询,计时,所以只需要小小修改一下就能实现。
 
首先,定义长按短按的标志位:
const uint8 HAL_KEY_SHORT=0x40;
const uint8 HAL_KEY_LONG=0x80;

 然后,在轮询函数HalKeyPoll()中加入计时

OSAL 的按键 长按短按的实现OSAL 的按键 长按短按的实现
if (!Hal_KeyIntEnable)
  {
    if (keys == halKeySavedKeys)                                                                            //如果中断关闭(轮询中),并且按键是保持按下的
    {
      
      keypresslasttime++;
      //因为polling每100ms执行一次,所以当keypresslasttime=20时,发出长按的消息,
      if(keypresslasttime==20)                                                                                   //如果达到2000ms
      {
        sendkeys = keys | HAL_KEY_LONG;                                                                  //加上长按标志
        (pHalKeyProcessFunction) ( sendkeys, HAL_KEY_STATE_NORMAL);                     //发送按键消息
      }
      else                                                                                                                  //如果没达到2000ms,则直接返回
      {
      /* Exit - since no keys have changed */
        return;
      }
    }
    else
    {
      //当按键弹起时,看一下按下的时间多长,因为polling的时间是100ms,所以当keypresslasttime<5时,发出短按的消息,
      if(keypresslasttime <5)
      {
         sendkeys = halKeySavedKeys | HAL_KEY_SHORT;
        (pHalKeyProcessFunction) ( sendkeys, HAL_KEY_STATE_NORMAL);
      }
      notify = 1;
    }
  }
  else                                                                            
  {
    /* Key interrupt handled here */
    //如果是按键终端,则开始计时
    keypresslasttime = 1;
    if (keys)
    {
      notify = 1;
    }
  }

  /* Store the current keys for comparation next time */
  halKeySavedKeys = keys;

  /* Invoke Callback if new keys were depressed */
  if (notify && (pHalKeyProcessFunction))
  {
    //(pHalKeyProcessFunction) (sendkeys, HAL_KEY_STATE_NORMAL);
    (pHalKeyProcessFunction) (keys, HAL_KEY_STATE_NORMAL);
  }
}
View Code

 顺便说一下,在实现key对应IO口配置的时候,要注意一下中断的触发方式,是上升沿触发还是下降沿触发。如果弹起时低电平,按下是高电平,就应该采用上升沿触发,这样才能正确计时。