Interrupt Problem


Closed Thread
Results 1 to 16 of 16
  1. #1
    Join Date
    Nov 2005
    Location
    Perth, Australia
    Posts
    429

    Default Interrupt Problem

    I've set up a very basic program to experiment with interrupts on a 16F84 (ive basically just used the example interrupt code from the pbp manual)

    This main program should loop forever until RB0/INT goes high (via a pushbutton), and the interrupt routine should trigger and turn on the LED, and then go back to the endless loop in the main program.

    However, when I press the button, the LED comes on for about 2 seconds and then turns off again. So i checked to see if it was resetting by putting code at the beginning of the program that makes the LED flash on and off a few times.

    Sure enough, when i pressed the button, the LED came on for 2 seconds and then flashed, so the program was reset for some reason. It even resets if i pull out the oscillator after pressing the button. Now this seems to point me towards thinking that the watchdog timer is going off, but i dont know why it would.

    Code:
    DEFINE  OSC     10              ' Oscillator = 10MHz
    define  INTHAND int_handler     ' Define interrupt handler
    
    INTEDG  VAR OPTION_REG.6        ' RB0 Interrupt edge select: 1=Rising Edge 0=Falling Edge
    INTF    VAR INTCON.1            ' RB0 Interrupt flag
    INTE    VAR INTCON.4            ' RB0 Interrupt enable
    GIE     VAR INTCON.7            ' Global interrup enable
    
    LED     var PORTB.1             ' LED on RB1
    
    wsave   var byte $20 system     ' Variable for saving W Register on Interrupt
    ssave   var byte bank0 system   ' Variable for saving STATUS Register on Interrupt
    psave   var byte bank0 system   ' Variable for saving PCLATH Register on Interrupt
    fsave   var byte bank0 system   ' Variable for saving FSR Register on Interrupt
    
    HIGH LED                        ' Flash LED Twice
    pause 50
    low led
    pause 50
    high led
    pause 50
    low led
    
    INTEDG=1                        ' RB0 Interrupt to Trigger on Rising Edge
    INTF=0                          ' Enable RB0 Interrupt
    INTE=1                          ' Enable RB0 Interrupt
    GIE=1                           ' Global Interrupt Enable
    
    loop: Goto loop                 ' Endless Loop
    
    
    '-----------------------------------------------------------------------------'
    ' Interrupt Handler                                                           '
    '-----------------------------------------------------------------------------'
    
    asm
    int_handler
        ; Save Resisters ;
        movwf   wsave               ; Save W Register into wsave
        swapf   STATUS,W            ; Save STATUS Register into ssave
        clrf    STATUS                  
        movwf   ssave              
        movf    PCLATH,W            ; Save PCLATH Register into psave
        movwf   psave
        movf    FSR,W               ; Save FSR Register into fsave
        movwf   fsave
    
        ; Interrupt Code ;
        bsf     _LED                ; Turn on LED
    
        ; Restore Resisters ;
        movf    fsave,W             ; Restore FSR Resister
        movwf   FSR                 
        movf    psave,W             ; Restore PCLATH Resister
        movwf   PCLATH
        swapf   ssave,W             ; Restore STATUS Resister
        movwf   STATUS
        swapf   wsave,F             ; Restore W Resister
        swapf   wsave,W
        retfie
    endasm

  2. #2
    Join Date
    Jul 2003
    Location
    Sweden
    Posts
    237


    Did you find this post helpful? Yes | No

    Lightbulb

    If my memory serves me right i think that the line .......
    loop: Goto loop ' Endless Loop
    ...... will not kick the watchdog. You probably need to insert atleast one statement between the label and the goto.

    /Ingvar

  3. #3
    Join Date
    Nov 2005
    Location
    Perth, Australia
    Posts
    429


    Did you find this post helpful? Yes | No

    Default

    Tried that... Didnt help im afraid...

    It looks like its not even making it out of the interrupt routine, and just locking up and resetting at some point after it turns on the led.

  4. #4
    J_Brittian's Avatar
    J_Brittian Guest


    Did you find this post helpful? Yes | No

    Default

    I think Ingvar's right. I'm not sure you're leaving any room for an interrupt to occur. Try it like this:

    loop:
    For y = 0 to 100
    pause 1
    Next y
    Goto loop

  5. #5
    Join Date
    Nov 2005
    Location
    Perth, Australia
    Posts
    429


    Did you find this post helpful? Yes | No

    Default

    well the interrupt is def occuring or the led wouldnt come on at all. an interrupt handled in assembly doesnt need "room" for it to occur. It will jump right to the interrupt handler no matter what the processor is doing at the time... but ill try what you suggest

    *edit* just tried it and no change... when i press the button attached to the interrupt pin the led goes high for 2 secs and then the whole thing crashes and restarts
    Last edited by Kamikaze47; - 16th November 2005 at 15:32.

  6. #6
    J_Brittian's Avatar
    J_Brittian Guest


    Did you find this post helpful? Yes | No

    Default

    I'm sorry. I just realized that. Do you reset you're interrupt flag somewhere? Should there be an Intf = 0 just before the retfie?

  7. #7
    Join Date
    Oct 2004
    Location
    Zagreb, Croatia
    Posts
    27


    Did you find this post helpful? Yes | No

    Smile

    first off all you forgot to clear int flag
    in your int handler so your PIC will always
    be in interrupt routine. you have to put line
    Code:
    bcf INTCON,1
    before retfie instruction.
    also I suggest you to turn on and off
    LED in int routine with little delay
    in between (although it is not adviceable to use
    delays in interrupt)
    to see the interrupt more clearly. you can
    use this int handler for example:

    Code:
    asm
    int_handler
        ; Save Resisters ;
        movwf   wsave               ; Save W Register into wsave
        swapf   STATUS,W            ; Save STATUS Register into ssave
        clrf    STATUS                  
        movwf   ssave              
        movf    PCLATH,W            ; Save PCLATH Register into psave
        movwf   psave
        movf    FSR,W               ; Save FSR Register into fsave
        movwf   fsave
    endasm
        high LED
        pause 100
        low LED
        ; Interrupt Code ;
        ;bsf     _LED                ; Turn on LED
    asm
        ; Restore Resisters ;
        movf    fsave,W             ; Restore FSR Resister
        movwf   FSR                 
        movf    psave,W             ; Restore PCLATH Resister
        movwf   PCLATH
        swapf   ssave,W             ; Restore STATUS Resister
        movwf   STATUS
        swapf   wsave,F             ; Restore W Resister
        swapf   wsave,W
        bcf INTCON,1
        retfie
    endasm

  8. #8
    Join Date
    Nov 2005
    Location
    Perth, Australia
    Posts
    429


    Did you find this post helpful? Yes | No

    Default

    I would have thought the interrupt flag would be reset automatically when it returns from the interrupt handler. I havnt seen interrupt routines that reset the flag, but I guess its worth a try.

  9. #9
    Join Date
    Nov 2005
    Location
    Perth, Australia
    Posts
    429


    Did you find this post helpful? Yes | No

    Default

    Ahh yep, that did the trick. Thanks Ingvar.

    Just a single line at the end of the interrupt handler: bcf _INTF

  10. #10
    Join Date
    Nov 2005
    Location
    Perth, Australia
    Posts
    429


    Did you find this post helpful? Yes | No

    Default

    Tom: is there any down side of including picbasic commands in your interrupt handler. I thought to work as a proper interrupt it had to be in asm?

  11. #11
    Join Date
    Oct 2004
    Location
    Zagreb, Croatia
    Posts
    27


    Did you find this post helpful? Yes | No

    Smile

    You always have to clear interrupt flag in software
    before retfie instruction. If you don't clear the flag,
    instruction retfie will set GIE bit and PIC will be
    interrupted again. Logical AND function beetwen
    int flag bit and int enabled bit (AND-ed with GIE)
    will result in interrupt.

  12. #12
    Join Date
    Oct 2004
    Location
    Zagreb, Croatia
    Posts
    27


    Did you find this post helpful? Yes | No

    Default

    kamikaze 47:
    well, of course it's better to use asm in my opinion
    but this also work. I try it.

  13. #13
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959


    Did you find this post helpful? Yes | No

    Default

    Kamikaze47 is right.

    There is definately a problem using PAUSE in an ASM interrupt.

    Pause uses 2 internal PBP variables. (R0 and R1). So if, another PBP statement that uses either R0 or R1 gets interrupted, the interrupt routine will change those values and the main program will get confused.

    It's possible to have a pause in the interrupt, IF you save both of the system vars first, then restore them when the int is finished.

    In that case, toms example would look like this...
    Code:
    R0save VAR WORD
    R1save VAR WORD
    
    asm
    int_handler
        ; Save Resisters ;
        IF (CODE_SIZE <= 2)
            movwf   wsave               ; Save W Register into wsave
            swapf   STATUS,W            ; Save STATUS Register into ssave
            clrf    STATUS                  
            movwf   ssave              
            movf    PCLATH,W            ; Save PCLATH Register into psave
            movwf   psave
            movf    FSR,W               ; Save FSR Register into fsave
            movwf   fsave
        endif
    endasm
        R0save = R0
        R1save = R1
        high LED
        pause 100
        low LED
        R1 = R1save
        R0 = R0save
    asm
        ; Restore Resisters ;
        movf    fsave,W             ; Restore FSR Resister
        movwf   FSR                 
        movf    psave,W             ; Restore PCLATH Resister
        movwf   PCLATH
        swapf   ssave,W             ; Restore STATUS Resister
        movwf   STATUS
        swapf   wsave,F             ; Restore W Resister
        swapf   wsave,W
        bcf INTCON,1
        retfie
    endasm
    But then, like tom says ... "it is not advisable to use delays in interrupt"
    <br>
    Last edited by Darrel Taylor; - 16th November 2005 at 18:48.
    DT

  14. #14
    Join Date
    Nov 2005
    Location
    Perth, Australia
    Posts
    429


    Did you find this post helpful? Yes | No

    Default

    Thanks for that info Darrel.

    Is there a reference somewhere that tells you what (if any) internal variables PBP uses for each command?

  15. #15
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959


    Did you find this post helpful? Yes | No

    Default

    No, unfortunately.

    Depending on how and where certain statements are used in the program, the actual system variables used might change. So there's really no way to make a "List".

    You pretty much have to sift thru the .LST file to find out which vars are used. That includes following every CALL to other routines too. It can take a while.

    PAUSE was easy though, it's pretty small, and only has 1 CALL.

    Of course, you can take the easy route and just save them all to be sure. But then we're back to OXIMBIT's routine again.
    <br>
    DT

  16. #16
    Join Date
    Mar 2005
    Location
    Iowa, USA
    Posts
    216


    Did you find this post helpful? Yes | No

    Talking A little more info

    Kamikaze47 -
    There's a little info about this HERE from Darrel. Look at post #9 on down. I guess it's out there if you have the time to dig through the files and look for them.
    Wisdom is knowing what path to take next... Integrity is taking it.
    Ryan Miller

Similar Threads

  1. problem using GOSUB under interrupt
    By fobya71 in forum mel PIC BASIC Pro
    Replies: 10
    Last Post: - 5th March 2010, 19:52
  2. Problem with Interrupt on PIC18F4620 PORTB
    By rookie in forum Off Topic
    Replies: 1
    Last Post: - 22nd March 2007, 01:34
  3. Problem with PBP interrupt and Serin, please help
    By rgregor in forum mel PIC BASIC
    Replies: 0
    Last Post: - 22nd August 2006, 19:02
  4. Interrupt stack overflow problem with Resume {label}
    By Yuantu Huang in forum mel PIC BASIC Pro
    Replies: 0
    Last Post: - 3rd May 2005, 01:17
  5. USART interrupt not interrupting right
    By Morpheus in forum mel PIC BASIC Pro
    Replies: 12
    Last Post: - 6th March 2005, 01:07

Members who have read this thread : 1

You do not have permission to view the list of names.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts