;================================================================= ; 4052 equates ;================================================================= stack equ 2fh ;begin stack after last bit memory location in internal RAM tl_base equ 50h tl_count equ 04h outpin1 equ P3.2 outpin2 equ P3.3 outpin3 equ P3.4 outpin4 equ P3.5 outpin5 equ P3.7 rl0 equ 92h rh0 equ 94h P1M0x equ 0C2h P1M1x equ 0C3h P3M0x equ 0C6h P3M1x equ 0C7h ;================================================================= ; 4052 hardware vectors ;================================================================= org 0000h ; power up and reset vector ajmp init org 0003h ; interrupt 0 vector ajmp init org 000Bh ; timer 0 interrupt vector ajmp time_isr org 0013h ; interrupt 1 vector ajmp init org 001Bh ; timer 1 interrupt vector ajmp init org 0023h ; serial port interrupt vector ajmp init org 0060h init: ;programme all 89lP4052 pins for output mov P1M0x, #00000000b mov P1M1x, #11111111b mov P3M0x, #00000000b mov P3M1x, #11111111b mov ie, #00000000b ;turn off all interrupts mov sp, #stack mov a, #0FFh mov P1, a mov P3, a ;select register bank 0 and push the registers that will be used clr psw.3 clr psw.4 ;init task list ;record 1 (for task at address 0300 hex) ;task present and run flags mov 50h, #00000001b ; bit0 (TP = 1), bit1 (run = 0) mov 51h, #00h ; set count low mov 52h, #00h ; set count high mov 53h, #00h ; set offset low mov 54h, #00h ; set offset high mov 55h, #01h ; set reload low mov 56h, #00h ; set reload high mov 57h, #00h ; set address low mov 58h, #03h ; set address high ;record 2 (for task at address 0600 hex) ;task present and run flags mov 59h, #00000001b ; bit0 (TP = 1), bit1 (run = 0) mov 5Ah, #00h ; set count low mov 5Bh, #00h ; set count high mov 5Ch, #00h ; set offset low mov 5Dh, #00h ; set offset high mov 5Eh, #02h ; set reload low mov 5Fh, #00h ; set reload high mov 60h, #00h ; set address low mov 61h, #06h ; set address high ;record 3 (for task at address 0900 hex) ;task present and run flags mov 62h, #00000001b ; bit0 (TP = 1), bit1 (run = 0) mov 63h, #00h ; set count low mov 64h, #00h ; set count high mov 65h, #00h ; set offset low mov 66h, #00h ; set offset high mov 67h, #03h ; set reload low mov 68h, #00h ; set reload high mov 69h, #00h ; set address low mov 6Ah, #09h ; set address high ;record 4 (for task at address 0C00 hex) ;task present and run flags mov 6Bh, #00000001b ; bit0 (TP = 1), bit1 (run = 0) mov 6Ch, #00h ; set count low mov 6Dh, #00h ; set count high mov 6Eh, #00h ; set offset low mov 6Fh, #00h ; set offset high mov 70h, #04h ; set reload low mov 71h, #00h ; set reload high mov 72h, #00h ; set address low mov 73h, #0Ch ; set address high ;load initial count for all present records; this is the offset value ;load task list address pointer into R0 mov R0, #tl_base ;load R4 with record count mov R4, #tl_count rec_loop0: ;test the TP flag mov a, @R0 jnb acc.0, next_rec0 mov a, R0 add a, #03h mov R1, a mov a, @R1 ;get offset value low mov R5, a ;store it temporarily in R5 mov a, R0 add a, #01h mov R1, a mov a, R5 mov @R1, a ;write offset low to initialize count low mov a, R0 add a, #04h mov R1, a mov a, @R1 ;get offset value high mov R5, a ;store it temporarily in R5 mov a, R0 add a, #02h mov R1, a mov a, R5 mov @R1, a ;write offset high to initialize count high ;move R0 pointer to next record next_rec0: mov a, R0 add a, #09h mov R0, a djnz R4, rec_loop0 ;repeat until all records are checked lcall init_t0 dispatch: ;load task list address pointer into R0 mov R0, #tl_base ;load R4 with record count mov R4, #tl_count ;check the run status of tasks that are present and ;if set clear the run flag and call the task rec_loop1: ;test the Run flag mov a, @R0 jnb acc.1, next_rec1 ;as task is ready to run, clear the run flag and call the task routine clr acc.1 mov @R0, a mov a, R0 add a, #07h mov R1, a mov a, @R1 ;get address value low mov DPL, a ;store it temporarily in DPL mov a, R0 add a, #08h mov R1, a mov a, @R1 ;get address value high mov DPH, a ;store it temporarily in DPH ;start by saving registers that may be used in the task push 0 push 1 push 2 push 3 push 4 push 5 push 6 push 7 push acc push psw ;jump to task code here clr a jmp @a+dptr ret_point: ;return from task code here and restore the registers pop psw pop acc pop 7 pop 6 pop 5 pop 4 pop 3 pop 2 pop 1 pop 0 ;after running the task, if reload value is zero then clear the task present flag mov a, R0 add a, #05h mov R1, a mov a, @R1 ;get reload value low cjne a, #00h, next_rec1 mov a, R0 add a, #06h mov R1, a mov a, @R1 ;get reload value high cjne a, #00h, next_rec1 ;as both low and high reload values are zero, we need to switch off this task mov a, @R0 clr acc.0 mov @R0, a ;move R0 pointer to next record next_rec1: mov a, R0 add a, #09h mov R0, a djnz R4, rec_loop1 ljmp dispatch ;==================================================== ; timer init ;==================================================== init_t0: ;reload value is -200000 decimal (B1 E0 Hex) ;for a 20MHz crystal this gives an overflow every 1 ms mov rh0, #0B1h ;init reload count (high) mov rl0, #0E0h ;init reload count (low) mov tmod, #00000001b ;sets T0 for mode 1 (16bit auto) mov tcon, #00010000b ;start running T0 mov ie, #10000010b ;turn on T0 interrupt ret ;==================================================== ;==================================================== ; timer ISR ;==================================================== time_isr: ;hardware automatically clears TF0 and reloads TL0/TH0 ;start by saving registers that will be used in ISR push psw push acc ;select register bank 0 and push the registers that will be used clr psw.3 clr psw.4 push 0 push 1 push 2 push 3 push 4 push 5 ;debug toggle cpl outpin5 ;for each record where task is present, decrement count and check if zero ;if zero load reload value into count and set run flag ;load task list address pointer into R0 mov R0, #tl_base ;load R4 with record count mov R4, #tl_count rec_loop2: ;test the TP flag mov a, @R0 jnb acc.0, next_rec2 ;assuming TP=1 then we need to decrement the count and possibly set the run flag mov a, R0 inc a mov R1, a ;set R1 to point to count low mov R2, a ;keep a copy of count low pointer in R2 dec @R1 ;decrement count low cjne @R1, #0FFh, next_rec2 inc R1 ;set R1 to point to count high mov a, R1 mov R3, a ;keep a copy of count high pointer in R3 dec @R1 ;as count low has wrapped around to 255 we need to subtract 1 from count high cjne @R1, #0FFh, next_rec2 ;as count high and count low have both wrapped around, then it is time to set run flag and ;reset the count mov a, @R0 setb acc.1 mov @R0, a mov a, R0 add a, #05h mov R1, a mov a, @R1 ;get reload value low mov R5, a ;store it temporarily in R5 mov a, R2 mov R1, a ;update R1 to R2 value (pointing to count low) mov a, R5 ;bring back reload vaue from R5 mov @R1, a ;reset count low mov a, R0 add a, #06h mov R1, a mov a, @R1 ;get reload value high mov R5, a ;store it temporarily in R5 mov a, R3 mov R1, a ;update R1 to R3 value (pointing to count low) mov a, R5 ;bring back reload vaue from R5 mov @R1, a ;reset count high ;move R0 pointer to next record next_rec2: mov a, R0 add a, #09h mov R0, a djnz R4, rec_loop2 ;restore registers to their original value pop 5 pop 4 pop 3 pop 2 pop 1 pop 0 pop acc pop psw reti ;==================================================== ;==================================================== ; task 1 ;==================================================== org 0300h task1: ;start task 1 ;insert task code here cpl outpin1 ljmp ret_point ;==================================================== ;==================================================== ; task 2 ;==================================================== org 0600h task2: ;start task 2 ;insert task code here cpl outpin2 ljmp ret_point ;==================================================== ;==================================================== ; task 3 ;==================================================== org 0900h task3: ;start task 3 ;insert task code here cpl outpin3 ljmp ret_point ;==================================================== ;==================================================== ; task 4 ;==================================================== org 0C00h task4: ;start task 4 ;insert task code here cpl outpin4 ljmp ret_point ;==================================================== failsafe_return: ljmp 0 ;==================================================== ;end of test ;==================================================== END