File "key12b.asm"
Full Path: /home/analogde/www/private/Projet/key12b.asm
File size: 4.03 KB
MIME-type: text/plain
Charset: utf-8
;
; KEY12B32.ASM
; ---------
; KEYPAD routines for Axiom HC12 development boards.
;
; 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#0*'
;-------
GETKEY:
jsr KEYWAIT ; wait for any keys to be released
GETKEY2:
jsr KEYSCAN ; scan keypad for new key
tsta ; key pressed?
beq GETKEY2 ; loop if no
rts
;-------
; loop until no key is pressed
KEYWAIT:
jsr KEYSCAN ; scan keypad
tsta ; key pressed?
bne KEYWAIT ; loop if yes
; Scan KEYPAD for input. return A=0 no input else A=key
; columns are active low, rows are then read active low
KEYSCAN:
bclr PORTS,#$0F0 ; clear all KEYPAD columns
jsr KEYSCAN2 ; get KEYPAD row status
beq KEYRESET ; branch if NO key pressed
;-------
; here if a key is pressed, determine which one
KEYSCAN1:
clrb ; clear row counter
bclr PORTS,#$10 ; clear column 1
jsr KEYSCAN2 ; get KEYPAD row status
bne KEYROW ; branch if a key pressed, find row
ldab #$04 ; next row count
bclr PORTS,#$20 ; clear column 2
jsr KEYSCAN2 ; get KEYPAD row status
bne KEYROW ; branch if a key pressed, find row
ldab #$08 ; next row count
bclr PORTS,#$40 ; clear column 3
jsr KEYSCAN2 ; get KEYPAD row status
bne KEYROW ; branch if a key pressed, find row
ldab #$0C ; next row count
bclr PORTS,#$80 ; 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 PORTP ; get KEYPAD port
bset PORTS,#$0F0 ; set all KEYPAD columns HIGH
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
cmpa OLDKEY ; same key pressed as last time?
bne KEYNEW ; no, debounce new key
ldab #$20 ; see if we already debounced this key
cmpb CNT1 ;
beq KEYNO ; branch if no
KEYCOUNT:
inc CNT1 ; incriment debounce counter
ldab #$20 ; finished debouncing?
cmpb CNT1 ;
beq KEYYES ; branch if yes
KEYNO:
clra ; return no key pressed yet
KEYYES:
rts
KEYNEW:
clr CNT1 ; start new key debounce
staa OLDKEY ; save new key for debouncing
clra ; return no key pressed yet
rts
;-------
KEYRESET:
bset PORTS,#$0F0 ; set all KEYPAD columns HIGH
clr CNT1 ; clear debounce counter
clr OLDKEY ; clear any old key
clra ; return no key pressed yet
rts
;-------
KEYDLY:
clr TMP1 ; clear offset count
KEYDLY1:
inc TMP1 ; incriment counter
brclr TMP1,#$10,KEYDLY1 ; loop if time not yet up
rts
;-------
; Initialize KEYPAD
; Port S 4-7 must be output
; Port P 4-7 must be input
INITKEY:
ldaa #$0F0 ; set Port S direction (0=input, 1=output)
oraa DDRS ; Only modify keypad pins
staa DDRS ;
ldaa #$0F ; set port P direction
anda DDRP ; only modify keypad pins
staa DDRP
ldaa PWCTL ; enable port P pull-ups
oraa #$02 ;
staa PWCTL ;
rts