Hi all,
I'm a newbie to 8051 programming. I program in assembly language on a ATMEL 80c51 with a crystal frequency of 18.432 MHz.
I use timer1 for generating baud rate. Timer1 interrupt is not used. I use external interrupt 0 for communicating with 2 other peripherals.
Timer 0 interrupt is used to check if port pin 1.4 is low or high. and a corresponding message is displayed .
Interrupt 0 has high priority than the timer. the moment I enter into Interrupt Service routine, I stop the timer, clr the timer0 overflow flag and the timer 0 interrupt. After completing the job intended, just before exiting the routine I switch on the TImer0 and set the overflow and timer interrup flags.
The program works only when one of the interrupts are enabled in the code. When both Timer0 and Interrupt0 are set, the program hangs......
Especially after external interrupt0 is activated. what happens is , that timer interrupt doesn't detect the status of pin1.4 and displays the message...but interrupt0 gets activated every time interrupt0 occurs.
I have attached the code below. I think its some kind of a clash between the two interrupts. I would like to have pointers in this regard.
TIA. Regards Gayathri
The code :
;--------------When the program resets it jumps to main label-----------------
org 2000h ; start of main program after reset ljmp main ; goto label "main"
;---------------definition of interrupts--------------------------------------
org 0003h ; int0 vector address ljmp mainint reti
org 000bh ; timer0 interrupt ljmp on_off reti
org 0013h ; int1 vector address reti
org 001bh ; timer1 interrupt reti
org 0023h ; ri & ti reti
;------------------------------Byte Storage
---------------------------------- rub_all: db '{C0816 |{C1916 |{C3216 |' rg: db '$BM',0DH
low: db '{C2800 LOW|' high: db '{C2800 HIGH|'
;-----------------------------code segmenting-----------------------------------
cseg at 0100h ; Code starts from location 0100h
;---------------------------------Main------------------------------------------
main: mov SP,#18h ; Stack pointer initialised to 18h clr A ; Clear accumulator setb IT0 ; Interrupt 0 edge sensitive mov IP,#01h clr RS0 ; Select Register Bank 2 setb RS1 CLR TR0 CLR TF0 setb EA ; Enable all Interrupt CLR EX1 setb EX0 ; Set External interrupt 0(main) clr ET1 ; Clear external timer interrupt setb ES ; Enable serial interrupt
mov r1,#2Eh ; Number of characters in rub_all (46D= 2Eh) mov r0,#40h ; Starting location mov dptr, #rub_all ; Ruball is the label for 'db' lcall receiver ; Fill the db into RAM
lcall sio_init ; serial and timer1 initialization LCALL SIO_TIME ; timer0 initialization
infinite: sjmp infinite
;---------------------------TIMER 0 INTERRUPT SERVICE ROUTINE
------------------on_off: CLR EA clr ri clr ti LCALL SIO_INIT jb p1.4,ok ; if pin is high then go to ok mov r1,#0Bh mov dptr, #low ; displaying'{C2800 LOW|' lcall sender_b ; send to the serial port and display message through device2 sjmp done
ok: mov r1,#0Ch ; character counter mov dptr, #high ; '{C2800 HIGH|' lcall sender_b ; send to the serial port
done: LCALL SIO_TIME SETB EA reti
;------------- end of timer 0 interrupt------------------------------------------
mainint: mainloop: CLR EA push acc push psw push dpl push dph push 10h push 11h push 12h push 13h push 14h push 15h push 16h push 17h push b
lcall sio_init
;;;;; code for communicating with DEVICE1 --- get response from device one( through serial communication)
;;;;code for communication with device2 - for displaying the response.
pop b pop 17h pop 16h pop 15h pop 14h pop 13h pop 12h pop 11h pop 10h pop dph pop dpl pop psw pop acc POP 0A8H
LCALL SIO_TIME SETB EA reti ;--------------------subroutine for "ch_s"
-----------------------------------
ch_s: ; subrutine for transmitting data clr ti ; clear transmit interrupt clr a movc a,@a+dptr ; move the first character mov sbuf,a gon: jnb ti,gon ; wait until transmit interrupt is set inc dptr ; to get next data ret ; ret from subroutine
;--------------------Subroutine for "ch_r"
----------------------------------
ch_r: ; subroutine for receiving data from serial port gch: jnb ri,gch ; wait until receive interrupt is set mov @r1,sbuf ; mov sbuf data to address pointed by r1 mov r3,sbuf cjne r3,#2Eh,ter mov a,#06h ter: inc r1 ; to store next data inc a ; decrement character counter clr ri ; clear receive interrupt ret ; ret from subroutine
;______________________________________________________________________________
;--------------------subroutine for "ch_send"
--------------------------------
ch_send: ; subrutine for transmitting data on serial port clr ti ; clear transmit interrupt mov sbuf,@r0 ; move the first character gone: jnb ti,gone ; wait until transmit interrupt is set ret ; ret from subroutine
;--------------------subroutine for "sender"
--------------------------------
sender_b: setb p1.2 ; select Device2 for communication using a DEMUX clr p1.3 lcall sio_init
send_see: lcall ch_s ; call sub for character transmission djnz r1, send_see ; repeat if counter is not = 0 ret
;--------------------subroutine for "receiver"
-------------------------------- receiver: ; for sending program memory to RAM
send_re: clr a movc a,@a+dptr ; move the first character pointed by DPTR mov @r0,a inc dptr inc r0 djnz r1, send_re ; repeat if counter is not = 0 ret ;------------------------------------------sub routine -SIO init---------------- sio_init: CLR TR0 CLR TF0 CLR ET0 mov tmod,#20h ; select timer1 mov TH1,#0f6h ; reload value for 9600 baud rate =f6 mov scon,#50h ; init.serial control reg. & select mode 1 mov 87h,#80h ; pcon register-to multiply baud rate by 2 setb tr1 ; start timer1 clr ti clr ri ret
SIO_TIME: CLR TR0 CLR TF0 CLR ET0 mov tmod,#21h ; select timer1 AND TIMER 0 mov th0,#00h mov tl0,#00h SETB ET0 setb TR0 RET
;-----------------End of program
--------------------------------------------
;end program end