打印

单片机键盘扫描之状态机实现(更正了一BUG)

[复制链接]
楼主: 原野之狼
手机看帖
扫描二维码
随时随地手机跟帖
41
zmlab.com| | 2008-1-8 11:54 | 只看该作者 回帖奖励 |倒序浏览

感觉楼主的方法不很实用

将一根线的电平高低用程序内的一个状态表示,似乎抽象有限,对于更多的多条扫描线的情况,楼主的方法可能就太复杂了。事实上,有必要引入“扫描码”的概念,它反映任一时刻按键的状态,包括多键按下的情况。通过对扫描抹的监控分析就可以进行去抖处理,并产生反映按键操作的“键码”。整个过程可以用很简单的代码实现,本人不日将把此方法整理出来(题目已经想好,叫“简捷的键盘扫描与去抖方法”),与大家交流。

使用特权

评论回复
42
一朝成名| | 2008-1-8 12:13 | 只看该作者

现在造出来的术语太多了

很容易让人迷糊哈哈

使用特权

评论回复
43
keer_zu| | 2008-1-8 14:45 | 只看该作者

裤子终于穿上了 呵呵

使用特权

评论回复
44
lamp| | 2008-1-8 15:10 | 只看该作者

有点意思

使用特权

评论回复
45
双壳蜗牛| | 2008-1-8 15:33 | 只看该作者

保存

好方法,保存了!!

使用特权

评论回复
46
hotpower| | 2008-1-8 20:07 | 只看该作者

哈哈~~~这条裤子穿着实在不容易呀~~~

使用特权

评论回复
47
etual| | 2008-1-8 21:04 | 只看该作者

顶一下

就扫键程序来说,不能说优秀,不过算挺好用的一个了,将所有消息封装起来,不错不错,不过用struct了,感觉不需要用到class.....

楼主考虑一下将最底层的硬件层抽象出来吧,这样程序的方便度会上一个档次,你现在还是跟底层耦合着。

另外,状态机这个东西,用在扫键之是一个例子,如果碰到一些时序控制方面确实非产实用,值得一学。

最后,楼主,写**的开头应该介绍,这个程序的平台,编译环境 等必要信息 ...... (看到头文件才知道是 AVR ,编译器就不知道了.....)

使用特权

评论回复
48
甄蔡组合| | 2008-1-8 21:56 | 只看该作者

顶一下!!经典!

使用特权

评论回复
49
原野之狼|  楼主 | 2008-1-8 21:58 | 只看该作者

这裤子来得还真是不容易啊~~~~

昨晚通宵,今晚劝架,回来后还见裤子,日子还是不错的嘛~~~

HOT大叔,keer_zu,lamp,你们辛苦了。。。。

谢谢大家支持!

回复43楼:zmlab.com 
我写的这个只是基于单线上的事件,如果有多个按键,可以多实例化几个对象来实现,只是组合键的处理上不方便,这个还需要改进,初步的想法就是再抽象出一层来扫描各单线上消息队列,然后再投放消息。你说的扫描码的方式,我倒是想学习一下,尚不知道这种方式下该如何抽象,期待你的大作。
回复49楼:etual
谢谢你写这么多!其实用struct或是class都行,无非是一种表达形式,关键还是方法。这里用的C++是因为编译器支持C++,所以想尝尝鲜,以前都是用C写东西的。
至于你说的上一个档次的抽象,希望你能就这个问题发表进一步的看法,这样大家以及我都能更好的理解。
状态机确实不错,偶也就是这次才看了看,这不,正现学现卖,呵呵。。。
软硬件平台信息已经加上,这个很有用,再次谢谢!

使用特权

评论回复
50
ocon| | 2008-1-9 01:12 | 只看该作者

昨天帮朋友写的一段按键去抖的状态机版,呵呵

功能:按键去抖;
描述:按钮按下时RES1返回1,如果持续按下的时间超过delay_key_on,则置按键状态status_res1为1,不超过则保持status_res1原值;
同样,按钮释放时RES1返回0,如果持续释放的时间超过delay_key_off,则置按键状态status_res1为0,不超过则保持status_res1原值;

