| 到 
 搜索
 搜索
 热搜: 净化器雕刻机阿莫邮购
 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;
 }
 复制代码转载
 
 
 |