You are on page 1of 6

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

You might also like