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

好东西,学习
页: 1 [2] 3 4 5 6
查看完整版本: [分享][交流]发一个通用按键模块,简单易用 [2014-3-24 Update]