; SIMPLE MULTITASKING PROGRAM $MOD51 $NOPRINT $INCLUDE(MYPAULM2.EQU) LED equ P1.7 CR EQU 13 GPIO2 equ 200H ; 8-bit input port DSEG AT 20H FLAG1: DS 1 TICK: DS 1 SEC: DS 1 MIN: DS 1 HOUR: DS 1 TIMER1: DS 1 TIMER2: DS 1 TIMER3: DS 1 TIMER4: DS 1 COMMAND: DS 1 CSEG AT 8000H jmp main ORG 8100H ; 10ms tick ; ____|____|____|____|____ ; WAIT_TICK: JNB TF0,$ CLR TF0 ORL TH0,#0DCH INC TICK RET UPDATE_CLOCK: MOV A,TICK CJNE A,#100,EXIT_CLOCK MOV TICK,#0 SETB FLAG1.0 ; flag that signals print time function SETB FLAG1.1 ; for tick led SETB FLAG1.2 ; signals print lcd function MOV A,SEC ADD A,#1 DA A MOV SEC,A CJNE A,#60H,EXIT_CLOCK MOV SEC,#0 MOV A,MIN ADD A,#1 DA A MOV MIN,A CJNE A,#60H,EXIT_CLOCK MOV MIN,#0 MOV A,HOUR ADD A,#1 DA A MOV HOUR,A CJNE A,#24H,EXIT_CLOCK MOV HOUR,#0 EXIT_CLOCK: RET ; MAKE LED ON EVERY ONE SECOND ; ------______------------------------------______----------------- ; |50ms| ; |-------------------- 1000ms -------| ; TICK_LED: JNB FLAG1.1,EXIT1 CLR LED INC TIMER1 MOV A,TIMER1 CJNE A,#5,EXIT1 SETB LED CLR FLAG1.1 MOV TIMER1,#0 EXIT1: RET ; check serial port every 10ms ; exit: COMMAND == -1 NO CHARACTER ; COMMAND != -1 ASCII CODE GETCHAR: JNB RI,EXIT2 CLR RI MOV A,SBUF MOV COMMAND,A RET EXIT2: MOV COMMAND,#-1 RET ; PRINT TIME TO TERMINAL EVERY SECOND PRINT_TIME: JNB FLAG1.0,EXIT_PRINT_TIME CLR FLAG1.0 PRINT_TIME1: MOV A,#CR CALL COUT MOV A,HOUR CALL PHEX MOV A,#':' CALL COUT MOV A,MIN CALL PHEX MOV A,#':' CALL COUT MOV A,SEC CALL PHEX EXIT_PRINT_TIME: RET HOUR_KEY: MOV A,COMMAND CJNE A,#'h',EXIT_HOUR_KEY MOV A,HOUR ADD A,#1 DA A MOV HOUR,A CJNE A,#24H,SKIP_CLEAR_HOUR MOV HOUR,#0 SKIP_CLEAR_HOUR: CALL PRINT_TIME1 EXIT_HOUR_KEY: RET MIN_KEY: MOV A,COMMAND CJNE A,#'m',EXIT_MIN_KEY MOV A,MIN ADD A,#1 DA A MOV MIN,A CJNE A,#60H,SKIP_CLEAR_MIN MOV MIN,#0 SKIP_CLEAR_MIN: CALL PRINT_TIME1 EXIT_MIN_KEY: RET ; PRINT BYTE TO LCD ; INPUT BYTE MUST BE TWO DIGITS BCD NUMBER PRINT_BYTE: PUSH ACC ANL A,#0F0H SWAP A ADD A,#'0' CALL PUTCH_LCD POP ACC ANL A,#0FH ADD A,#'0' CALL PUTCH_LCD RET PRINT_TIME_LCD: JNB FLAG1.2, EXIT_PRINT_LCD CLR FLAG1.2 PRINT_TIME_LCD1: MOV A,#00H ; A = X MOV B,#00H ; B = Y CALL goto_xy MOV A,HOUR CALL PRINT_BYTE MOV A,#':' CALL PUTCH_LCD MOV A,MIN CALL PRINT_BYTE MOV A,#':' CALL PUTCH_LCD MOV A,SEC CALL PRINT_BYTE EXIT_PRINT_LCD: RET READ_KEY: MOV DPTR,#GPIO2 MOVX A,@DPTR JB ACC.4, CHECK_NEXT_KEY MOV A,#1 RET CHECK_NEXT_KEY: JB ACC.5, EXIT_CHECK_KEY MOV A,#2 RET EXIT_CHECK_KEY: MOV A,#-1 RET EXE_KEY: CALL READ_KEY CJNE A,#1,EXE_KEY2 MOV A,HOUR ADD A,#1 DA A MOV HOUR,A CJNE A,#24H,SKIP_CLEAR_HOUR1 MOV HOUR,#0 SKIP_CLEAR_HOUR1: CALL PRINT_TIME_LCD1 EXIT_HOUR_KEY1: RET EXE_KEY2: CJNE A,#2,EXIT_KEY2 MOV A,MIN ADD A,#1 DA A MOV MIN,A CJNE A,#60H,SKIP_CLEAR_MIN1 MOV MIN,#0 SKIP_CLEAR_MIN1: CALL PRINT_TIME_LCD1 EXIT_KEY2: RET SCAN_KEY: INC TIMER2 MOV A,TIMER2 CJNE A,#20,EXIT_SCAN ; 200ms MOV TIMER2,#0 CALL EXE_KEY EXIT_SCAN: RET ;*************************** MAIN *************************** main: ORL TMOD,#1 SETB TR0 MOV SEC,#0 MOV MIN,#55H MOV HOUR,#17H MOV TICK,#0 CALL NEWLINE CALL INITLCD ; main 10ms loop LOOP: CALL WAIT_TICK ; following tasks will be executed every 10ms CALL TICK_LED CALL UPDATE_CLOCK CALL GETCHAR CALL PRINT_TIME CALL HOUR_KEY CALL MIN_KEY CALL PRINT_TIME_LCD CALL SCAN_KEY JMP LOOP $include(lcddrv.asm) END