;================================================================= ; LP4052 SFR equates ;================================================================= ; Byte Registers P1 equ 90h ; Port 1 P1M0x equ 0C2h ; P1M1x equ 0C3h ; P3 equ 0B0h ; Port 3 P3M0x equ 0C6h ; P3M1x equ 0C7h ; PSW equ 0D0h ; Program Status Word ACC equ 0E0h ; Accumulator B equ 0F0h ; B Register SP equ 81h ; DPL equ 82h ; Data Pointer Low DPH equ 83h ; Data Pointer High TCON equ 88h ; TMOD equ 89h ; TL0 equ 8Ah ; TL1 equ 8Bh ; TH0 equ 8Ch ; TH1 equ 8Dh ; TCONB equ 91h ; RL0 equ 92h ; RL1 equ 93h ; RH0 equ 94h ; RH1 equ 95h ; WDTRST equ 0A6h ; WDTCON equ 0A7h ; SCON equ 98h ; SBUF equ 99h ; SADEN equ 0B9h ; SADDR equ 0A9h ; IE equ 0A8h ; Interrupt Enable IP equ 0B8h ; Interrupt Priority IPH equ 0B7h ; PCON equ 87h ; SPSR equ 0AAh ; SPCR equ 0D5h ; SPDR equ 85h ; ACSR equ 97 ; ; Bit Definitions ; P1 SPI SCK equ P1.7 MISO equ P1.6 MOSI equ P1.5 SSB equ P1.4 ; P3 T1 equ P3.5 T0 equ P3.4 INT1 equ P3.3 INT0 equ P3.2 TXD equ P3.1 RXD equ P3.0 ; PSW CY equ PSW.7 ; Carry Flag AC equ PSW.6 ; Auxiliary Carry Flag F0 equ PSW.5 ; User Flag 0 RS1 equ PSW.4 ; Register Bank Select 1 RS0 equ PSW.3 ; Register Bank Select 0 OV equ PSW.2 ; Overflow Flag UD equ PSW.1 ; P equ PSW.0 ; Accumulator Parity Flag ; TCON TF1 equ TCON.7 ; Timer 1 Overflow Flag TR1 equ TCON.6 ; Timer 1 On/Off Control TF0 equ TCON.5 ; Timer 0 Overflow Flag R0 equ TCON.4 ; Timer 0 On/Off Control EX1E equ TCON.3 ; Ext. Interrupt 1 Edge Flag EX1T equ TCON.2 ; Ext. Interrupt 1 Type EX0E equ TCON.1 ; Ext. Interrupt 0 Edge Flag EX0T equ TCON.0 ; Ext. Interrupt 0 Type ; SCON SM0 equ SCON.7 FE equ SCON.7 SM1 equ SCON.6 SM2 equ SCON.5 REN equ SCON.4 TB8 equ SCON.3 RB8 equ SCON.2 TI equ SCON.1 RI equ SCON.0 ; Interrupt Enable A equ IE.7; Global Interrupt Enable C equ IE.6; S equ IE.4; T1IE equ IE.3; Timer 1 Interrupt Enable X1 equ IE.2; External Interrupt 1 Enable T0IE equ IE.1; Timer 0 Interrupt Enable X0 equ IE.0; External Interrupt 0 Enable ; Interrupt Priority PC equ IP.6; PS equ IP.4; PT1 equ IP.3; Timer 1 Priority PX1 equ IP.2; External Interrupt 1 Priority PT0 equ IP.1; Timer 0 Priority PX0 equ IP.0; External Interrupt 0 Priority ;================================================================= ; Other equates ;================================================================= stack equ 2Fh ;begin stack after last bit memory location in internal RAM task equ 2Eh speed equ 2Dh reloadh equ 2Ch reloadl equ 2Bh task1reg equ 27h task2reg equ 28h task3reg equ 29h task4reg equ 2Ah tl_base equ 50h tl_count equ 04h button1 equ P3.2 button2 equ P3.3 outpin1 equ P1.0 outpin2 equ P1.1 outpin3 equ P1.2 outpin4 equ P1.3 outpin5 equ P1.4 outpin6 equ P1.5 outpin7 equ P1.6 outpin8 equ P1.7 ;================================================================= ; 16 bit hex delays based on 20MHz RC Oscillator (1 clk / cycle) ;================================================================= t0high equ 0B1h ; 1.0 msec t0low equ 0E0h ;================================================================= ; lpc9107 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 0033h ; Analog Comparator interrupt vector ajmp init org 0080h init: ;programme LP4052 P1 pins for output and P3 for input mov P1M0x, #00000000b mov P1M1x, #11111111b mov P3M0x, #11111111b mov P3M1x, #00000000b mov ie, #00000000b ;turn off all interrupts mov sp, #stack ;select register bank 0 and push the registers that will be used clr psw.3 clr psw.4 ;initialise task list with task1 active ;record 1 (for task at address 02D0 hex) ;task present and run flags mov 50h, #00000011b ; bit0 (TP = 1), bit1 (run = 1) mov 51h, #2Ch ; set count low mov 52h, #01h ; set count high mov 53h, #0D0h ; set address low mov 54h, #02h ; set address high ;record 2 (for task at address 0320 hex) ;task present and run flags mov 55h, #00000000b ; bit0 (TP = 0), bit1 (run = 0) mov 56h, #2Ch ; set count low mov 57h, #01h ; set count high mov 58h, #20h ; set address low mov 59h, #03h ; set address high ;record 3 (for task at address 0380 hex) ;task present and run flags mov 5Ah, #00000000b ; bit0 (TP = 0), bit1 (run = 0) mov 5Bh, #2Ch ; set count low mov 5Ch, #01h ; set count high mov 5Dh, #80h ; set address low mov 5Eh, #03h ; set address high ;record 4 (for task at address 03D0 hex) ;task present and run flags mov 5Fh, #00000000b ; bit0 (TP = 0), bit1 (run = 0) mov 60h, #2Ch ; set count low mov 61h, #01h ; set count high mov 62h, #0D0h ; set address low mov 63h, #03h ; set address high mov task, #01h ; stores the value of the current task mov speed, #03h ; stores the current task update speed mov reloadh, #01h ; set reload high mov reloadl, #2Ch ; set reload low mov task1reg, #11111110b ;chaser bit pattern for task1 mov task2reg, #00000000b ;chaser bit pattern for task2 mov task3reg, #11111110b ;chaser bit pattern for task3 mov task4reg, #10000100b ;chaser bit pattern for task4 ;load task list address pointer into R0 mov R0, #tl_base ;load R4 with record count mov R4, #tl_count lcall init_t0 ;start T0 - this interrupts once every 1msec main: jnb button1, b1process ;check to see if button 1 is pressed jnb button2, b2process ;check to see if button 2 is pressed ljmp dispatch ;skip to dispatch if no buttons pressed b1process: jnb button1, $ ;wait for button release lcall delay mov a, task cjne a, #01h, task2sel inc task mov 50h, #00000000b mov 55h, #00000011b ;enable task2 mov 56h, reloadl ; set reload low mov 57h, reloadh ; set reload high ljmp finish1 task2sel: cjne a, #02h, task3sel inc task mov 55h, #00000000b mov 5Ah, #00000011b ;enable task3 mov 5Bh, reloadl ; set reload low mov 5Ch, reloadh ; set reload high ljmp finish1 task3sel: cjne a, #03h, task4sel inc task mov 5Ah, #00000000b mov 5Fh, #00000011b ;enable task4 mov 60h, reloadl ; set reload low mov 61h, reloadh ; set reload high ljmp finish1 task4sel: cjne a, #04h, finish1 mov task, #01h mov 5Fh, #00000000b mov 50h, #00000011b ;enable task1 mov 51h, reloadl ; set reload low mov 52h, reloadh ; set reload high finish1: ljmp dispatch b2process: jnb button2, $ ;wait for button release lcall delay mov a, speed cjne a, #01h, speed2 inc speed ;set new speed to '2' and adjust reload mov reloadl, #0F4h ;set reload low mov reloadh, #01h ;set reload high ljmp dispatch speed2: cjne a, #02h, speed3 inc speed ;set new speed to '3' and adjust reload mov reloadl, #2Ch ;set reload low mov reloadh, #01h ;set reload high ljmp dispatch speed3: cjne a, #03h, speed4 inc speed ;set new speed to '4' and adjust reload mov reloadl, #0C8h ;set reload low mov reloadh, #00h ;set reload high ljmp dispatch speed4: cjne a, #04h, speed5 inc speed ;set new speed to '5' and adjust reload mov reloadl, #64h ;set reload low mov reloadh, #00h ;set reload high ljmp dispatch speed5: cjne a, #05h, speed6 inc speed ;set new speed to '6' and adjust reload mov reloadl, #32h ;set reload low mov reloadh, #00h ;set reload high ljmp dispatch speed6: cjne a, #06h, speed7 inc speed ;set new speed to '6' and adjust reload mov reloadl, #19h ;set reload low mov reloadh, #00h ;set reload high ljmp dispatch speed7: cjne a, #07h, dispatch mov speed, #01h ;set new speed to '1' and adjust reload mov reloadl, #0EEh ;set reload low mov reloadh, #02h ;set reload high 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, #03h mov R1, a mov a, @R1 ;get address value low mov DPL, a ;store it temporarily in DPL mov a, R0 add a, #04h 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 ;move R0 pointer to next record next_rec1: mov a, R0 add a, #05h mov R0, a djnz R4, rec_loop1 ljmp main ;==================================================== ; timer init - assumes 20MHz Crystal Oscillator (1 msec) ;==================================================== 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 ;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 dec @R1 ;decrement count low cjne @R1, #0FFh, next_rec2 inc R1 ;set R1 to point to count high 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 inc a mov R1, a mov @R1, reloadl ;reset count low inc R1 mov @R1, reloadh ;reset count high ;move R0 pointer to next record next_rec2: mov a, R0 add a, #05h 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 ;==================================================== ;==================================================== ; move contents of accumulator to outputs ;==================================================== from_acc: rlc a mov outpin8, c rlc a mov outpin7, c rlc a mov outpin6, c rlc a mov outpin5, c rlc a mov outpin4, c rlc a mov outpin3, c rlc a mov outpin2, c rlc a mov outpin1, c ret ;==================================================== ;==================================================== ; delay ;==================================================== delay: mov r3, #0Ah wait_1: mov r4, #0ffh ;reg2 and reg3 wait_2: djnz r4, wait_2 djnz r3, wait_1 ret ;==================================================== ;==================================================== ; task 1 ;==================================================== org 02D0h task1: ;run task 1 mov a, task1reg rl a mov task1reg, a lcall from_acc ljmp ret_point ;==================================================== ;==================================================== ; task 2 ;==================================================== org 0300h t2table: db 01111110b db 10111101b db 11011011b db 11100111b db 11011011b db 10111101b db 11011011b db 11100111b db 11011011b db 10111101b org 0320h task2: ;run task 2 push dpl push dph mov dptr, #t2table mov a, task2reg cjne a, #0Ah, t2skip1 mov a, #00h mov task2reg, a ljmp t2skip2 t2skip1: inc task2reg t2skip2: movc a, @a+dptr pop dph pop dpl lcall from_acc ljmp ret_point ;==================================================== ;==================================================== ; task 3 ;==================================================== org 0360h t3table: db 11111110b db 11111100b db 11111000b db 11110000b db 11100000b db 11000000b db 10000000b db 00000000b db 00000001b db 00000011b db 00000111b db 00001111b db 00011111b db 00111111b db 01111111b db 11111111b org 0380h task3: ;run task 3 push dpl push dph mov dptr, #t3table mov a, task3reg cjne a, #10h, t3skip1 mov a, #00h mov task3reg, a ljmp t3skip2 t3skip1: inc task3reg t3skip2: movc a, @a+dptr pop dph pop dpl lcall from_acc ljmp ret_point ;==================================================== ;==================================================== ; task 4 ;==================================================== org 03D0h task4: ;run task 4 mov a, task4reg jnz rand8b cpl a mov task4reg, a rand8b: anl a, #10111000b mov c, p mov a, task4reg rlc a mov task4reg, a lcall from_acc ljmp ret_point ;==================================================== failsafe_return: ljmp 0 ;==================================================== ;end of test ;==================================================== END