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