В настоящее время у меня установлено два микроконтроллера 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
Значение ключа, генерирующее микроимеет кристалл 20 МГц, а другой микро имеет кристалл 22 МГц.
Я мог бы с этим справиться, если бы я установил пороги обнаружения на огромные значения, но я хочу, чтобы нажатия клавиш и обнаружение происходили очень быстро (все в пределах 100миллисекунд на ключевое событие).
Это единственный лучший способ сделать это, или есть еще лучший способ, учитывая мои настройки?помните, у меня есть только две линии GPIO, которые могут отправлять данные назад и вперед между двумя микроконтроллерами, и события клавиатуры должны происходить как можно быстрее, а основной микроконтроллер, который только определяет значение клавиатуры, также имеет действие последовательного порта, происходящее примерно каждые 170 мкс(он подключен к другому устройству через UART на скорости 57600 бит / с).