Keyboard not responding with 8051

Thread Starter

testuserabcdef

Joined Jul 12, 2016
127
circuit.png

This is my keypad circuit which uses only two GPIO lines of a microcontroller.
I'm trying to determine in an asynchronous way, what key (if any) is pressed
and for how long. The middle key pressed is the same as the two outer keys
pressed at the same time.

The problem is, no key is ever returned and the next function doesn't start even if the
correct key is pressed.

In the circuit, the resistors are 10K, and capacitors are 470pF.
I want users to be able to press the same button up to 5 times a second.

Would I be able to get away with using simpler code and larger value
capacitors and/or resistors, or are there changes I can make to this code to make it work?
I don't mind replacing capacitors and resistors, and if it helps, I could add more
diodes as well.

At this time, schmitt triggers are not an option for me as I have already built the PCB.

Which is better. Increase Resistors, Increase Capacitors, or modify my code?

If modify code, please explain. If Increasing resistors and/or capacitors are better, please
suggest the minimum values I should be using.

Thanks.

Code:
;LKEY = left button
;RKEY = right button
;other values use their own internal memory locations 

getakey:
;Firsy 8 lines load the real-time key press value into accumulator
mov C,LKEY
cpl C
mov KEYS.1,C
mov C,RKEY
cpl C
mov KEYS.0,C
mov A,KEYS
anl A,#3h
;here, A=0 for no key or 1 for left, or 2 for right, or 3 for center.
clr C
jz gotakey
;Key pressed for at least 600 nanoseconds, increment hold counter
mov KEYTEMP,#0h
inc KEYHOLD
mov A,KEYHOLD
jnz keyend 
;Key is legit pressed if held down for 153uS (.6uS per instruction times 256)
setb KEYS.2 ;set 3rd bit
mov KEYHOLD,#0FFh 
mov KEYTEMP,KEYS ;and store value with 3rd bit set into temp
;below 9 lines increment 16-bit counter (KEYMDH:KEYMD) once per function
;execution until value is FFFFh. Counter is used to determine how many seconds key is down
inc KEYMD
mov A,KEYMD
jnz keyend
inc KEYMDH
mov A,KEYMDH
jnz keyend
mov KEYMD,#0FFh
mov KEYMDH,#0FFh
sjmp keyend
gotakey:
;Here, no key is pressed for at least 600 nanoseconds
mov KEYMDH,#0h
mov KEYMD,#0h
dec KEYHOLD ;emulating a large capacitor here
mov A,KEYHOLD
inc A
jnz keyend
;key legitimately released
mov KEYHOLD,#0h
jnb KEYHCT,keyend ;KEYHCT = KEYTEMP.2
;here, button was fully pressed (KEYHCT=1) and fully released 
clr KEYHCT
clr KEYS.2
setb C ;set legit press status
keyend:
mov A,KEYTEMP
anl A,#7h
mov R6,A ;R6=whatever key was pressed and whether or not it was held down
mov A,KEYMDH ;A times 40ms = how long key was held down without releasing it
jnc noreskey
mov KEYTEMP,#0h ;if key was fully pressed, reset temp so wrong key data isn't sent
noreskey:
ret


Sample of mainline code calling the function:

KCENTERH equ 7
KCENTER equ 3

mov R4,#1h ;start with first menu
reset:
lcall printmenu ;R4 defines menu screen. function prints it.
menu:
;loop restarts here if key pressed isn't acceptable for the menu option
lcall getakey ;this function cannot cause a lock-up
;reset on hold-center on any menu for 5 seconds
cjne R6,#KCENTERH,nocenthold
;enter here if center button is held down (this doesn't work)
subb A,#7Fh ;determine if button held for 5s
jc noreset
;5+ seconds elapsed, so set menu to 1 and force reset
mov R4,#1h
ljmp reset
noreset:
clr C ;clear carry 
nocenthold:
mov A,R4 ;save current menu number
cjne R4,#1h,handler1
;first menu accepts middle button
cjne R6,#KCENTER,sk
mov R4,#2h ;enter menu 2 because middle button pressed (currently doesnt work)
sk:
ljmp menub
handler1:
cjne R4,#2h,handler2
;second menu (incomplete). should arrive here after button press but not working
ljmp menub
handler2:
ljmp menu
menub: 
;check value
subb A,R4
jz nochg
;if menu number changed go back to the beginning of the menu system with new menu value
ljmp reset
nochg:
;if menu number didn't change then read new key
ljmp menu
 
Top