File "KEY12.ASM"
Full Path: /home/analogde/www/private/Projet/KEY12.ASM
File size: 3.79 KB
MIME-type: text/plain
Charset: utf-8
;
; KEY12.ASM
; ---------
; KEYPAD routines for Axiom HC12 development boards. KEYPAD uses Port H.
;
; Variables - calling program must reserve these:
; -----------
; Global variables
; OLDKEY 1 byte, stores the previous key value for debouncing
;
; Local variables
; CNT1 1 byte, temporary debounce counter
; TMP1 1 byte, temporary storage variable
;
; Subroutines:
; -----------
; INITKEY: Initialize KEYPAD
; GETKEY: Wait for key released then wait for key pressed. Return it in A
; KEYWAIT: Wait for key to be released
; KEYSCAN: Do a quick scan of the KEYPAD. Return A=key if pressed, 0 if not
; KEYDLY: Delay, wait for lines to settle
; Define Key Character Table
_KEY_TBL: FCC 'A321B654C987D#9*'
;-------
GETKEY:
jsr KEYWAIT ; wait for any keys to be released
jsr KEYSCAN ; scan keypad for new key
tsta ; key pressed?
beq GETKEY ; loop if no
rts
;-------
; loop until no key is pressed
KEYWAIT:
jsr KEYSCAN ; scan keypad
tsta ; key pressed?
bne KEYWAIT ; loop if yes
rts
; Scan KEYPAD for input. return A=0 no input else A=key
; columns are active low, rows are then read active low
KEYSCAN:
bclr PORTH,#$0F ; clear all KEYPAD columns
ldaa PORTH ; get KEYPAD port
anda #$F0 ; key mask
eora #$F0 ; test for any low
beq KEYRESET ; branch if NO key pressed
;-------
; here if a key is pressed, determine which one
KEYSCAN1:
bset PORTH,#$0F ; set all KEYPAD columns HIGH
clrb ; clear row counter
bclr PORTH,#$01 ; clear column 1
jsr KEYSCAN2 ; get KEYPAD row status
bne KEYROW ; branch if a key pressed, find row
ldab #$04 ; next row count
bset PORTH,#$01 ; set column 1
bclr PORTH,#$02 ; clear column 2
jsr KEYSCAN2 ; get KEYPAD row status
bne KEYROW ; branch if a key pressed, find row
ldab #$08 ; next row count
bset PORTH,#$02 ; set column 2
bclr PORTH,#$04 ; clear column 3
jsr KEYSCAN2 ; get KEYPAD row status
bne KEYROW ; branch if a key pressed, find row
ldab #$0C ; next row count
bset PORTH,#$04 ; set column 3
bclr PORTH,#$08 ; clear column 4
jsr KEYSCAN2 ; get KEYPAD row status
bne KEYROW ; branch if a key pressed, find row
bra KEYRESET ; NO key pressed, reset
KEYSCAN2:
jsr KEYDLY ; wait for lines to settle
ldaa PORTH ; get KEYPAD port
anda #$F0 ; key mask
eora #$F0 ; test for any low
rts
; here if a key is pressed, B=row count, A=row value
KEYROW:
clr TMP1 ; clear offset count
KEYROW1:
lsla ; shift row value to low nibble
bcs KEYROW2 ; column found, go compute offset
inc TMP1 ; incriment offset counter
bra KEYROW1 ; loop
KEYROW2:
addb TMP1 ; add column offset to row value
ldx #_KEY_TBL ; get start of key table
ldaa B,X ; load offset key value in a
; key pressed in A, debounce
ldab #$04 ; see if we already debounced this key
cmpb CNT1 ;
bne KEYCOUNT ; branch if not, continue debounce
rts ; same key pressed, already said so, return it
KEYCOUNT:
cmpa OLDKEY ; same key pressed as last time?
bne KEYNEW ; no, debounce new key
inc CNT1 ; incriment debounce counter
ldab #$04 ; finished debouncing?
cmpb CNT1 ;
bne KEYNO ; branch if no
rts ; return key
KEYNEW:
clr CNT1 ; start new key debounce
staa OLDKEY ; save new key for debouncing
KEYNO:
clra ; return no key pressed yet
rts
;-------
KEYRESET:
bset PORTH,#$0F ; set all KEYPAD columns HIGH
; clr CNT1 ; clear debounce counter
clr OLDKEY ; clear any old key
clra ; clear key status
rts
;-------
KEYDLY:
clr TMP1 ; clear offset count
KEYDLY1:
inc TMP1 ; incriment counter
brclr TMP1,#$08,KEYDLY1 ; loop if time not yet up
rts
;-------
; Initialize KEYPAD
; Port H 0-3 must be output
; 4-7 must be input
INITKEY:
ldaa #$0F ; set Port H direction (0=input, 1=output)
staa DDRH ;
rts