Untitled

 avatar
unknown
plain_text
10 months ago
11 kB
7
Indexable
;=============================================== DEFINITIONS ==============================
RS_PIN BIT P2.0
RW_PIN BIT P2.1
E_PIN BIT P2.2
LCD_DATA DATA P0
LED_BUZZER BIT P2.3
KEYPAD DATA P1

ORG 00H ; program starts
JMP BEGIN ; jump to BEGIN
ORG 0BH ; Timer 0 interrupt vector
MOV TH0, #20H ; reset TH0 value
MOV TL0, #080H ; reset TL0 value
DJNZ R0, RETURN_I ; interrupt return if R0 is not zero
MOV R0, #10H ; reset R0 value
JMP ISR ; jump to ISR
RETURN_I: RETI
BEGIN:
MOV TMOD, #01H ;|
MOV TH0, #20H ;|
MOV TL0, #080H ;| Timer setting
MOV IE, #82H ; Interrupt Enable
; initial values/conditions
MAIN: CLR TR0
MOV R0, #10H
MOV R1, #40H
MOV R2, #0
MOV R3, #0
MOV R4, #0
MOV R5, #0
MOV R6, #0
MOV R7, #0
MOV A, #0
MOV DPTR, #0
MOV 40H, #255
MOV 41H, #0
MOV 42H, #0
MOV 43H, #0
MOV 44H, #0
MOV 45H, #0
MOV 46H, #0
MOV 47H, #0
MOV 48H, #0
MOV 49H, #1
SETB LED_BUZZER
CLR F0
ACALL LCD_INITIALIZE ; initialize LCD
ACALL WORD1 ; display WORD1
ACALL LCD_2ND_LINE
ACALL TEMP_DISP

;============================================= INPUT PROCESS ==============================
START:
PROCEED:ACALL KEYSCAN ; scan keypad
JNZ CHECK_NEXT1 ; jump not zero CHECK_NEXT1
JMP START ; jump START
CHECK_NEXT1:
CJNE A, #'*', CHECK_NEXT2 ; check if * is pressed
JMP MAIN ; jump MAIN
CHECK_NEXT2:
CJNE A, #'#', CHECK_NEXT3 ; check if # is pressed
CJNE R5, #0, START_TIMER ; check if there is no input digit
JMP START ; jump START
CHECK_NEXT3:
CJNE R5, #8, VALID_INPUT ; check if there is eight input digit
JMP START ; jump START

VALID_INPUT:
INC R5 ; increase input digit count
INC R1 ; increment R1
MOV @R1, A ; move contents of A into RAM location
MOV A, #87H ; |
ADD A, R5 ; | adjust cursor position
ACALL COMNWRT ; call command routine
MOV A, @R1 ; pass @R1 to accumulator for display
ACALL DATAWRT ; call data write routine
JMP START ; jump START

;============================================== TIMER STARTS ==============================
START_TIMER:
SETB TR0 ; start timer0
ACALL LCD_1ST_LINE ; adjust LCD cursor to line 1
MOV A, #0CH ; display on, cursor off
ACALL COMNWRT ; call command routine
ACALL WORD3 ; display WORD3
; show initial value for counting
MOV A, R5
MOV R4, A
REPEAT1:MOV A, #87H ; |
ADD A, R4 ; | adjust cursor position
ACALL COMNWRT ; call command routine
MOV A, #40H ; |
ADD A, R4 ; |
MOV R1, A ; | adjust R1 value
MOV A, @R1 ; pass @R1 to accumulator for display
ACALL DATAWRT ; call data write routine
DJNZ R4, REPEAT1 ; repeat process to show next digit
JMP BACK2 ; jump BACK2

