zhangliang3646
发表于 2013-12-2 22:14:34
mark,学习
wthzack
发表于 2013-12-3 02:33:17
好东西,学习了
1752482885
发表于 2013-12-6 08:34:53
神一样的存在。
zdhxzy1981
发表于 2013-12-6 08:46:57
好东西,下载了学习学习。
山在桥那边
发表于 2013-12-6 10:08:28
学习 mark
喜羊羊
发表于 2013-12-6 15:51:27
好资料,学习了。
dongyanbo
发表于 2013-12-9 21:04:15
mark一下
hamipeter
发表于 2013-12-9 21:17:51
支持一下!!
jzhang123
发表于 2013-12-9 23:12:57
mark
chenting520
发表于 2013-12-10 14:34:54
模块化思维值得借鉴
nishuizhou
发表于 2013-12-11 09:16:33
确实模块化挺好,拿来主义
rexrex
发表于 2013-12-11 09:32:13
好东西,马克一下
zheng8648
发表于 2013-12-11 09:46:28
mark 学习 收藏
swustlx
发表于 2013-12-14 17:04:45
支持一下
yoofe
发表于 2013-12-14 21:45:50
我好像从一本MSP430的书中看到过
dongdaxing
发表于 2013-12-15 11:22:57
高手,真的是高手,果然是精华帖,先MARK一下
hndyk
发表于 2013-12-15 13:55:23
很实用的程序,谢谢楼主分享。
lpdliumyc
发表于 2013-12-17 09:40:09
看了此贴觉得自已也要时不时到论子里转转了,,学习{:lol:}
2012Ehome
发表于 2013-12-21 13:50:07
学习学习
cheng_5230
发表于 2013-12-24 11:14:48
{:smile:}很强大啊 学习了呵呵
Gorgon_Meducer
发表于 2013-12-24 17:48:06
本帖最后由 Gorgon_Meducer 于 2013-12-25 16:43 编辑
更新状态图。
315936392
发表于 2013-12-24 21:35:02
唉 感觉流程图也看不明白?
是不是有点弄复杂了?
shikelang
发表于 2013-12-24 22:19:47
mark一下
江湖笑
发表于 2013-12-24 22:22:00
学习了{:lol:}
xshhou
发表于 2013-12-25 12:36:05
mark一下
passage110
发表于 2013-12-25 12:38:52
好东西,可以用上!
macaroni
发表于 2013-12-25 12:58:25
标题不合格、重复发帖,将会被封锁ID。
bbosliyang
发表于 2013-12-25 15:37:00
傻孩子真是NB,顶一个~!
meirenai
发表于 2014-1-6 00:50:39
学习学习。。。。。。。。。。。。
yh8637
发表于 2014-1-6 11:03:22
收藏学习。。。
wulanhua
发表于 2014-1-20 23:14:04
看了check_key()这个状态机,很想知道 其中为何用了2次计数判断?
第一次是if (0 == s_chCount)s_chHisKeyValue = s_chKeyValue;//这一次s_chCount从65536减到0时才赋值
第二次是if (KEY_COUNT > s_chCount) s_chState = CHECK_KEY_CHECKING; //这一次s_chCount从0加到100时才赋值
第一次计数有何作用? 谁能解答一下,谢谢。
liuzhen526
发表于 2014-1-21 16:16:58
mark按键处理通用模块
y574924080
发表于 2014-1-21 17:32:52
wulanhua 发表于 2014-1-20 23:14
看了check_key()这个状态机,很想知道 其中为何用了2次计数判断?
第一次是if (0 == s_chCount)s_chHisKe ...
该状态机的思路是:
如果 继续检测到 当前键值与历史键值相同就计数+1,反之-1
在计数器 s_chCount 的值为零时, 就把当期的值作为历史键值保存下来,用于比较
在计数器 s_chCount 的值为KEY_COUNT ,就认为又认为是一次有效的检测
不知道我的解释是否能解答你的疑问{:smile:}
lm4766
发表于 2014-1-21 20:11:14
好贴,学习了!
yayagepei
发表于 2014-1-21 21:07:02
好东西啊,顶起
sc_world
发表于 2014-1-21 21:37:03
谢谢分享,学习了{:lol:}
wulanhua
发表于 2014-1-22 00:42:37
y574924080 发表于 2014-1-21 17:32
该状态机的思路是:
如果 继续检测到 当前键值与历史键值相同就计数+1,反之-1
谢谢你的回答,我再仔细看看。
amnumber
发表于 2014-2-5 15:32:48
谢谢分享,学习ing
ztg328
发表于 2014-2-5 22:31:24
果断mark
AbnerSmith
发表于 2014-2-6 23:40:33
mark一下,感谢楼主分享。PS:怎么感觉都是对资料贡献感兴趣呢?问个问题到没人回答,虽然我自己也过激了,一直顶,但好歹也给我个回答不是。。。高手何时出手
chinaboy25
发表于 2014-2-6 23:55:05
make
Gorgon_Meducer
发表于 2014-2-7 12:10:35
AbnerSmith 发表于 2014-2-6 23:40
mark一下,感谢楼主分享。PS:怎么感觉都是对资料贡献感兴趣呢?问个问题到没人回答,虽然我自己也过激了, ...
请问提问在几楼?
AbnerSmith
发表于 2014-2-7 12:29:18
Gorgon_Meducer 发表于 2014-2-7 12:10
请问提问在几楼?
谢版主了,不过差不多解决了。
huojianfei
发表于 2014-2-13 16:16:12
下载,到keil c51下试试
jesen_2010
发表于 2014-2-13 17:17:23
这个要MARK 学习 学习
jesen_2010
发表于 2014-2-13 17:17:49
这个要MARK 学习 学习
zyorai
发表于 2014-2-14 16:53:52
Mark一下,组合按键怎么做呢?
jz701209李
发表于 2014-2-14 23:13:01
学习学习,谢谢
zyorai
发表于 2014-2-18 19:10:14
问个题外话,流程图是用啥画的啊?{:titter:}
radar_12345
发表于 2014-2-18 20:15:19
学习,mark,谢谢
y574924080
发表于 2014-2-18 22:38:48
zyorai 发表于 2014-2-18 19:10
问个题外话,流程图是用啥画的啊?
office word
yoofe
发表于 2014-2-19 10:21:42
大爱这个论坛
zdhxzy1981
发表于 2014-2-19 16:29:19
MARK一下
qingaixww
发表于 2014-2-22 10:33:24
很久没有过来了,真心不错,谢谢!
fuanzwg
发表于 2014-2-22 10:53:32
mark{:hug:}
edkaifa
发表于 2014-2-24 16:36:10
傻孩子工作室作品 精品
qingaixww
发表于 2014-3-1 15:41:36
y574924080 发表于 2014-1-21 17:32
该状态机的思路是:
如果 继续检测到 当前键值与历史键值相同就计数+1,反之-1
在static bool check_key(uint8_t* pchKey)这个函数里,s_chCount不停的自增或者自减,在按键的操作中,会出现s_chCount从1减到0或者从0减到65535的情况,所以在case CHECK_KEY_SCAN这个分支里,代码if (0 == s_chCount)的执行时间将会有65535个周期的差异,会不会影响到按键的消抖效果和响应呢?请大家帮忙解答,谢谢!
y574924080
发表于 2014-3-1 17:08:48
本帖最后由 y574924080 于 2014-3-1 17:11 编辑
qingaixww 发表于 2014-3-1 15:41
在static bool check_key(uint8_t* pchKey)这个函数里,s_chCount不停的自增或者自减,在按键的操作中, ...
多谢指出。
这里的确有一个bug
在s_chCount 为零且获取到的按键值与历史键值不一致时
s_chCount-- 导致向下溢出
我做了一个修正,能帮忙看看么?
static bool check_key(uint8_t* pchKey)
{
static uint8_t s_chState = CHECK_KEY_START;
static uint16_t s_hwCount= 0;
static uint8_t s_chKeyValue = KEY_NULL;
static uint8_t s_chHisKeyValue = KEY_NULL;
switch (s_chState) {
case CHECK_KEY_START:
s_hwCount= 0;
s_chState = CHECK_KEY_CHECKING;
//break;
case CHECK_KEY_CHECKING:
s_chKeyValue = GET_KEY_SCAN_VALUE();
if (s_chKeyValue == s_chHisKeyValue) {
s_hwCount++;
s_chState = CHECK_KEY_FINISH;
} else {
s_chState = CHECK_KEY_SCAN;
}
break;
case CHECK_KEY_SCAN:
if (0 == s_hwCount) {
s_chHisKeyValue = s_chKeyValue;
} else {
s_hwCount--;
}
s_chState = CHECK_KEY_CHECKING;
break;
case CHECK_KEY_FINISH:
if (KEY_COUNT > s_hwCount) {
s_chState = CHECK_KEY_CHECKING;
} else {
*pchKey = s_chKeyValue;
CHECK_KEY_RESET_FSM();
return false;
}
break;
}
return true;
}
修改了一下:变量名和类型不一致
Gorgon_Meducer
发表于 2014-3-3 17:14:03
qingaixww 发表于 2014-3-1 15:41
在static bool check_key(uint8_t* pchKey)这个函数里,s_chCount不停的自增或者自减,在按键的操作中, ...
终于有人认真看代码了,好感动……(赞<<5)
qingaixww
发表于 2014-3-3 17:19:22
y574924080 发表于 2014-3-1 17:08
多谢指出。
这里的确有一个bug
我觉得这样可以,最多只产生KEY_COUNT-1个计数误差,对于按键处理是没有问题的。谢谢你的回复!
qingaixww
发表于 2014-3-3 17:25:31
Gorgon_Meducer 发表于 2014-3-3 17:14
终于有人认真看代码了,好感动……(赞
因为自己的水平很菜,通过拜读坛里的程序,从中得到些感悟,也把自己认为有疑问的地方提出来。谢谢傻孩子老师的鼓励,每天都盼着老师的新书能快点出版啊!
cld795
发表于 2014-3-3 22:51:52
学习…………
yjsjsy
发表于 2014-3-7 23:12:21
请问如何识别多个按键同时按下呢?
y574924080
发表于 2014-3-8 01:24:31
yjsjsy 发表于 2014-3-7 23:12
请问如何识别多个按键同时按下呢?
要识别多个按键,首先要考虑的是 :硬件是否支持多个按键同时按下?
例如矩阵按键,随便找个电路:
这种电路是无法完全正确识别三个按键同时按下的。
在硬件支持的情况下,检测到多个按键按下,就返回一个新的键值,代表组合按键
ericdai
发表于 2014-3-8 08:26:24
为啥不做成成品卖呢像排队机呼叫器点菜宝都会用到啊
yjsjsy
发表于 2014-3-8 10:01:21
y574924080 发表于 2014-3-8 01:24
要识别多个按键,首先要考虑的是 :硬件是否支持多个按键同时按下?
例如矩阵按键,随便找个电路:
嗯!比如独立按键,第一个按下,不松。第二个接着按下,这样这个程序就识别不了第二个按键了,这个模块能实现么?根据程序是实现不了吧?
y574924080
发表于 2014-3-8 10:30:04
yjsjsy 发表于 2014-3-8 10:01
嗯!比如独立按键,第一个按下,不松。第二个接着按下,这样这个程序就识别不了第二个按键了,这个模块能 ...
好吧,假设硬件能识别多个按键同时按下,第一个我返回键值KEY1,第二次我检测到两个按键,返回键值KEY3代表新的组合键,这就可以
yjsjsy
发表于 2014-3-8 10:34:39
y574924080 发表于 2014-3-8 10:30
好吧,假设硬件能识别多个按键同时按下,第一个我返回键值KEY1,第二次我检测到两个按键,返回键值KEY3代 ...
哦哦,对你提供的例子是两个独立按键的判断,并没有判断连个按键同时按下时的现象(返回值),明白了楼主,谢谢哦!
wspytu
发表于 2014-3-8 10:44:20
好贴,正需要,谢谢楼主!
yjsjsy
发表于 2014-3-8 10:47:17
请问,按键模块的消抖函数在哪?学习学习!
y574924080
发表于 2014-3-8 11:09:15
yjsjsy 发表于 2014-3-8 10:47
请问,按键模块的消抖函数在哪?学习学习!
请对照楼主位的图,和程序一起看
danfeidie
发表于 2014-3-8 11:18:57
果断标记,比我写得好
Vampireyifeng
发表于 2014-3-8 12:36:13
好贴啊,mark一下
chenguanghua
发表于 2014-3-8 13:21:36
Gorgon_Meducer 发表于 2013-12-24 17:48
更新状态图。
我看了下代码,按键支持包括按下检测、松手检测、长按、连按
如果能够支持 “双击或者多击”+“组合按键”
那么这个通用按键模块算是全了
foxpro2005
发表于 2014-3-9 23:13:30
y574924080 发表于 2014-3-1 17:08
多谢指出。
这里的确有一个bug
今天有时间看了一下代码,感觉还可以做如下优化:
(声明,本人是小白菜,说错了还望包涵...{:lol:} )
y574924080
发表于 2014-3-9 23:35:57
foxpro2005 发表于 2014-3-9 23:13
今天有时间看了一下代码,感觉还可以做如下优化:
(声明,本人是小白菜,说错了还望包涵... )
...
主要是考虑周期性的脉冲干扰,在这种情况下,我觉得计数自减比直接清零合理
y574924080
发表于 2014-3-9 23:39:48
foxpro2005 发表于 2014-3-9 23:13
今天有时间看了一下代码,感觉还可以做如下优化:
(声明,本人是小白菜,说错了还望包涵... )
...
注释写的很赞!
话说看到注释我吃了一惊,记得没写注释的啊
下了源码看看,确认了的确没有,{:lol:}
nuncle
发表于 2014-3-10 08:34:53
MARK 流的一笔{:lol:}
wxty
发表于 2014-3-11 08:44:48
mark once .
pangweishen
发表于 2014-3-11 09:43:36
mark············
jiayue12450
发表于 2014-3-11 10:26:32
留记号,标记一下,慢慢学
himan
发表于 2014-3-11 13:09:45
多功能按键检测哦
sunliezhi
发表于 2014-3-11 14:08:56
代码风格好,看起来就是爽心悦目!
yyinfo263
发表于 2014-3-11 22:46:39
很详细的讲解还有流程图 好好学习下!
夜里的雪
发表于 2014-3-12 09:24:44
很好啊!!学习了!!
cld795
发表于 2014-3-16 13:38:32
学习
zkf0100007
发表于 2014-3-16 15:06:18
好东西,赞一个
foxpro2005
发表于 2014-3-16 17:27:00
y574924080 发表于 2014-3-9 23:35
主要是考虑周期性的脉冲干扰,在这种情况下,我觉得计数自减比直接清零合理
...
由于这几天比较忙, 没来得及看帖子, 今天接着上次的讨论。
如果说要考虑到周期性的脉冲干扰的话:
1. 正如您所说, 如果对于那种 干扰脉冲的高低电平的宽度不一样的情况 , 我们假设低电平为识别有效, 若出现的干扰脉冲低电平 大于 高电平的时间, 同时干扰脉冲群的重复出得的间隔时间又小于按键消抖的时间, 这样会不会导致 s_hwCount 自减的量小于自加的量, 将造成相当于跳过了按键消抖处理真正需要的时间长短, 最终可能会 导致出现在没有按键的情况下, 由于干扰脉冲群引起的按键错误识别。
2. 对于我上面提出的方法而言, 如果这些干扰脉冲出现的间隔周期(即:N个脉冲群 重复出现的间隔周期)大于 按键消抖的时间,那么按键操作将会是 有效可靠的; 反之,如果脉冲干扰群重复出现的周期 小于 按键消抖时间, 那么按键操作将一直处于无效状态 ,即按键操作被消抖处理掉了。 然而,对于这种情况,似乎应该考虑硬件是否合理, 若对于已知干扰脉冲群周期时间,在硬件无法解决的情况下可以修改按键消抖时间长短来解决之。(或许是比较笨的方法...)
ilovemysel
发表于 2014-3-16 17:42:26
不错,好东西
y574924080
发表于 2014-3-16 22:32:48
foxpro2005 发表于 2014-3-16 17:27
由于这几天比较忙, 没来得及看帖子, 今天接着上次的讨论。
如果说要考虑到周期性的脉冲干扰的话:
我完整的说说我的思路:
首先怎么算是按键有效按下,稍微理想的情况是,连续多次采样,
都是同一个键值,那么认为按键有效按下。
但是这样无法应付这样的情况:周期性的干扰。例如,考虑极端
情况,在多次采样中,总有一次干扰,那就悲剧了。
那干扰和按键按下的本质区别是什么?
那即是:干扰相对按下始终是短暂的。只要连续多次读到相同的值,
就可以认为是按键按下。这样我们就可以得到以下思路:
连续采样,采样次数达到一定值时,认为有效按下。干扰来了,次
数减1。
foxpro2005
发表于 2014-3-16 23:03:50
y574924080 发表于 2014-3-16 22:32
我完整的说说我的思路:
首先怎么算是按键有效按下,稍微理想的情况是,连续多次采样,
是的,对于连续采样的过程中, 总有一次或几次干扰一下, 那么这个按键操作可能 会消抖处理掉, 极端的情况下,就是按键操作将无效。
但又有另外一个问题,在干扰严重(可能有点极端了),如果自减的次数远小于自加的次数,会不会出现干扰导致按键的误识别呢?
y574924080
发表于 2014-3-16 23:38:10
foxpro2005 发表于 2014-3-16 23:03
是的,对于连续采样的过程中, 总有一次或几次干扰一下, 那么这个按键操作可能 会消抖处理掉, 极端的情 ...
的确是有这种可能
但是这样干扰和按键按下就没有区别了
软件怎么做都无法区分了
所以软件上不考虑这种情况
wxty
发表于 2014-3-17 14:44:53
楼主请教下,主循环get_key()取出并处理消息。5ms中断(因主循环每次时间可能有较大差异)调用key_task()存入消息。
结果悲剧了,get_key()出队时,可能来中断入队,但不能重入。
目前处理的办法是将get_key()时,关掉中断。
有什么好的办法么?
y574924080
发表于 2014-3-17 15:14:09
wxty 发表于 2014-3-17 14:44
楼主请教下,主循环get_key()取出并处理消息。5ms中断(因主循环每次时间可能有较大差异)调用key_task()存 ...
key_task() 我是把它放在主循环中一直不停的执行,
因为这个任务不算紧急,而且不是很快就能完成的,所有没有尝试过放在中断中。
至于get_key(),在有需要获取按键消息的时候,调用它获取
Gorgon_Meducer
发表于 2014-3-17 17:16:29
wxty 发表于 2014-3-17 14:44
楼主请教下,主循环get_key()取出并处理消息。5ms中断(因主循环每次时间可能有较大差异)调用key_task()存 ...
请在队列代码里面加入对中断的临界区保护,具体就是加入SAFE_ATOM_CODE,请楼主补充这部分内容,
并更新代码。That's a order!
wazhiyi
发表于 2014-3-17 17:22:23
mark一下,傻孩子的思想啊
wxty
发表于 2014-3-17 18:46:34
本帖最后由 wxty 于 2014-3-17 18:49 编辑
Gorgon_Meducer 发表于 2014-3-17 17:16
请在队列代码里面加入对中断的临界区保护,具体就是加入SAFE_ATOM_CODE,请楼主补充这部分内容,
并更新 ...
谢谢啊,等更新了来下载参考!
在原代码基础上,今天刚增加了一个双击功能:
-------------------------------------------------------------------------------- 编辑:添加分隔符 --------------------------------------------------------------------------------
双击事件测试OK。
组合按键识别暂时没有找到方法。
Gorgon_Meducer
发表于 2014-3-24 22:51:41
更新日志
- 2014-3-24
a. 修改key_queue接口:增加中断保护修改注释风格
b. 更新Demo工程,并将key_task放入到system tick 异常处理程序中
LOVEDZKF
发表于 2014-3-27 14:34:55
mark都。
wangsgw68
发表于 2014-3-30 23:14:28
好东西,学习