Experiment-9

Examples

Example-1

; Interface the keypad and read the key-codes (HEX) of all keys.
; Connect the keyboard to J2 of the trainer
; Set the trainer in to KEYBOARD MODE
; Configure Port A as Input and Port C as Output

; 8000H
BEGIN:
	MOV DPTR, #E803H 			; ADDRESS OF (J2) CONTROL REG
	; SET ALL PORTS AS INPUTS; PORT_A IN INPUT MODE
	MOV A, #90H 				; CONTROL CODE
	MOVX @DPTR, A 				; SET CONTROL REGISTER WITH THE CODE
	MOV A, #07H 				; TO SEND HIGH ON ALL ROWS
	DEC 82H 					; DEC DPTR
	MOVX @DPTR, A 				; WRITE TO PORT_C
	MOV 82H, #00H 				; GO TO PORT_A

WAIT1:
	MOVX A, @DPTR 				; GET PORT_A INPUT TO ACCUMULATOR
	; CHECK ALL KEYS RELEASED?
	JNZ WAIT1 					; REPEAT UNTILL NON-ZERO INPUT GIVEN
	LCALL DBOUNCE 				; AWAIT DEBOUNCE KEYBOARD

WAIT2:
	MOVX A, @DPTR 				; READ PORT_A FOR COLUMNS
	JZ WAIT2 					; CHECK ANY KEY PRESSED?
	LCALL DBOUNCE 				; AWAIT DEBOUNCE KEYBOARD
	MOV R0, #00H 				; INITIAL KEY CODE
	MOV R1, #03H 				; THE NUMBER OF ROWS
	MOV R2, #80H 				; TO SEND HIGH TO THE ROWS; INITIAL VALUE

NXT_ROW:
	MOV DPTR, #E802H 			; ADDRESS OF PORT_C
	MOV A, R2 					; GET HIGH CODE TO ACCUMULATOR
	RL A 						; ROTATE LEFT TO GO TO THE NEXT ROW
	MOV R2, A 					; SAVE IN (R2)
	MOVX @DPTR, A 				; WRITE IN PORT_C
	MOV DPL, #00H 				; GO TO PORT_A
	MOVX A, @DPTR 				; GET PORT_A INPUT
	JNZ FOUND 					; 
	MOV A, R0 					;
	ADD A, #08H 				;
	MOV R0, A 					;
	DJNZ R1, NXT_ROW 			;
	LJMP BEGIN 					; EXIT AND BEGIN AGAIN

FOUND:
	RRC A
	JC OVER
	INC R0
	SJMP FOUND

OVER:
	MOV 60H, R0 				; DISPLAY PLACEHOLDER
	MOV F0H, #00H 				; NO DOT
	LCALL UPDDT 				; SHOW IN DISPLAY FIELD
	LJMP BEGIN 					; REPEAT ENTIRE PROGRAM AGAIN

DBOUNCE:
	MOV TMOD, #10H 				; TIMER-1 IN MODE_1
	; DELAY OF 20ms
	MOV TH1, #B7H
	MOV TL1, #FFH
	SETB TR1 					; TIMER-1 SET

HERE:
	JNB TF1, HERE 				; WAIT UNTIL TIMER-1 OVERFLOWS
	; RESET TIMER-1
	CLR TF1
	CLR TR1
	RET 						; RETURN BACK TO MAIN LOOP

Exercises

Exercise-1

; Perform mathematical operations: ADD, MULTIPLY and SUBTRACT.
; Connect the keyboard to J2 of the trainer
; Set the trainer in to KEYBOARD MODE
; Configure Port A as Input and Port C as Output

; Replace #HEX_ADD, #HEX_SUB, #HEX_MUL with their corresponding
; key-codes (HEX) for the checks to work

; 8000H
START:
	MOV R5, #00H 				; FLAG, TO KNOW FIRST/SECOND OPERAND

BEGIN:
	MOV DPTR, #E803H 			; ADDRESS OF (J2) CONTROL REG
	; SET ALL PORTS AS INPUTS; PORT_A IN INPUT MODE
	MOV A, #90H 				; CONTROL CODE
	MOVX @DPTR, A 				; SET CONTROL REGISTER WITH THE CODE
	MOV A, #07H 				; TO SEND HIGH ON ALL ROWS
	DEC 82H 					; DEC DPTR
	MOVX @DPTR, A 				; WRITE TO ~PORT_C
	MOV 82H, #00H 				; GO TO PORT_A

WAIT1:
	MOVX A, @DPTR 				; GET PORT_A INPUT TO ACCUMULATOR
	; CHECK ALL KEYS RELEASED?
	JNZ WAIT1 					; REPEAT UNTILL NON-ZERO INPUT GIVEN
	LCALL DBOUNCE 				; AWAIT DEBOUNCE KEYBOARD