;======================================== TIMER RUNNING LOOP ==============================
BACK: SETB TR0 ; start timer0
BACK2: JNB F0, RUNNING ; check timer end flag
JMP TIMER_END ; jump TIMER_END
RUNNING: 
PROCEED2:
ACALL KEYSCAN ; scan keypad
CJNE A, #'#', CHECK_NEXT4 ; check if # is pressed
JMP PAUSE ; jump PAUSE
PAUSE: CLR TR0 ; stop timer0
ACALL LCD_1ST_LINE ; LCD cursor to line 1
ACALL WORD4 ; display WORD4
REPEAT2:
PROCEED3:
ACALL KEYSCAN ; scan keypad
CJNE A, #'#', CHECK_NEXT5 ; check if # is pressed
ACALL LCD_1ST_LINE ; LCD cursor to line 1
ACALL WORD3 ; display WORD3
JMP BACK ; jump BACK
CHECK_NEXT5:
CJNE A, #'*', REPEAT2 ; check if * is pressed
JMP MAIN ; jump MAIN
CHECK_NEXT4:
CJNE A, #'*', BACK2 ; check if * is pressed
JMP MAIN ; jump MAIN

;================================================ TIMER ENDS ==============================
TIMER_END:
CLR TR0 ; stop timer0
ACALL LCD_1ST_LINE ; LCD cursor to line 1
ACALL WORD5 ; display WORD5
CLR LED_BUZZER ; activate LED and buzzer output
REPEAT3:
PROCEED4:
ACALL KEYSCAN ; scan keypad
CJNE A, #'*', REPEAT3 ; check if * is pressed
JMP MAIN ; jump MAIN

;============================================= TEMPERATURE RANGE ==============================
TEMP_DISP:
CHECK_P3_7:
	JB P3.7, TEMP_HIGH    ; If P3.7 is high, jump to TEMP_HIGH
	ACALL CHECK_P3_6      ; Otherwise, check P3.6

CHECK_P3_6:
	JB P3.6, TEMP_MOD     ; If P3.6 is high, jump to TEMP_MOD
	ACALL CHECK_P3_5      ; Otherwise, check P3.5

CHECK_P3_5:
	JB P3.5, TEMP_LOW     ; If P3.5 is high, jump to TEMP_LOW
	ACALL CHECK_P3_7      ; Otherwise, check P3.7 again

JMP MAIN                ; Jump back to MAIN if none of the pins are high

TEMP_HIGH:
	ACALL LCD_2ND_LINE
	
	MOV A, #'T'          ; Display "TEMP ABOVE 80"
	ACALL DATAWRT
	MOV A, #'E'
	ACALL DATAWRT
	MOV A, #'M'
	ACALL DATAWRT
	MOV A, #'P'
	ACALL DATAWRT
	MOV A, #' '
	ACALL DATAWRT
	MOV A, #'A'
	ACALL DATAWRT
	MOV A, #'B'
	ACALL DATAWRT
	MOV A, #'O'
	ACALL DATAWRT
	MOV A, #'V'
	ACALL DATAWRT
	MOV A, #'E'
	ACALL DATAWRT
	MOV A, #' '
	ACALL DATAWRT
	MOV A, #'8'
	ACALL DATAWRT
	MOV A, #'0'
	ACALL DATAWRT
	RET
	
TEMP_MOD:
	ACALL LCD_2ND_LINE
	
	MOV A, #'T'          ; Display "TEMP NORMAL"
	ACALL DATAWRT
	MOV A, #'E'
	ACALL DATAWRT
	MOV A, #'M'
	ACALL DATAWRT
	MOV A, #'P'
	ACALL DATAWRT
	MOV A, #' '
	ACALL DATAWRT
	MOV A, #'N'
	ACALL DATAWRT
	MOV A, #'O'
	ACALL DATAWRT
	MOV A, #'R'
	ACALL DATAWRT
	MOV A, #'M'
	ACALL DATAWRT
	MOV A, #'A'
	ACALL DATAWRT
	MOV A, #'L'
	ACALL DATAWRT
	RET
	
