$NOPAGING
$MOD252
;---------------------------------------------------------------------------------------------------------------------
;Code: 4x4 matrix key pad
;Inputs: hex keypad via port1
;Outputs: ASCII value of pressed button is sent through the serial port and also the hex equivalent is ouput thru p3.5 to p3.2
;--------------------------------------------------------------------------------------------------------------------
ROW0 EQU P1.0
ROW1 EQU P1.1
ROW2 EQU P1.2
ROW3 EQU P1.3
CLMN0 EQU P1.7
CLMN1 EQU P1.6
CLMN2 EQU P1.5
CLMN3 EQU P1.4
DIGIT DATA 30h ;temporary storage of pressed key ..
ALERT EQU P3.7 ;goes low when any key's pressed ..
ORG 0000h
LJMP Ks_Main
ORG 0030h
;_________________________________________________________________
;----------SERIAL PORT INITIALISATION STARTS HERE-----------------
;_________________________________________________________________
S9k_Main: MOV TMOD,#20h ;timer_0 in mode2 (8bit auto reload) ..
MOV TH1,#0fdh ;set baud to 9600 ..
MOV SCON,#50h ;serial mode1 (8bit data varialble baud) ..
SETB TR1 ;start timer_0 ..
RET
;--------------SERIAL TRANSMIT SUBROUTINE-------------------------
Tx_Main: MOV SBUF, A
Tx_Loop: JNB TI, Tx_Loop
CLR TI
RET
;--------------SERIAL RECIEVE SUBROUTINE--------------------------
Rx_Main: CLR A
Rx_Loop: JNB RI, Rx_Loop
MOV A, SBUF
CLR RI
RET
;----------------------20ms delay---------------------------------
Delay_20ms: ;PUSH R0
;PUSH R1
MOV R0, #36
Delay_20ms_Loop1: MOV R1, #255
Delay_20ms_Loop2: DJNZ R1, Delay_20ms_Loop2
DJNZ R0, Delay_20ms_Loop1
;POP R1
;POP R0
RET
;------------------------display subroutine--------------------------------
Disp_Message: PUSH ACC
Disp_M_Loop1: MOV A, #00h ; reset accumulator ..
MOVC A, @A+DPTR
CJNE A, #00h, Disp_M_Loop2
POP ACC
RET
Disp_M_Loop2: MOV SBUF, A
LCALL Tx_Main
INC DPTR
LJMP Disp_M_Loop1
Disp_Pressed: DB ' Key pressed is: ', 00h
;----------------packed ascii to hex conversion------------------
Ascii2hex: PUSH ACC
MOV A, DIGIT
SUBB A, #30h
MOV B, A
ANL A, #10h
CJNE A, #00h,Ascii2hex_Loop2
MOV B, A
Ascii2hex_Loop1: MOV DIGIT, A
POP ACC
RET
Ascii2hex_Loop2: MOV A, DIGIT
SUBB A, #37h
SJMP Ascii2hex_Loop1
;------------------send pressed button via p3----------------------
Send4x4_Parallel: PUSH ACC
MOV A, DIGIT
RRC A
MOV P3.5, C ; LSB ..
RRC A
MOV P3.4, C
RRC A
MOV P3.3, C
RRC A
MOV P3.2, C ; MSB ..
POP ACC
RET
;_________________________________________________________________
;-------------------------main code------------------------------
;_________________________________________________________________
Ks_Main: MOV P1, #0FFh ; Make input ports ..
;mov p3,#00h ;make output ports; never make this mistake => 3.0 n 3.1 are serial pins
SETB ALERT
LCALL S9k_Main
Ks_Main1: MOV P1, #0F0h ; all columns high n rows low ..
MOV A, P1
ANL A, #11110000b ; consider only columns ..
CJNE A, #11110000b, Ks_Main1 ; initially check for all keys released ..
;-------------------------------------------------------------------
Ks_Loop1: LCALL Delay_20ms
MOV A, P1
ANL A, #11110000b ; scan columns ..
CJNE A, #11110000b, Debounce ; if key pressed, check debounce ..
SJMP Ks_Loop1 ; if not, keep checking for key pressed ..
;-------------------------------------------------------------------
Debounce: LCALL Delay_20ms
MOV A, P1
ANL A, #11110000b
CJNE A, #11110000b,Check_Row
SJMP Ks_Loop1
;--------------------------------------------------------------------
Check_Row: MOV DPTR, #Disp_Pressed
LCALL Disp_Message
CLR ROW0
SETB ROW1
SETB ROW2
SETB ROW3
MOV A, P1
ANL A, #11111110b ; test row zero ..
CJNE A, #11111110b, Row_0
;--------------------------------------------------------------------
SETB ROW0
CLR ROW1
SETB ROW2
SETB ROW3
MOV A, P1
ANL A, #11111101b ; test row one ..
CJNE A, #11111101b, Row_1
;---------------------------------------------------------------------
SETB ROW0
SETB ROW1
CLR ROW2
SETB ROW3
MOV A, P1
ANL A, #11111011b ; test row two ..
CJNE A, #11111011b, Row_2
;---------------------------------------------------------------------
SETB ROW0
SETB ROW1
SETB ROW2
CLR ROW3
MOV A, P1
ANL A, #11110111b ; test row three ..
CJNE A, #11110111b, Row_3
;----------------------------------------------------------------------
SJMP Ks_Loop1
;----------------------------------------------------------------------
Row_0: MOV DPTR, #Disp_Kcode0
SJMP Find_Num
Row_1: MOV DPTR, #Disp_Kcode1
SJMP Find_Num
Row_2: MOV DPTR, #Disp_Kcode2
SJMP Find_Num
Row_3: MOV DPTR, #Disp_Kcode3
SJMP Find_Num
;----------------------------------------------------------------------
Find_Num: RLC A
JNC Found_Num ; which column is pressed/grounded ..
INC DPTR
SJMP Find_Num
;----------------------------------------------------------------------
Found_Num: CLR ALERT ; notify main MC that key has been pressed ..
CLR A
MOVC A, @A+DPTR
MOV DIGIT, A
LCALL Tx_Main ; send pressed button to serial port ..
LCALL Ascii2hex
LCALL Send4x4_Parallel
SETB ALERT ; bring keypad module to waiting state ..
;-----------------------------------------------------------------------
LJMP Ks_Main1
;-----------------------------------------------------------------------
Disp_Kcode0: DB '0','1','2','3'
Disp_Kcode1: DB '4','5','6','7'
Disp_Kcode2: DB '8','9','A','B'
Disp_Kcode3: DB 'C','D','E','F'
;-----------------------------------------------------------------------
END