step_res1:当前处理状态,按下/释放;
add_res1:用于累计状态持续时间
======================
    switch (step_res1){//处理输入信号
        case 0:
            if(RES1){//如果按钮被按下
                add_res1++;
                if(add_res1>delay_key_on){//如果持续按下的时间足够
                    status_res1=1;//置当前状态为闭合
                    add_res1=0;//清计数器
                    step_res1=1;//进入第二步
                }
            }
            else{
                add_res1=0;//如果按钮被释放,则重新累计
            }
            break;
        case 1:
            if(!RES1){//如果按钮被释放
                add_res1++;
                if(add_res1>delay_key_off){//如果持续释放的时间足够
                    status_res1=0;//置当前状态为释放
                    add_res1=0;//清计数器
                    step_res1=0;//回到第一步
                }
            }
            else{
                add_res1=0;//如果按钮仍然闭合,则重新累计
            }
            break;
        default:
            add_res1=0;//若为其他状态,则初始化
            step_res1=0;
            break;
    }

使用特权

评论回复
51
flandy| | 2008-1-9 09:18 | 只看该作者

使用特权

评论回复
52
liyongzhou| | 2008-1-9 22:17 | 只看该作者

初来乍到

c++

学习啊

使用特权

评论回复
53
LastNew| | 2008-1-10 14:18 | 只看该作者

再顶

再顶,对刚开始用的人很有好处的,比如我,真希望有更多的阿狼

使用特权

评论回复
54
5_0_5| | 2008-1-10 20:31 | 只看该作者

坐会儿

使用特权

评论回复
55
lhj200304| | 2008-1-12 11:36 | 只看该作者

扫描个键盘也用状态机,不实用

扫描个键盘也用状态机,不实用。在显示的间隔时间中把键盘码送出来就行了。并把这个键码存在的时间记录下来。用个函数结合键码和存在时间进行处理,送出键盘编码就行了

使用特权

评论回复
56
hpanfeng| | 2008-1-12 18:25 | 只看该作者

太好了,学习了

太好了,学习了,支持你

使用特权

评论回复
57
橡希| | 2008-1-16 16:10 | 只看该作者

我也来说说我得经验

前些天作了个项目,里面也有按键部分,不过这个按键是PC得按键,键按下向system发make code(通码) 键释放向system 发break code(断码 ),这样打开一个记事本,按下键你就能看到响应得键码对应得字符了。(其实就是PS2 AT键盘,呵呵)

另外,这个键处理还有一个特点,就是单击键,键响应时间短(10ms);连击键,第一次相应时间短(10ms),后面得响应时间稍长(400ms或者500ms)。视觉上得效果就是,当你打击一个字母a时,记事本上立刻会出现a,当你连击a时,第一个a很快出来,之后得a就会以较慢得速率打印出来。

我先参考了别人得一个代码,总结了一套方法:

定义10ms或者20ms扫描

1,首先定义3个key map:

unsigned char newkeymap[]={};
unsigned char oldkeymap[]={};
unsigned char changkeymap[]={};
这3个map得大小可根据键盘数量而定,每位对应一个键,例如16个键,那就可以定义成:

unsigned char  newkeymap[2]={0xff,0xff};
unsigned char  oldkeymap[2]={0xff,0xff};
unsigned char  changkeymap[2]={0xff,0xff};
初值可以都设置位键释放时得状态值。
2,每次扫描求去这3张map得值


step1:  newkeymap 值为读到得键状态
step2:  changkeymap为 newkeymap 与oldkeymap得异或值
step1:  oldkeymap为newkeymap 得copy.

3,根据changkeymap 和newkeymap 判断哪个键按下或者释放了。并对按下得键码作标志,释放得键码清标志,从而控制键连击得操作。(这一步内容比较多)

就大体先介绍这些,希望对大家有用。



使用特权

评论回复
58
zmlab.com| | 2008-1-18 23:00 | 只看该作者

复楼主

答应写的东西已经发了,请见https://bbs.21ic.com/club/bbs/bbsview.asp?essenceID=9079

使用特权

评论回复
59
hotpower| | 2008-1-18 23:12 | 只看该作者

楼上的作文应该是这个吧~~~

使用特权

评论回复
60
zmlab.com| | 2008-1-19 00:12 | 只看该作者

谢谢hotpower!

正是。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则