;EXAM10.ASM
;Matrix KeyBoard 3x4
;
MAXCOL EQU 3 ;Max Column = 3
KEYMARK EQU 00000111B ;Mark bit Use input bit
;User internal ram area
ORG 30H
KeyBuff: DS 1 ;
KeyRow: DS 1 ;Hold Key Row
KeyCol: DS 1 ;Hold Key Col
Key: DS 1
ORG 0000H
;*** Power up delay ***
;Wait for other Device
RES: MOV R2,#40H
RES1: MOV R3,#0
RES2: DJNZ R3,RES2
DJNZ R2,RES1
;*** MAIN ***
MAIN: LCALL InitUART ;Initial UART 9600,n,8,1 no parity
MOV DPTR,#Hello
LCALL SendSROM
Next: LCALL ScanKey ;Read Key Board
MOV A,KEY ;Test Key
XRL A,#00 ;if key = 0
JZ Next ; Yes Scan Next
MOV A,KEY ;Get Key value
LCALL SNDASCII ;Display Key Code
LCALL LineFeed ;Send Line Feed
SJMP Next ;Scan Next
;End Main
;*** Scan Key Board ***
;IN no
;Out KEY =0 not key press
; KEY = 1-n Key press
;
ScanKey:
;ROW0
MOV KeyRow,#00H ;KeyRow = 0
MOV P1,#10111111B ;Test Row0 P1.6 =0
LCALL CHKCOL ;Check Column at Row=0
XRL A,#00H ;Check Key Press
JNZ ScanKX ;Yes Calculate Key Code
;ROW1
MOV KeyRow,#01H ;KeyRow = 1
MOV P1,#1011111B ;Test Row0 P1.5 =0
LCALL CHKCOL ;Check Column at Row=1
XRL A,#00H ;Check Key Press
JNZ ScanKX ;Yes Calculate Key Code
;ROW2
MOV KeyRow,#02H ;KeyRow = 2
MOV P1,#1101111B ;Test Row0 P1.4 =0
LCALL CHKCOL ;Check Column at Row=2
XRL A,#00H ;Check Key Press
JNZ ScanKX ;Yes Calculate Key Code
;ROW3
MOV KeyRow,#03H ;KeyRow = 3
MOV P1,#1110111B ;Test Row0 P1.3 =0
LCALL CHKCOL ;Check Column at Row=3
XRL A,#00H ;Check Key Press
JNZ ScanKX ;Yes Calculate Key Code
MOV Key,#00H ;Return 0 no Key Press
RET
ScanKX:
;Calculate Key Code
;KEY = (ROW*MAXCOL)+COL+1 when Key Code =1 to n
MOV A,KeyRow ;A=ROW
MOV B,#MAXCOL ;B=MAXCOL
MUL AB ;A = ROW*MAXCOL
ADD A,KeyCol ;A = (ROW*MAXCOL)+COL
ADD A,#01H ;A = (ROW*MAXCOL)+COL+1
MOV Key,A ;Save Result to A
RET
;*** Check Column ***
;Scan Colume
;if Key Press
; A=1;
; KeyCol=Column
; KeyRow=Row
CHKCOL:
MOV A,P1 ;Read P1
ANL A,#KEYMARK ;Clear not use bit
MOV KeyBuff,A ;Save to KeyBuff
XRL A,#KEYMARK ;Compare with no Key Conts
JZ CHKCEX ;not Key Press Exit
MOV DPTR,#KDown ;Display Key Down
LCALL SendSROM
;Check Debounce
MOV R2,#10 ;Wait for Read again
LCALL DMSEC
;Read Key again
MOV A,P1 ;Read P1
ANL A,#KEYMARK ;Clear not use bit
XRL A,KeyBuff ;Compare with Old Key
JNZ CHKCEX ;Not same exit
;Release Key
CHKWT: MOV A,P1 ;Read P1
ANL A,#KEYMARK ;Clear not use bit
XRL A,KeyBuff ;Compare with Old Key
JZ CHKWT
MOV DPTR,#KUp ;Display Key UP
LCALL SendSROM
;Get Key Code
MOV A,KeyBuff
ANL A,#KEYMARK ;Clear not use bit
LCALL SNDASCII
MOV A,#'H'
LCALL SBYTE
MOV A,#' '
LCALL SBYTE
;Get Column
MOV A,KeyBuff
ANL A,#KEYMARK ;Clear not use bit
LCALL GetColNo
MOV KeyCol,A ;Save Colunm
MOV A,#'('
LCALL SBYTE
MOV A,KeyCol ;Restore Column for print
LCALL SNDASCII
MOV A,#','
LCALL SBYTE
;Get Row
MOV A,KeyRow
LCALL SNDASCII
MOV A,#')'
LCALL SBYTE
MOV A,#'='
LCALL SBYTE
MOV A,#01H ;Key Press A=1
RET
CHKCEX: CLR A ;No Key Press A=0
RET
;*** Get Column in Count Number 0-n***
GetColNo:
MOV R2,#00H ;Start with 0
GCNX:
RRC A ;Rotage A to Carry
JNC GCEXIT ;Test C=0 (Key Press)
INC R2 ;Increment R2
SJMP GCNX ; and Check nect bit
GCEXIT:
MOV A,R2 ;Store R2 to A
RET
;*** Send ASCII 2 Byte ***
;IN A
;REG R2,R3
SNDASCII:
LCALL HTOA
MOV A,R2
LCALL SBYTE
MOV A,R3
LCALL SBYTE
; LCALL LineFeed
RET
;*** Send String in Program Memory ***
;Input DPTR
SendSROM:
CLR A
MOVC A,@A+DPTR ;load char
JZ EndStr ;yes end
LCALL SBYTE ;send 1 byte
INC DPTR ;point to next char
SJMP SendSROM ;load next char
EndStr: RET
;*** Send String in RAM ***
;Input R0
SendSRAM:
MOV A,@R0
XRL A,#00
JZ EndRStr ;yes end
MOV A,@R0
LCALL SBYTE ;send 1 byte
INC R0 ;point to next char
SJMP SendSRAM ;load next char
EndRStr:
RET
;*** Initial UART ***
InitUART:
MOV SCON,#01010010B ;Set SCON Serial Control Mode 1: 8-bit UART (Timer-Based).
MOV TMOD,#00100000B ;Set Mode 2 8-bit Auto-Reload
MOV TH1,#0FDH ;Set Baud Rate 9600
SETB TR1 ;Enable Timer 1
RET
; ********** SBYTE SUB **********
;SEND BYTE
;IN = A
;REG = NO
SBYTE: JNB TI,SBYTE ;Wait For Sending done
CLR TI
MOV SBUF,A
RET
; ********** RBYTE SUB **********
;OUT = A
;REG = A
RBYTE: JNB RI,RBYTE ;Wait For Receive already
CLR RI
MOV A,SBUF
RET
;*** Send line feed ***
LineFeed:
MOV A,#0Dh
LCALL SBYTE
feed: MOV A,#0Ah
LCALL SBYTE
RET
;*** HTOA SUB ***
;CONVERT HEX TO ASCII
;IN = A
;OUT = R2,R3
;REG = A,R2,R3
HTOA: PUSH ACC
SWAP A
LCALL HTOAS
MOV R2,A
POP ACC
LCALL HTOAS
MOV R3,A
RET
HTOAS: ANL A,#0FH
CJNE A,#0AH,$+3
JNC HTOAS1
ORL A,#30H
RET
HTOAS1: SUBB A,#9
ORL A,#40H
RET
;*** DMSEC SUB ***
;DELAY 1/1000 SECOND
;IN = R2
;REG = R2,R3
DMSEC: MOV R3,#230
DMSEC1: NOP
NOP
DJNZ R3,DMSEC1
DJNZ R2,DMSEC
RET
Hello: DB 0DH,"*** KeyBoard ***",0DH,0AH,00
KDown: DB "KeyDown",00
KUp: DB ",KeyUp ",00
END