|
51单片机的RAM太珍贵,用一个字节保存键值,现在的单片机完全可以不顾记这些了。这是早去汇编代码。
pdf,doc,rar文件无法上传,只能COPY过来。版面乱了一些。图片也过不来?
如何编制高效的键译程序
摘 要: 传统教科书中介绍的单片机键译程序有较大的弊端,它实时性差;占用MCU时间长;编制繁杂。为此提出新的键译程序结构,有效克服了上述缺点。
关键词:键译程序、单片机
在单片机应用系统中,键译程序是非常重要的。它直接影响人、机对话操作的方便,同时MCU在忙于各项任务时还要保证实时检测键盘。如何高效地处理键译程序是单片机开发者面对的一个问题。
一、 传统的键译程序(流程图见图1)
1.这个经典的键译流程图存在一个致命的缺点,在程序中有两处延时:1、延时:20MS去抖动;2、判别按键是否释放。它们占用了MCU大量的时间,如果系统中有需要及时处理的数据,则MCU无法处理。影响了系统的工作性能。有些设计者将一些实时需要处理的子程序替代延时,但是有时替代延时的子程序执行时间长短不确定, 造成键译程序中去抖动不可靠。当有多个需要实时处理的任务时,根本无法解决问题。
2.“延时按键处理”的功能实现
有许多智能产品为了减少按键的数量采用了“一键多用”的方法,往往按下一个键几秒钟,便进入另一个功能程序。例如:查看时采用单击方式;设置参数时采用延时方式。当键译程序要完成几秒钟延时则必须加入一个计时指针以及相应的标志,才能实现,增加了程序编制的难度。
二、改进后的键译程序(流程图见图2)
1.将键译程序分解成5个小任务,由MCU“分时”单独完成,在每个小任务中不出现延时程序,这样MCU就有足够的时间去执行:需要实时响应的程序,整体的性能大大提高。
0#~5#功能处理说明:
2.改进后的键译程序的详细说明
2.1 设置三个控制字:
(1)KeyMode:键译程序散转控制字。它控制MCU进入6个任务中的哪一个任务,取值范围:0~5。
(2)KeyData:键值存放单元。它存放键译后的键值,取值范围:0~31。它的最高位D7位是此键值可用标志;D6位是单击、连击(如:3秒)标志。各位定义见图3。
(3)KeyCount:延时指针。它控制去抖动的时间、连击的时间(如果连击时间要求很长,则需要设置两个延时指针)。它的取值取决于主程序的执行时间。
2.2 在键功能散转处理程序中加入对KeyData的D7、D6位判别程序,再进入正常处理程序(程序见下、流程图见图4)。
KeyTrans: mov a,KeyData
Jb acc.7 ,DoKey
RET ;键值无用返回
DoKey: Jb acc.6 ,DubKey ;连击处理
;单击处理(键功能散转处理程序)
mov KeyData,#0
。。。
RET
DubKey: ;连击3S处理程序,A=键值
mov KeyData,#0
。。。
RET
三、结束语:
通过由上述处理,将键译程序分解成5个小程序后,每个小程序均模块化,相互独立,修改方便,大大减少了键译程序占用MCU执行时间的问题。提高了系统的实时性。
源程序:
;###################################
;keybord_program
;***************
;扫描4个键,得到8种键状态。由于程序小将#4功能与#3功能合并。
key_data equ 24h ;KeyData
key_mode equ key_data+1 ;KeyMode
key_dog equ key_mode+1 ;KeyCount
dog_20ms equ 01 ;KeyCount的值X=20mS
dog_3s equ 200 ;KeyCount的值X=3S
key_da equ 0fh ;4个键占用低四位
key_port equ p2 ;键盘占用端口
beep_out bit p1.1;蜂鸣
;*********************************************
key_bord:
mov a,key_mode
cjne a,#0,key_bo1
;read port for key
mov key_data,#0
mov a,key_port
anl a,#key_da
cjne a,#key_da,key_bo12
ret
key_bo12:
mov key_dog,#dog_20ms
mov key_mode,#01
clr beep_out
ret
;****************************
key_bo1:
cjne a,#1,key_bo2
;jb dog_20ms
djnz key_dog,key_bo1_end
;count key_data
mov a,key_port
anl a,#key_da
cjne a,#key_da,key_bo24;
mov key_mode,#0
key_bo1_end:
ret
key_bo24:
;****count key_data
jb acc.7,key_d1
mov key_data,#01
key_d1:
jb acc.6,key_d2
mov key_data,#02
key_d2:
jb acc.5,key_d3
mov key_data,#03
key_d3:
jb acc.4,key_d4
mov key_data,#04
key_d4:
mov key_dog,#dog_3s
mov key_mode,#02
setb beep_out
key_bo22:
ret
;*****************************
key_bo2:
cjne a,#2,key_bo3
djnz key_dog,key_bo32
;********setb key_data.7=1
mov a,key_data
setb acc.7
mov key_data,a
sjmp key_bo33
key_bo32:
;***** 判别释放
;;;;!!!!!!!!!!!!
mov a,key_port
anl a,#key_da
cjne a,#key_da,key_bo3 ;没有释放
key_bo33:
mov key_mode,#0
key_bo3:
ret
|
阿莫论坛20周年了!感谢大家的支持与爱护!!
该献的血还是要献的。你不献他不献。难道让我去献? --- 出自坛友:lovejp1981
|