微控制器中的按键和按键

时间:2018-10-14 15:52:14

标签: microcontroller keypress keydown gpio 8051

目前,我有两个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的速率连接到另一台设备)。

0 个答案:

没有答案