WAIT2:
	MOVX A, @DPTR 				; READ PORT_A FOR COLUMNS
	JZ WAIT2 					; CHECK ANY KEY PRESSED?
	LCALL DBOUNCE 				; AWAIT DEBOUNCE KEYBOARD
	MOV R0, #00H 				; INITIAL KEY CODE
	MOV R1, #03H 				; THE NUMBER OF ROWS
	MOV R2, #80H 				; TO SEND HIGH TO THE ROWS; INITIAL VALUE

NXT_ROW:
	MOV DPTR, #E802H 			; ADDRESS OF PORT_C
	MOV A, R2 					; GET HIGH CODE TO ACCUMULATOR
	RL A 						; ROTATE LEFT TO GO TO THE NEXT ROW
	MOV R2, A 					; SAVE IN (R2)
	MOVX @DPTR, A 				; WRITE IN PORT_C
	MOV DPL, #00H 				; GO TO PORT_A
	MOVX A, @DPTR 				; GET PORT_A INPUT
	JNZ FOUND 					;
	MOV A, R0 					;
	ADD A, #08H 				;
	MOV R0, A 					;
	DJNZ R1, NXT_ROW 			;
	LJMP BEGIN 					; EXIT AND BEGIN AGAIN

; DECRPYT ONE-HOT ENCODING
FOUND:
	RRC A
	JC OVER
	INC R0
	SJMP FOUND

OVER:
	MOV 60H, R0 				; DISPLAY PLACEHOLDER
	MOV F0H, #00H 				; NO DOT
	LCALL UPDDT 				; SHOW IN DISPLAY FIELD

; CHECK OPERAND
CHK_OPR:
	CJE R5, #02H, CHK_ADD 		; CHECK IF FIRST & SECOND OPERAND ENTERED?
	; IF SO, THEN PERFORM THE OPERATIONS; ELSE SAVE THE OPERAND

SAVE_OPR:
	CJE R5, #01H, SAVE_SECND 	; CHECK WHETHER TO SAVE FIRST/SECOND OPERAND

SAVE_FIRST:
	MOV R3, R0 					; SAVE FIRST OPERAND IN (R3)
	INC R5 						; INCREMENT FLAG
	LJMP BEGIN					; PROCEED TO GET NEXT INPUT

SAVE_SECND:
	MOV R4, R0 					; SAVE SECOND OPERAND IN (R4)
	INC R5 						; INCREMENT FLAG
	LJMP BEGIN					; PROCEED TO GET NEXT INPUT

CHK_ADD:
	CJNE R0, #HEX_ADD, CHK_SUB 	; CHECK IF ADD? ELSE CHECK SUBTRACT

ADD_NUMS:
	MOV A, R3 					; RETRIEVE FIRST OPERAND
	ADD A, R0					; ADD THE SECOND OPERAND
	LJMP DISPLAY 				; RESULT IN (ACC)

CHK_SUB:
	CJNE R3, #HEX_SUB, CHK_MUL 	; CHECK IF SUBTRACT? ELSE CHECK MULTIPLY

SUB_NUMS:
	MOV A, R3 					; RETRIEVE FIRST OPERAND
	SUBB A, R0					; SUBTRACT SECOND OPERAND FROM FIRST OPERAND
	LJMP DISPLAY 				; RESULT IN (ACC)

CHK_MUL:
	CJNE R3, #HEX_MUL, BEGIN 	; CHECK IF MULTIPLY? ELSE BEGIN

MUL_NUMS:
	MOV F0H, R3 				; RETRIEVE FIRST OPERAND
	MOV A, R0					; RETRIEVE SECOND OPERAND
	MUL AB 						; MULTIPLY
	; FOR SIMPLICITY, ONLY LOWER BYTE (IN ACC) WILL BE DISPLAYED
	; PROCEED FOR DISPLAY

DISPLAY:
	MOV 60H, A 					; DISPLAY PLACEHOLDER
	MOV F0H, #00H 				; NO DOT
	LCALL UPDDT 				; SHOW IN DISPLAY FIELD

	MOV R5, #00H 				; RESET FLAG
	LJMP BEGIN 					; REPEAT ENTIRE PROGRAM AGAIN

DBOUNCE:
	MOV TMOD, #10H 				; TIMER-1 IN MODE_1
	; DELAY OF 20ms
	MOV TH1, #B7H
	MOV TL1, #FFH
	SETB TR1 					; TIMER-1 SET

HERE:
	JNB TF1, HERE 				; WAIT UNTIL TIMER-1 OVERFLOWS
	; RESET TIMER-1
	CLR TF1
	CLR TR1
	RET 						; RETURN BACK TO MAIN LOOP

Last updated