打印

学习与思考之二

[复制链接]
2347|5
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
天雨粟|  楼主 | 2010-9-21 21:52 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 天雨粟 于 2010-9-21 22:04 编辑

学习与思考之二——这个键盘程序还不错

单片机学习,键盘程序,应该是一个重要的课题。一般介绍单片机的书,对键盘程序的介绍,我总觉得不够深入——篇幅不多,介绍也很简略。对键盘程序作专题研究,是完全可以写一本书的——当然,这有待于高手。我倘能供献一点素材,也就满意了。

这是一个用定时中断写的键盘程序,见于周航慈老师的书。这个程序提供了一种支持长按的办法。

击键,在某些方面很类似于开枪。只支持单击,相当于三八大盖;还支持长按,那就相当于是卡宾枪了。

卡宾枪与三八大盖,那火力是有天壤之别的、技术上也是不可同日而语的,原因在于卡宾枪不仅可以连发即扫射,而且可以单发即点射。

问题其实就在于这里:支持连发,但同时又要支持单发,并且射速还要有一定的范围(太快太慢都不妥)——这就对程序作者提出了很大的挑战!

另外,不支持长按的键,你长时间按着,也只响应一次。好比三八大盖,你扣一次扳机,即便不放手,也只能发射一粒子弹。在三八大盖,这个是自然的,但按键在程序中,还要动些脑筋,才能达到这个效果。

闲言少叙,且看周老师是如何解决这个问题的。

;10ms定时中断键扫描的核心程序

        KEYCODE DATA 38H   ;键码放在38H中
        KEYT   DATA  39H  ;KEYT是键龄,注意周老师提出的这个概念
        KEYOK   BIT  2DH.5 ;键已执行标志

KEY: LCALL KEYIN     ;KEYIN是键扫描子程序,读出的键码放在A中
        CPL A ;无键则读出全1,取反的话则变为0,否则是变不了0的
        JZ KEY0 ;显然前面的那个取反正是为这个判断指令埋下的伏笔
        CPL A ;有按键则恢复键码,这三条指令岂非丝丝入扣呢?
        INC KEYT ;有按键,则键龄加1
        XCH A,KEYCODE; 这条指令很关键

;表面上只是将A与KEYCODE中的值互换,其实其中藏有玄机.开机时KEYCODE
;是随机值,首次执行时装载当前扫描所得键码,而A中装入随机值;二次及以后执行
;时,KEYCODE中仍装载当时键码,但通过这个互换指令,A中却装入了上一次的键
;码,以后始终如此——即新旧两个键码总是分别在A及KEYCODE中!递推?推挽?
;没有合适的词来形容这种现象,只觉得有味哉,其写之也!
;随机值有时是危险的,固建议开机时置KEYCODE为0FFH,使首次执行时与A值绝
;对不同,以牢牢控制程序流程,防止程序流程异常.

          XRL A,KEYCODE
          JZ KEY1 ;相同跳,相异则初始化”键龄”及”已执行”标志,退出
;请注意,检测到”按下” “释放”两个不同的状态,则程序宣布一次按键事件结束,
;即始终以按键弹起来作为按键事件结束标志。也是一手二牍之法。一显然是
;用于“去抖”,二则宣布按键事件结束。其玄机如此。

KEY0: MOV KEYT,#0
         CLR KEYOK
         LJMP KEYEND

KEY1: MOV B,#0FEH ;有有效按键,执行至此,对B进行初始化
;请注意其中的玄机,不管该键是否支持长按,有有效按键,先执行一次再说,
;用此解决所有键都可以点射(单击)功能。

        JNB KEYOK,KEY2 ;未执行跳至KEY2。已执行,判其是否是支持长按的键
        MOV B,#0E7H  ;初始化B备用,以控制射速即响应速度
        MOV A,KEYCODE
        XRL A,#5  ;假设键码为5的键支持长按
        JZ KEY2  ;是则转KEY2,否则退出。
        LJMP KEYOFF  ;捋一下,执行至此是何状态:有有效按键、已执行过
;但不支持长按,则转至KEYOFF处(置已执行标志及清键龄计数器),用此控制不支
;持长按的键按一次(无论久暂)只执行一次,防止误触发。其用心之深,比普通
;按键程序,有几何级数的差异.
  
;KEY2,相当于是C的函数,用KEYT及B传递参数.其功能为二者相加溢出则
;调函数KEY3,否则return(RETI)。
KEY2: MOV  A,KEYT  ;由于B值不同,点射时立即执行,扫射时有节奏地进行
         ADD A,B
         JC KEY3  ;判是否溢出,与定时器原理同
         LJMP KEYEND
         KEY3: MOV A,KEYCODE
;以下就是散转,要注意的是执行了键功能后返回KEYOFF
;处,置已执行标志及清键龄,为下一次读键准备条件

          MOV B,#3
          MUL AB
          MOV DPTR,#KEYN
          JMP @A+DPTR
KEYN: LJMP KEYWK0
          LJMP KEYWK1
          LJMP KEYWK2
  .
  .
  .
KEYOFF:SETB KEYOK
            MOV KEYT,#0
KEYEND:

由于采取按键然后响应这样的编程机制,所以不支持一键多义。如再支持一键多义,其难度又会上升到何种程度,有不可测度者。

有神童级别的人物,不数年功夫,即精通主要的PC机编程语言、主要的嵌入式系统编程语言、主要的绘图软件使用、精通各种单片机、ARM、DSP、FTGP等,至于模电、数电等更不在话下。自己学有年矣,却还在为键盘程序伤脑筋。把自己的学习心得写出来,是想据此推测:高手的高度实在是难以仰望!且与诸位初学们共勉罢!

相关帖子

沙发
xixihaha0| | 2010-9-22 08:43 | 只看该作者
楼主可以看看hot大叔的零耗时键盘,其实不论键盘还是其它程序的处理,状态机与定时器结合的思想是不可少的,

使用特权

评论回复
板凳
highgear| | 2010-9-22 10:31 | 只看该作者
顶认真的思考

使用特权

评论回复
地板
原野之狼| | 2010-9-22 11:35 | 只看该作者
赠条裤子鼓励下~

使用特权

评论回复
5
singleywy| | 2010-9-22 12:11 | 只看该作者
额,学习

使用特权

评论回复
6
天雨粟|  楼主 | 2010-9-23 19:24 | 只看该作者
感谢各位大侠给予的鼓励

且再努力!

使用特权

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

本版积分规则

16

主题

168

帖子

0

粉丝