TEMP_LOW:
	ACALL LCD_2ND_LINE

	MOV A, #'T'          ; Display "TEMP BELOW 40"
	ACALL DATAWRT
	MOV A, #'E'
	ACALL DATAWRT
	MOV A, #'M'
	ACALL DATAWRT
	MOV A, #'P'
	ACALL DATAWRT
	MOV A, #' '
	ACALL DATAWRT
	MOV A, #'B'
	ACALL DATAWRT
	MOV A, #'E'
	ACALL DATAWRT
	MOV A, #'L'
	ACALL DATAWRT
	MOV A, #'O'
	ACALL DATAWRT
	MOV A, #'W'
	ACALL DATAWRT
	MOV A, #' '
	ACALL DATAWRT
	MOV A, #'4'
	ACALL DATAWRT
	MOV A, #'0'
	ACALL DATAWRT
	RET

;======================================================= ISR ==============================
ISR: MOV A, R5 ; |
MOV R4, A ; | set R4 = R5
REPEAT4:MOV A, #87H ; |
ADD A, R4 ; | adjust cursor position
ACALL COMNWRT ; call command routine
MOV A, #40H ; |
ADD A, R4 ; |
MOV R1, A ; | adjust R1 value to point at current digit value
CJNE @R1, #'0', DECREASE ; check if current digit value is zero
MOV @R1, #'9' ; set current digit value to 9
MOV A, @R1 ; pass @R1 to accumulator for display
ACALL DATAWRT ; call data write routine
CJNE R4, #1, LEFT_SHIFT ; left shift if R4 is not 1
SETB F0 ; raise timer end flag
RETI
LEFT_SHIFT:
DEC R4 ; decrement R4
JMP REPEAT4 ; jump to REPEAT4 subroutine
DECREASE: DEC @R1 ; decrement content at R1 location
MOV A, @R1 ; pass content at R1 location to accumulator
ACALL DATAWRT ; call data write routine
RETI

;================================== DISPLAY WORDS SUBROUTINE ==============================
WORD1:
MOV DPTR, #MYWORD1 ; point DPTR to #MYWORD1
ACALL SHOW_WORD ; call SHOW_WORD
RET
WORD3:
MOV DPTR, #MYWORD3 ; point DPTR to #MYWORD3
ACALL SHOW_WORD ; call SHOW_WORD
RET
WORD4:
MOV DPTR, #MYWORD4 ; point DPTR to #MYWORD4
ACALL SHOW_WORD ; call SHOW_WORD
RET
WORD5:
MOV DPTR, #MYWORD5 ; point DPTR to #MYWORD5
ACALL SHOW_WORD ; call SHOW_WORD
RET
SHOW_WORD:
D1: CLR A ; clear accumulator
MOVC A, @A+DPTR ; pass pointed content to accumulator
JNZ D2 ; check if content is 0 is yes end subroutine
RET
D2: ACALL DATAWRT ; call data write routine
INC DPTR ; increment DPTR
JMP D1 ; jump D1

;============================================ LCD SUBROUTINE ==============================
LCD_INITIALIZE:
MOV A, #38H ; lcd 2 lines, 5x7 matrix
ACALL COMNWRT ; call command routine
MOV A, #0CH ; display on, cursor off
ACALL COMNWRT ; call command routine
MOV A, #3CH ; Activate second line
ACALL COMNWRT ; call command routine
ACALL LCD_CLEAR ; call LCD_CLEAR
RET
LCD_CLEAR:
MOV A, #01H ; clear LCD
ACALL COMNWRT ; call command routine
ACALL DELAY ; give LCD some time
RET
LCD_1ST_LINE:
MOV A, #80H ; cursor at line 1, post.0
ACALL COMNWRT ; call command routine
RET
LCD_2ND_LINE:
MOV A, #0C0H ; cursor at line 2, post.0
ACALL COMNWRT ; call command routine
RET

