查看: 1369|回复: 0
打印 上一主题 下一主题

[并发长短键+shift键+环形buf]简洁且功能强大的按键程序

[复制链接]
跳转到指定楼层
沙发
发表于 2015-6-14 17:13:37 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
到 
       
搜索
搜索       
热搜: 净化器雕刻机阿莫邮购
amoBBS 阿莫电子论坛?论坛首页?单片机?CortexM3?[并发长短键+shift键+环形buf]简洁且功能强大的按键程序 ...bottom↓
12 / 2 页下一页
返回列表发新帖
查看: 5958|回复: 103
打印 上一主题 下一主题 [并发长短键+shift键+环形buf]简洁且功能强大的按键程序   [复制链接]
mojinpan

电梯直达跳转到指定楼层 1楼
发表于 2013-11-9 20:13:04 | 只看该作者 回帖奖励
本帖最后由 mojinpan 于 2013-11-9 20:36 编辑


提供一个简洁且功能强大的按键程序,供大家参考[并发长短键+shift键+环形buf]

主要参考:
1.[转]新型的按键扫描程序:http://www.amobbs.com/forum.php? ... =%E6%8C%89%E9%94%AE
2.[推荐]一种软件去除键抖动的方法:http://blog.csdn.net/joseph_happy/article/details/5133708

功能:
1.支持最大32个按键(视编译器所支持的数据类型而定)
2.支持不同的扫描方式(根据具体情况编写KeyIOread()和KeyInit())
3.支持按键消抖处理
2.支持按键环形缓冲区
5.支持短按键,短按键数量 = 最大按键数 - shift按键数
6.支持长按键,长按键数量 = 最大按键数,延时判定时间和扫描周期均可配置
7.支持shift键,shift键长按短按均可生效
用法:
1.每20ms~50ms调用KeyScan()扫描按键
2.调用KeyHit()判断是否有按键
3.调用KeyGet()获得按键值

关键代码:
/*************************************************************************************************************
函数名称:KeyScan()
函数入口:无
函数出口:无
函数说明:
1.功能说明
  a.按键消抖
  b.捕捉长按键和短按键
2.算法说明
  a.滤波算法
    1).PreScanKey&NowScanKey: 取连续2次按键的高电平值
    2).PreScanKey^NowScanKey: 取连续2次按键的差异部分
    3).PreReadKey&(PreScanKey^NowScanKey): 取前一次按键值的差异部分
    4).上面的合起来即:当前按键值等于连续2次有效按键值或前次有效按键值
  b.按键获取算法
    1).NowKey ^ PreKey                                : 边缘触发
    2).NowKey & (NowKey ^ PreKey)或(~PreKey) & NowKey : 上升沿触发
    3).PreKey & (NowKey ^ PreKey)或PreKey & (~NowKey) : 下降沿触发
3.调用说明
  a.对下调用的KeyIOread()中,有效按键必须为高电平,且每个bit表示一个按键值
  b.应用调用该函数的间隔应该在20ms~50ms,在调用间隔内的毛刺均可滤除。
*************************************************************************************************************/
void KeyScan(void)
{
  KEY_TYPE NowScanKey   = 0;                                  //当前按键值扫描值
  KEY_TYPE NowReadKey   = 0;                                  //当前按键值
//INT32U KeyPressDown = 0;                                  //按键按下
  KEY_TYPE KeyRelease   = 0;                                  //按键释放
  KEY_TYPE KeyShiftMask = KEY_SHIFT;                          //shift按键码
  NowScanKey  = KeyIOread();
  NowReadKey  = (PreScanKey&NowScanKey)|
                 PreReadKey&(PreScanKey^NowScanKey);  

//KeyPressDown  = NowReadKey & (NowReadKey ^ PreReadKey);
  KeyRelease    = PreReadKey & (NowReadKey ^ PreReadKey);
  KeyShift      = KeyShift ^ (KeyRelease & KeyShiftMask);
#if LONG_KEY_EN > 0                                         
  if(NowReadKey == PreReadKey && NowReadKey){               //长按键有效判断
    KeyPressTmr--;
    if(!KeyPressTmr){                                       //长按判断周期到,保存相应长按键值
      KeyBufIn(NowReadKey | KeyShift);
      KeyPressTmr = KEY_PRESS_TMR;                          //重置按键判断周期,准备获取下1个长按键
    }
  }
  else{
    KeyPressTmr = KEY_PRESS_DLY;                            //按键变化,重置按键判断周期
  }
#endif


  if(KeyRelease & (~KeyShiftMask)){                         //短按键判断
    KeyBufIn(KeyRelease | KeyShift);
  }

  PreScanKey     = NowScanKey;
  PreReadKey     = NowReadKey;
}
复制代码转载

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 加入因仑

本版积分规则

快速回复 返回顶部 返回列表