Untitled
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