目前,我有两个AT89S52微控制器设置,其中一个用于确定按下哪个键的艰苦工作。如下所示。它在计时器中断内运行。
;KEYxOI = GPIO pin x of 2 pins representing the final key output value
keyinput_timer:
mov SAVEDPSW,PSW ;save registers
mov SAVEDACC,A
mov KEYCFG,#0h ;reset key setup
mov TH0,#0FBh ;run this function every 1ms
mov C,KEY1I ;Load value from first key GPIO pin
mov A,KEY1S ;Get value from first key byte buffer
rlc A ;shove in new bit
mov KEY1S,A ;save key byte buffer
jnz nkp1 ;if buffer isn't cleared then key isn't pressed
setb KEY1OI ;set output GPIO pin to key if pressed
nkp1:
mov C,KEY2I ;Do same with second key
mov A,KEY2S
rlc A
mov KEY2S,A
jnz nkp2
setb KEY2OI
nkp2:
mov C,KEY3I ;And with third key
mov A,KEY3S
rlc A
mov KEY3S,A
jnz nkp3
mov KEYCFG,#KEYALL ;Here we set KEY2OI + KEY1OI simultaneously
nkp3:
mov PSW,SAVEDPSW ;restore PSW
mov A,P1
anl A,#3Fh
orl A,KEYCFG
mov P1,A ;Modify output hardware now to reflect new KEY2OI + KEY1OI values
mov A,SAVEDACC
reti
从我的角度来看,此代码很好,因为它可以检测到密钥。它在两个GPIO引脚上输出一个二进制代码,表示按下哪个键。
但是我想做的是检测何时按下某个键以及何时按下该键(当键状态从按钮变为未按下时)。
到目前为止,这是我在第二个检测密钥的微控制器中拥有的:
;function executes as often as possible except for when serial port action
;occurs at every about 175uS
scankeys:
mov A,UKEY1 ;load key1 buffer
mov C,KEY1 ;load LSB of the two-bit key value from other micro
addc A,#0h ;add to the buffer if LSB=1
subb A,#0h ;subtract 1 from buffer if its overflowed
mov UKEY1,A ;store new key1 buffer
mov A,UKEY2 ;do the same for key 2
mov C,KEY2
addc A,#0h
subb A,#0h
mov UKEY2,A
ret
;This function gets called only when the program
; is interested in what key is pressed or held at the time
KEY1DOWN bit KEYS.0
KEY1HELD bit KEYS.1
KEY2DOWN bit KEYS.2
KEY2HELD bit KEYS.3
KEY3DOWN bit KEYS.4
KEY3HELD bit KEYS.5
getmykey:
mov KEYS,#0h ;Assume nothing is pressed or held
mov A,UKEY1 ;Check first key buffer
jz nop1
cjne A,#1h,nop1
setb KEY1DOWN ;Key was detected 1 time
subb A,#8h
jc nop1
setb KEY1HELD ;key was detected at least 9 times
nop1:
mov A,UKEY2 ;do same detection for second key
jz nop2
cjne A,#1h,nop2
setb KEY2DOWN
subb A,#8h
jc nop2
setb KEY2HELD
nop2:
jnb KEY1DOWN,nokd
jnb KEY2DOWN,nokd
setb KEY3DOWN
nokd:
jnb KEY1HELD,nokh
jnb KEY2HELD,nokh
setb KEY3HELD
nokh:
mov UKEYS,KEYS ;store key results
clr A
mov UKEY1,A ;reset key counters
mov UKEY2,A
ret
生成键值的微型计算机具有20Mhz的晶体,另一个微型计算机具有22Mhz的晶体。
如果我将检测阈值设置为很大的值,但我希望按键和检测能够非常快地发生(每个按键事件都在100毫秒之内),我可能会摆脱它。
这是执行此操作的唯一最佳方法,还是在我的设置中有更好的方法?记住,我只有两条GPIO线可以在两个微控制器之间来回发送数据,并且键盘事件必须尽快发生,并且仅检测键盘值的主微控制器也每隔约170uS发生一次串行端口动作。 (它通过uart以57600bps的速率连接到另一台设备)。