Searching \ for '[PIC]:16F877 Interupt probs' in subject line. ()
Make payments with PayPal - it's fast, free and secure! Help us get a faster server
FAQ page: www.piclist.com/techref/microchip/devices.htm?key=16F
Search entire site for: '16F877 Interupt probs'.

Exact match. Not showing close matches.
PICList Thread
'[PIC]:16F877 Interupt probs'
2001\04\24@091221 by Graham North

picon face
Hi, thanks to everyone who replied to my last message.

I have an interupt problem. I am trying to use RB0 to detect a change
(positive edge), I then what this interupt to start timer 1 which then gives
me an interupt when it rolls over.

I think I have set everything up correctly. Could someone have a look.

I have run the code, and sometimes I can get the test LED to light and
sometimes not. It seems to work best just after I have downloaded the
program using the ICSP lead. I change the input and the LED lights. I then
power down the board, power it up again and it will not work. If the program
is downloaded again it will (sometimes) work.

Thanks Graham

; ******************** Interrupt Service Routine *********************

       org     0x004                   ; Interrupt vector location
       PUSH                            ; Save registers

RB0_INT_TEST

       bsf     PORTE,1                 ; Used for testing to see if
interupt ocurred.
       btfss   INTCON,INTF             ; Test if external change on RB0
       goto    INT_EXIT                ; Exit ISR

       call    RB0_INT_HANDLER         ; Call routine to deal with interupt

       bcf     INTCON,INTF             ; clear int pin flag

INT_TEST_TIMER1
       BANKSEL PIE1                    ; select SFR bank
       BTFSS   PIE1,TMR1IE             ; test if interrupt is enabled
       GOTO    INT_EXIT                ; no, so exit ISR
       BCF     STATUS,RP0              ; select SFR bank
       BTFSS   PIR1,TMR1IF             ; test if Timer1 rollover occured
       GOTO    INT_EXIT                ; no so exit isr
       BCF     PIR1,TMR1IF             ; clear Timer1 H/W flag
       BANKSEL T1CON                   ; select SFR bank
       MOVLW   b'01101111'
       MOVWF   TMR1L                   ; initialize Timer1 low
       MOVLW   b'00101100'
       MOVWF   TMR1H                   ; initialize Timer1 high
                                       ; Total time = 2.275ms @ 20MHz
;       BSF     T1CON,TMR1ON            ; turn ON Timer1 module
       goto    TIM0_INT_HANDLER        ; Call routine to deal with interupt

       ; **** Test other interupts here!

INT_EXIT
       PULL                            ; Restore registers
       retfie                          ; Return from interrupt

; ****************** End of Interupt Service Routine ******************

; ***********************************************************************
;
;  RB0_INT_HANDLER -
;  Called from inside int service routine.
;

RB0_INT_HANDLER

       BSF     T1CON,TMR1ON             ; turn ON Timer1 module

       RETURN

; ***********************************************************************
;
;  TIM0_INT_HANDLER -
;  Called from inside int service routine.
;

TIM0_INT_HANDLER

       btfsc   PORTE,0
       goto    Turn_off
       bsf     PORTE,0
       goto    Finish

Turn_off

       bcf     PORTE,0

Finish

       RETURN

; ********************* End of Interupt Handlers ***********************

; ************************** Main  Code ********************************

Main

       call    Startup_Init
       call    InitPorts
       call    Init_Timer1

Loop

       call    Read_A2D

       call    Output_A2D_Low_Byte

       goto Loop

; ************************* Subroutines **************************

Init_Timer1

       MOVLW   b'01101111'
       MOVWF   TMR1L                    ; initialize Timer1 low
       MOVLW   b'00101100'
       MOVWF   TMR1H                    ; initialize Timer1 high
                                        ; Total time = 2.275ms @ 20MHz
       return


Read_A2D

; Reads the 16 bit value from the A2D

       bcf     PORTC,Byte
       bcf     PORTC,R_C

Wait_until_busy_low

       btfsc   PORTC,Busy
       goto    Wait_until_busy_low

       bsf     PORTC,R_C

Wait_until_busy_high

       btfss   PORTC,Busy
       goto    Wait_until_busy_high

       movf    PORTD,0
       movwf   A2D_High_Byte

       bsf     PORTC,Byte

       ;***** Wait at least 83 ns
       nop

       movf    PORTD,0
       movwf   A2D_Low_Byte

       return


Output_A2D_Low_Byte

; Outputs one of the 8bit values read from the A2D

       movf    A2D_Low_Byte,0
       movwf   PORTB

       return


Output_A2D_High_Byte

; Outputs one of the 8bit values read from the A2D

       movf    A2D_High_Byte,0
       movwf   PORTB

       return


InitPorts