COMNWRT: ; send command to LCD
MOV LCD_DATA, A ; copy reg A to LCD
CLR RS_PIN ; RS=0 for command
CLR RW_PIN ; R/W=0 for write
SETB E_PIN ; E=1 for high pulse
ACALL DELAY ; give LCD some time
CLR E_PIN ; E=0 for H-to-L pulse
RET

DATAWRT: ; write data to LCD
MOV LCD_DATA, A ; copy reg A to LCD
SETB RS_PIN ; RS=1 for data
CLR RW_PIN ; R/W=0 for write
SETB E_PIN ; E=1 for high pulse
ACALL DELAY ; give LCD some time
CLR E_PIN ; E=0 for H-to-L pulse
RET

;======================================== KEYSCAN SUBROUTINE ==============================
KEYSCAN:
MOV KEYPAD, #00001111B ; |
MOV A, KEYPAD ; |
CJNE A, #00001111B, KEYSCAN ; | check if all key is released
K2:
ACALL DELAY ; |
MOV A, KEYPAD ; |
CJNE A, #00001111B, OVER ; | check if a key is pressed
MOV A, #0 ; A = 0
JMP RETURN2 ; jump RETURN2
RETURN2: RET
OVER:
ACALL DELAY ; | after some time
MOV A, KEYPAD ; |
CJNE A, #00001111B, OVER1 ; | check if the key pressed is still in pressed
JMP K2 ; jump K2
OVER1:
MOV KEYPAD, #11101111B ; |
MOV A, KEYPAD ; |
CJNE A, #11101111B, ROW_0 ; | ; to check if pressed key is from row0
MOV KEYPAD, #11011111B ; |
MOV A, KEYPAD ; |
CJNE A, #11011111B, ROW_1 ; | ; to check if pressed key is from row1
MOV KEYPAD, #10111111B ; |
MOV A, KEYPAD ; |
CJNE A, #10111111B, ROW_2 ; | ; to check if pressed key is from row2
MOV KEYPAD, #01111111B ; |
MOV A, KEYPAD ; |
CJNE A, #01111111B, ROW_3 ; | ; to check if pressed key is from row3
JMP K2

ROW_0:
MOV DPTR, #KCODE0 ; point DPRT to #KCODE0
JMP FIND ; jump FIND
ROW_1:
MOV DPTR, #KCODE1 ; point DPRT to #KCODE1
JMP FIND ; jump FIND
ROW_2:
MOV DPTR, #KCODE2 ; point DPRT to #KCODE2
JMP FIND ; jump FIND
ROW_3:
MOV DPTR, #KCODE3 ; point DPRT to #KCODE3
FIND:
RRC A ; rotate accumulator right through carry
JNC MATCH ; jump MATCH if carry is zero
INC DPTR ; increment DPTR
JMP FIND ; jump FIND
MATCH:
CLR A ; clear accumulator
MOVC A, @A+DPTR ; pass pointed content to accumulator
RET

;===================================================== DELAY ==============================
DELAY: MOV R7, #2 ; R7 = 2
HERE: MOV R6, #255 ; R6 = 255
DJNZ R6, $ ; decreament jump at the same line
DJNZ R7, HERE ; decreament jump to HERE
RET

;============================================== DEFINE BYTES ==============================
MYWORD1: DB "TIMER:", 0 ; TIMER
MYWORD3: DB "RUNNING:", 0 ; RUNNING:
MYWORD4: DB "PAUSE: ", 0 ; PAUSE:
MYWORD5: DB "TIME'S UP ", 0 ; TIME'S UP
KCODE0: DB '1', '2', '3' ; |
KCODE1: DB '4', '5', '6' ; |
KCODE2: DB '7', '8', '9' ; | all keypad available key
KCODE3: DB '*', '0', '#' ; | according to row and column
TCODE: DB '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' ;digit for display temperature
	
;=============================================== END OF CODE ==============================
END
Editor is loading...
Leave a Comment