Code:
' KEY_FSM.BS2
' Tracy Allen, http://www.emesystems.com
' scans a 16 key (4x4) matrix keypad
' using state machine for debouncing, all keys in parallel
' The columns are connected to BS2 outputs of port C, P8 to P11
' The rows are connected to BS2 inputs of port D, P12 to P15
' with pull-up resistors to Vdd=+5 volts.
' This routine has two output variables, "keys" and "keyx"
' Bits in "keys" go low after the corresponding key is
' pressed and debounced.
' Bits in "keyx" go high for _one iteration only_ to signal
' a high to low transition (button pushed & debounced)
' of the corresponding key
' In all state variables, each bit corresponds to one key.
' One word is used for 16 keys, in a 4x4 array.
' This uses a lot of variables, but in many applications it is
' possible to reuse most of the variables outside the keyscan loop
' Note that the scan can detect key combinations.
' The decoding step can miss keys only if they are pressed at
' exactly the same instant.
kout var outC ' 4-bit keypad columns, state, if output
kdir var dirC ' 4-bit keypad columns, input or output
kin var inD ' inputs from keypad rows connected to port D
' bit low for key pressed
key0 var word ' state variable, first detection
key1 var word ' state variable, second detection
key2 var word ' state variable, third detection
keyn var key0.nib0 ' address the first detection as nibble array
keys var word ' debounced output, bit low for key pressed
keyz var word ' state variable, previous state of keys
keyx var word ' transition output, bit high one iteration for each press
ix var word ' index for array addressing
dirs=%0000111111111111 ' port D is input, all others output
outs=%0000000000000000 ' start with port C columns output low
' pins P0 to P7 are not used in this program
debug cls ' Clear screen
scanloop:
key2=key1 ' move the debounced states
key1=key0
for ix=0 to 3 ' scan 4 cols by bringing one col at a time low.
kdir = dcd ix ' 0001,0010,0100,1000 in succession
' this makes one column at a time output low
' while the other columns are inputs
keyn(ix)=kin ' read the row inputs into nibbles of key0
next
kdir = %1111 ' make all columns output (avoid floating inputs)
keys=key0&key1&key2|keys ' key bit 0->1 when all 3 are high
keys=key0|key1|key2&keys ' key bit 1->0 when all 3 are low
keyx=keys^keyz & keyz ' detect change 1->0 (active low keypress)
keyz=keys
' optional debug to visualize operation of the state machine
' slows down the operation tremendously
' debug home,bin16 key0,cr,bin16 key1,cr,bin16 key2,cr
' debug bin16 keys,32,bin16 keyx,home
' optional branch to decode keypress, note keyx is transient
if keyx>0 then decode
' pause 30 ' optional delay to slow the scanning
goto scanloop
decode:
code1 var byte ' code1 variable
code1 = ncd keyx-1 ' binary encode the most significant key
lookup code1,[10,7,4,1,0,8,5,2,11,9,6,3],code1 ' translate to code
dtmfout 7,[code1] ' send as touchtone
lookup code1,["0123456789*#"],code1 ' --> printable character
debug code1 ' print on screen
goto scanloop
Thanks,
Bookmarks