; This program activates the most commonly used interrupts ; of the MCS-51 controller. These are: ; serial interrupt ; timer 0 interrupt ; timer 1 interrupt ; external interrupt 0 ; external interrupt 1 ; This program services the above interrupts. ; the serial routine sends a byte out and receives it back. ;********************************************************** ;* the user must jumper P3.0 and P3.1 together * ;********************************************************** ; the stack is used in the serial interrupt to a depth of 5. $debug $mod51 ea_byte equ 09fh ; all -51 interrupts enabled tmod_val equ 11h ; timer0 in 16-bit mode ; timer1 in 16-bit mode t0_val equ 00h ; timer0 reload, LSB t1_val equ 80h ; timer1 reload, LSB t_val equ 0ffh ; timer MSB end_it equ 0ffh ; inc a up till this value delay equ 0ffh ; base for delay time ; w/12 MHz clock, routine works ; at delay=14h, not 0ah scon_val equ 098h ; 9 bit uart, ninth bit = 1 ; rcv enabled pcon_val equ 000h ; $80, 1/32*(clock), 19.2 kbaud ; $00, 1/64*(clock), 9600 baud stk_ptr equ 31h ; stack begins immediately ; after 2 data bytes at 30h,31h low_val equ 01h ; low byte of timer 0 reload hi_val equ 58h ; hi byte of timer 0 reload dseg org 30h ; scratchpad RAM wait: ds 1 rcv_data: ds 1 ; cseg org 0h initz: jmp start org 3h int_0: jnb p3.2,$ ; wait till int0 goes high inc r0 ; use r0 to count # of int0's reti org 0bh t0_int: clr tr0 ; stop timer0 jmp t0_work org 13h int_1: jnb p3.3,$ ; wait till int1 goes high inc r1 ; use r1 to count # of int0's reti org 1bh t1_int: clr tr1 ; stop timer1 jmp t1_work org 23h s_int: ljmp ser_int org 60h start: mov sp,#stk_ptr ; set the stack pointer mov scon,#scon_val mov pcon,#pcon_val mov ie,#ea_byte mov tmod,#tmod_val mov tl0,#t0_val mov th0,#t_val mov tl1,#t1_val mov th1,#t_val mov r0,#00h mov r1,#00h setb p3.0 ; alternate func. is RXD setb p3.1 ; alternate func. is TXD mov dpl,#00h clr ti clr ri setb it0 ; int0 is edge sensitive setb it1 ; int1 is edge sensitive setb tr0 ; start timer0 setb tr1 ; start timer1 xmit: mov sbuf,dpl ; dpl inits to 0 set_wait: mov wait,#delay ; dead time: adjust this ; to tighten noose ; loop2: nop djnz wait,loop2 jmp xmit ; ser_int: push acc push dpl push dph push wait push rcv_data ; mov a,dpl ; manipulate data by acc mov rcv_data,sbuf ; read the rcv'd byte cjne a,rcv_data,bombout ; if different, bomb clr ri ; clear the rcv interrupt clr ti ; clear xmt interrupt too inc a ; then inc a ; exit condition is commented out for this version ; cjne a,end_it,popm ; and compare to $ff ; go to top if not done ; jmp the_end ; go to the end if done popm: pop rcv_data pop wait pop dph pop dpl mov dpl,a ; xmit byte will inc'd pop acc reti bombout: jmp $ ; screwed up the_end: jmp $ ; ok t0_work: mov tl0,#t0_val mov th0,#t_val setb tr0 ; start timer0 again reti t1_work: mov tl1,#t1_val mov th1,#t_val setb tr1 ; start timer1 again reti end