; INITIALISE PORTS
; binary used to see individual pin level

       movlw b'00000000'       ; all port pins = low
       movwf PORTA
       movlw b'00000000'
       movwf PORTB
       movlw b'00000000'
       movwf PORTC
       movlw b'00000000'
       movwf PORTD
       movlw b'00000000'
       movwf PORTE

       BANK1                   ; Select Bank 1 for TRIS registers

; binary used to see individual pin IO status  MSB -> LSB (0 > OP, 1 > IP)

       movlw b'00000001'       ; Port A Bit 0 = input
       movwf TRISA
       movlw b'11111111'       ; Port B = inputs
       movwf TRISB
       movlw b'01000000'       ; Port C Bit 6 = input
       movwf TRISC
       movlw b'11111111'       ; Port D = inputs
       movwf TRISD
       movlw b'00000000'       ; Port E = outputs
       movwf TRISE

       movlw b'00000110'       ; all analog pins = digital
       movwf ADCON1

       BANK0                   ; Select Bank 0

       return


Startup_Init

; Setting up the Special Function Registers

       movlw   b'11010000'
       movwf   INTCON

       movwf   b'11111111'
       movwf   OPTION_REG

       movlw   b'00000000'     ; Do not start timer 1 yet.
       movwf   T1CON

       movlw   b'00000001'
       movwf   PIE1

       return


Delay

; 1/2 SEC DELAY SUBROUTINE WITH 4MHz CLOCK

       movlw 01h
       movwf NbHi
       movlw 03h
       movwf NbLo
       movlw 8Ah
       movwf NaHi
       movlw 5Bh
       movwf NaLo

DeLoop0 decfsz NaLo,F
       goto DeLoop0
       decfsz NaHi,F
       goto DeLoop0
       decfsz NbLo,F
       goto DeLoop0
       decfsz NbHi,F
       goto DeLoop0
       return


       end


_________________________________________________________________________
Get Your Private, Free E-mail from MSN Hotmail at http://www.hotmail.com.

--
http://www.piclist.com hint: The PICList is archived three different
ways.  See http://www.piclist.com/#archives for details.


2001\04\24@161607 by Drew Vassallo

picon face
>I then
>power down the board, power it up again and it will not work. If the
>program
>is downloaded again it will (sometimes) work.

Sounds like you need to add a brownout circuit to your MCLR*.  Check the
datasheets for an example.  If the 16F877 datasheet doesn't have an example,
the 16F84 datasheet does for sure.

--Andrew
_________________________________________________________________
Get your FREE download of MSN Explorer at http://explorer.msn.com

--
http://www.piclist.com hint: The PICList is archived three different
ways.  See http://www.piclist.com/#archives for details.


2001\04\24@213402 by David Duffy

flavicon
face
Graham North wrote:
>Hi, thanks to everyone who replied to my last message.
>
>I have an interupt problem. I am trying to use RB0 to detect a change
>(positive edge), I then what this interupt to start timer 1 which then gives
>me an interupt when it rolls over.

RB0 interrupt is negative edge triggered.
I haven't looked through your code.
Regards...

--
http://www.piclist.com hint: The PICList is archived three different
ways.  See http://www.piclist.com/#archives for details.


2001\04\24@224523 by Drew Vassallo

picon face
>>Hi, thanks to everyone who replied to my last message.
>>
>>I have an interupt problem. I am trying to use RB0 to detect a change
>>(positive edge), I then what this interupt to start timer 1 which then
>>gives
>>me an interupt when it rolls over.
>
>RB0 interrupt is negative edge triggered.
>I haven't looked through your code.

This is not true!  It can be either, depending on how you have your
OPTION_REG (in Bank 1) bits set.  And since you haven't looked through his
code, how do you know he has it set for a negative edge trigger?

If OPTION_REG, INTEDG (bit 6) is set, the interrupt will occur on the rising
edge of RB0.  If cleared, it will occur on the falling edge of RB0.

I still think your problem is that you don't have a brownout circuit on
MCLR*.  Try that first before you debug any further.  "Random code
operation" or "it works sometimes when I power it off and on" is often due
to the source not coming up fast enough, which will be fixed with the
brownout circuit.

--Andrew
_________________________________________________________________
Get your FREE download of MSN Explorer at http://explorer.msn.com

--
http://www.piclist.com hint: The PICList is archived three different
ways.  See http://www.piclist.com/#archives for details.


2001\04\25@090602 by Olin Lathrop

face picon face
> RB0 interrupt is negative edge triggered.
> I haven't looked through your code.

You can select the RB0 edge with the INTEDG bit in the OPTION register.


********************************************************************
Olin Lathrop, embedded systems consultant in Littleton Massachusetts
(978) 742-9014, spam_OUTolinTakeThisOuTspamembedinc.com, http://www.embedinc.com

