8051 timer and external interrupt problem???

Do you have a question? Post it now! No Registration Necessary

Translate This Thread From English to

Threaded View
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

Re: 8051 timer and external interrupt problem???
Instead of doing the serial comms inside an interrupt just set a flag
which can be actioned in the main loop.

Try putting the code for timer 1 int in the main loop to see if serial
comms works ok.

Also there is an extra pop in int0 isr - Im not sure why this is in
there ?




On 11 Aug 2003 05:24:18 -0700, snipped-for-privacy@yahoo.com (pooja) wrote:

Quoted text here. Click to load it


Re: 8051 timer and external interrupt problem???
Thanx Paul and Gary..

I set two flags in the interrupt service routines and actioned them in
the main loop. Now I do not use the timer interrupt at all. Instead
I'm trying to do call the on_off routine in the main loop by default.

the program sequence:
main:
1.initialise: Ex0,Ex1,SP,EARegister bank etc.
2.in an infinite loop ( check for the flags that my be set by the ISRs
and service the routines. then also perform on_off routine then jmp
back to inifinite loop).
            


The program works well only if this on_off routine is excluded from
the main program.

On the other hand, if the flags --- ( set by interrupt Service
routines) are not actioned..( if that code is removed) then this
on_off routine works fine when included in the main program..

I mean... the on_off routine and the flag servicing routines seem to
be mutually exclusive...

Please let me know why the program hangs... What am I missing??
Thanks in advance

Gayathri


Quoted text here. Click to load it
>;---------------------------------Main------------------------------------------
Quoted text here. Click to load it
>;______________________________________________________________________________
Quoted text here. Click to load it

Re: 8051 timer and external interrupt problem???
Have you tried turning interrups off before checking the flags, then
on again after you have checked them?

You may be incountering the set while checking problem....

On 19 Aug 2003 05:42:54 -0700, snipped-for-privacy@yahoo.com (pooja) wrote:


Quoted text here. Click to load it
>;---------------------------------Main------------------------------------------
Quoted text here. Click to load it
>;______________________________________________________________________________
Quoted text here. Click to load it


Re: 8051 timer and external interrupt problem???
Hi,...

why do i have to turn the interrupts off..???


This is what I'm doing:
                flag1 bit 01h
                flag2 bit 02h

                org  2000h         ; start of main program after reset
                ljmp main          ; goto label "main"

                org  0003h        ; int0 vector address
                setb flag1
                reti

                org  0013h        ; int1 vector address
                setb flag2
                reti
;------------------------------Byte
Storage----------------------------------
rub_all:       db      '{C0816       |{C1916         |{C3216        |'
rg:            db      '$BM',0DH
low:           db      '{C2800 LOW|'
high:          db      '{C2800 HIGH|'

                cseg at 0100h     ; Code starts from location 0100h

;---------------------------------Main------------------------------------------
main:
                mov      SP,#55h  ;
                clr      A        ; Clear accumulator    
                setb     IT0      ; Interrupt 0 edge sensitive
                setb     IT1
                clr      RS0      ; Select Register Bank 2
                setb     RS1
                setb     EA       ; Enable all Interrupt
                CLR      EX1
                setb     EX0      ; Set External interrupt 0(main)
                clr      ET1      ; Clear external timer interrupt
                clr      ES       ; Enable serial interrupt
                clr      flag1
                clr      flag2
                clr      ri
                clr      ti

                mov r1,#2Eh       ; Number of characters in rub_all
(46D= 2Eh)
                mov r0,#25h       ; 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

infinite:      

        lcall on_off

                jnb flag1,n1
                lcall mainint
        
n1:             jnb flag2,n2
                lcall continue

n2:        
               sjmp infinite

****************************************************************

within mainint I communicate with a device say DEVICE1
within continue I communicate with yet another device say device2

on_off routine displays a message everytime program enters into
"infinite:" loop.

I face the following problem. on_off and maintint,continue seem to be
mutually exclusive. If "lcall on_off " is removed the program works
fine.
lcall on_off works fine when the flags 1 and 2 are not checked.

Please let me know what  might be the cause???? What am i missing ???

TIA
Gayathri










Quoted text here. Click to load it
>;---------------------------------Main------------------------------------------
Quoted text here. Click to load it
>;______________________________________________________________________________
Quoted text here. Click to load it

Re: 8051 timer and external interrupt problem???
As you say, there must be something you are doing in on_off and (mainint,
continue) that are interfering with each other. You'll have to look at the code
from those to see why this is. Your interrupt routines are nice and short and
shouldn't be a problem.

Re: 8051 timer and external interrupt problem???
Hi Gary,...

When I simulate the code on a keil simulator, it works very fine...
but when on the actual 89C51, the progtam hangs.....
The program misbehaves on my development kit also....

please let me know what might cause these kinds of problems?????

Regards
Gayathri





snipped-for-privacy@aol.com (Gary Kato) wrote in message
Quoted text here. Click to load it

Re: 8051 timer and external interrupt problem???
A simulator is just that. It can help you develop your code, but it's not
perfect. You can only simulate what the I/O pins see. I don't know if the Keil
simulator can simulate things like noise on the I/O lines or not.

Re: 8051 timer and external interrupt problem???
Quoted text here. Click to load it

No. You can't. AFAIK nothing does that sort of thing.

/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
\/\/\/\/\ Chris Hills  Staffs  England    /\/\/\/\/\
/\/\/ snipped-for-privacy@phaedsys.org       www.phaedsys.org \/\/
\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/

Re: 8051 timer and external interrupt problem???
Quoted text here. Click to load it

I seem to remember a setting in some simulator that could inject random noise
into I/O stream. Can't remember what simulator that was though.

Re: 8051 timer and external interrupt problem???
Quoted text here. Click to load it

ROFL!

Re: GROUND noise

Quoted text here. Click to load it

One of our products included a welder controlled by the
embedded computer - we had to have the
computer position the welder, then shut down, let the
welder fire, then reboot the computer! It is very hard
to isolate power supply from spikes on the ground! - RM


Site Timeline