--
http://www.piclist.com#nomail Going offline? Don't AutoReply us!
email .....listservKILLspamspam@spam@mitvma.mit.edu with SET PICList DIGEST in the body


2001\04\25@193343 by Tony Nixon

flavicon
picon face
Graham North wrote:
>
> Hi, thanks to everyone who replied to my last message.
>
> I have an interupt problem. I am trying to use RB0 to detect a change
> (positive edge), I then what this interupt to start timer 1 which then gives
> me an interupt when it rolls over.
>
> I think I have set everything up correctly. Could someone have a look.


I assume at ORG 0000h that you have

   goto Main  ; yes, no, maybe ???

If so then this won't work...

Main

   call    Startup_Init


... because some of these registers are in RAM page 1 not 0

Startup_Init

; Setting up the Special Function Registers

       movlw   b'11010000'
       movwf   INTCON

       movwf   b'11111111'
       movwf   OPTION_REG        <<<<<<<<<<

       movlw   b'00000000'     ; Do not start timer 1 yet.
       movwf   T1CON             <<<<<<<<<<

       movlw   b'00000001'
       movwf   PIE1              <<<<<<<<<<

       return


You seem to be using RB0 as a trigger for a function, so unless you
really need RB0INT to stay active ALL the time, I would disable the
RB0INT after it triggers an interrupt.

That way RB0 cannot trigger another IRQ until the Timer1 interrupt
funtion has been completed. When the Timer1 function has completed,
re-enable the RB0INT again. If you are tiggering RB0INT with a push
button switch or similar, then you may get multiple interrupts occurring
for the switch press.


        bcf     INTCON,INTF             ; clear int pin flag

to

        bcf     INTCON,INTE             ; RB0INT disable


When TIMER1 function has completed, don't forget to clear the RB0INT
flag before reenabling the IRQ

        bcf     INTCON,INTF             ; clear int pin flag
        bsf     INTCON,INTE             ; RB0INT enable


Flame me if my methods are wrong here, but...

You are testing the RB0INT flag for the source of the interrupt..

        btfss   INTCON,INTF             ; Test if external change on
RB0

This will occur any time the RB0 pin logic level changes to the state
that is setup in the OPTION_REG, even if INTCON,INTE is disabled.

This may fool you into thinking RB0INT caused the interrupt even though
TIMER1 caused it. Remember that INTE may not be enabled.

I would test to see if INTE is enabled and then test the INTF flag if it
is.


With the minimal code you supplied, you seem to be using a 16F877 with
minimal external I/O connections, make sure all unused inputs are set as
outputs. Failure to do this may cause erratic operation. Most here seem
to be set as inputs.


       movlw b'00000001'       ; Port A Bit 0 = input
       movwf TRISA
       movlw b'11111111'       ; Port B = inputs
       movwf TRISB
       movlw b'01000000'       ; Port C Bit 6 = input
       movwf TRISC
       movlw b'11111111'       ; Port D = inputs
       movwf TRISD
       movlw b'00000000'       ; Port E = outputs
       movwf TRISE

--
Best regards

Tony

mICros
http://www.bubblesoftonline.com
salesspamKILLspampicnpoke.com

--
http://www.piclist.com#nomail Going offline? Don't AutoReply us!
email .....listservKILLspamspam.....mitvma.mit.edu with SET PICList DIGEST in the body


2001\04\25@193601 by David Duffy

flavicon
face
Drew wrote:
>>>Hi, thanks to everyone who replied to my last message.
>>>
>>>I have an interupt problem. I am trying to use RB0 to detect a change
>>>(positive edge), I then what this interupt to start timer 1 which then
>>>gives
>>>me an interupt when it rolls over.
>>
>>RB0 interrupt is negative edge triggered.
>>I haven't looked through your code.
>
>This is not true!  It can be either, depending on how you have your
>OPTION_REG (in Bank 1) bits set.  And since you haven't looked through his
>code, how do you know he has it set for a negative edge trigger?

I stand corrected!  Must have been too early in the day.  :-)

>If OPTION_REG, INTEDG (bit 6) is set, the interrupt will occur on the rising
>edge of RB0.  If cleared, it will occur on the falling edge of RB0.
>I still think your problem is that you don't have a brownout circuit on
>MCLR*.  Try that first before you debug any further.  "Random code
>operation" or "it works sometimes when I power it off and on" is often due
>to the source not coming up fast enough, which will be fixed with the
>brownout circuit.

Sounds like good advice to me.
Regards...

--
http://www.piclist.com#nomail Going offline? Don't AutoReply us!
email EraseMElistservspam_OUTspamTakeThisOuTmitvma.mit.edu with SET PICList DIGEST in the body


More... (looser matching)
- Last day of these posts
- In 2001 , 2002 only
- Today
- New search...