Interrupt usage


+ Reply to Thread
Results 1 to 10 of 10

Thread: Interrupt usage

  1. #1
    Join Date
    Jan 2006
    Location
    New Hampshire, USA
    Posts
    107

    Default Interrupt usage

    I am a neophyte and don't understand why my code is not working. The statement: on interrupt goto wait is said to be bad syntax but I don't believe it, something else is wrong. My program:
    REM device = 12F675
    CMCON = 7 ' SETS DIGITAL MODE
    ANSEL = 0 ' GPIO.0 TO GPIO.3 SET AS DIGITAL
    OPTION_REG = 0 ' WEAK PULLUPS ENABLED
    TRISIO = %00000100 ' GPIO.2 SET AS INPUT
    IOC = %00000100 ' INTERRUPT ENABLED ON GPIO.2
    INTCON = %10010000 ' INTERRUPT ENABLED
    N VAR BYTE ' VARIABLE N DEFINED
    ' ************************************************** ***********
    START:
    ON INTERRUPT GOTO WAIT
    HIGH GPIO.0
    FOR N=1 TO 13
    NAP 6
    NEXT N
    LOW GPIO.0

    WAIT:
    DISABLE INTERRUPT
    SLEEP
    ON INTERRUPT GOTO START
    ENABLE INTERRUPT 'do i need to clear the interrupt bit first?
    END

  2. #2
    Join Date
    Sep 2004
    Location
    montreal, canada
    Posts
    6,898

    Default

    i see quite a few mistake here
    1. there's no Goto Start after your LED blink
    2. Disable INTERRUPT is not placed at the right place
    3. you can't have more than 1 ON INTERRUPT GOTO
    4. the first ON INTERRUPT is not a the right place
    5. not sure about the NAP loop... to me PAUSEUS would be a better option
    6. not sure about SLEEP in the ISR
    7. yes you MUST clear INT flag
    8. There's no RESUME at the end of your ISR
    9. WAIT is a reserved word and can't be used for labels

    but the rest is OK

    Something like bellow should work
    Code:
        @ __CONFIG _INTRC_OSC_NOCLKOUT & _WDT_ON & _PWRTE_ON & _MCLRE_OFF & _BODEN_ON
    
        CMCON = 7               ' SETS DIGITAL MODE
        ANSEL = 0               ' GPIO.0 TO GPIO.3 SET AS DIGITAL
    
        OPTION_REG = 0          ' WEAK PULLUPS ENABLED
                                ' GP2/INT on falling edge
                                
        TRISIO = %00000100      ' GPIO.2 SET AS INPUT
    
        GPIO = 0
    
        N VAR BYTE              ' VARIABLE N DEFINED
        
        ON INTERRUPT GOTO WAIT_int    
        INTCON = %10010000      ' INTERRUPT ENABLED
    
      '  *************************************************************
    START:
                TOGGLE GPIO.0
                FOR N=0 TO 250
                    pauseus 1000
                    NEXT
                GOTO START
                         
    DISABLE        
    WAIT_INT:
                TOGGLE GPIO.1
                INTCON.1=0      ' Clear GP2/INT flag
                RESUME
                ENABLE
                
                END
    Last edited by mister_e; - 9th April 2008 at 04:10.
    Steve

    It's not a bug, it's a random feature.
    There's no problem, only learning opportunities.

  3. #3
    Join Date
    Jan 2006
    Location
    New Hampshire, USA
    Posts
    107

    Default

    Thanks for the info. Since I can't have more than one interrupt goto, I will have to re-think my program. I would like to have the program wake from sleep on interrupt. Could I use "on interruupt goto start"? I want it to end up in sleep mode, do I need a resume statement?
    My program is:
    Turn LED on
    Wait 15 minutes
    Turn LED off
    Go to sleep
    Optionally, I would like to turn the LED off in less than 15 minutes, using the interrupt; but that does not seem possible. I guess I will have to have two buttons: a start (interrupt) button and stop (goto sleep) button.
    This program compiles OK, what do you think?


    REM device = 12F675
    CMCON = 7 ' SETS DIGITAL MODE
    ANSEL = 0 ' GPIO.0 TO GPIO.3 SET AS DIGITAL
    OPTION_REG = 0 ' WEAK PULLUPS ENABLED
    TRISIO = %00001100 ' GPIO.2 AND GPIO.3 SET AS INPUT
    IOC = %00000100 ' INTERRUPT ENABLED ON GPIO.2
    N VAR WORD ' VARIABLE N DEFINED
    ON INTERRUPT GOTO START
    INTCON = %10010000 ' INTERRUPT ENABLED
    ' ************************************************** ***********
    START:

    HIGH GPIO.0
    FOR N=1 TO 900
    IF GPIO.3=0 THEN SLEEPNOW
    PAUSE 1000
    NEXT N
    SLEEPNOW:
    LOW GPIO.0
    SLEEP 65535 ' DOES IT EVENTUALLY WAKE UP? (I DON'T WANT IT TO)

    END

  4. #4
    Join Date
    Sep 2004
    Location
    montreal, canada
    Posts
    6,898

    Default

    What else the pic will need to do? There's some case you don't even need any ON INTERRUPT.

    @ SLEEP will send the PIC in sleep mode untill there's a interrupt type who can wake up the PIC. It should be listed in your datasheet, somewhere at the end.
    Steve

    It's not a bug, it's a random feature.
    There's no problem, only learning opportunities.

  5. #5

    Default I'm an 'On Interrupt Goto' newbee too

    My understanding is, that although there are many sources of interrupts possible within the PIC's hardware, there is only one resulting interrupt condition. Either the processor has been interrupted or it has not. This leads me to believe that this interrupt condition has to be dealt with by a single interrupt handling routine which tells the interrupted processor what to do.

    The interrupt routine, or interrupt handler, in its execution could, of course, determine the source of the interrupt by investigating the various interrupt flags and take specific action appropriate to the source, but there is only one routine and the point in the program (the label) where it is located is stated in the 'ON INTERRUPT GOTO' statement. Having more than one 'ON INTERRUPT GOTO', each with a different label, doesn't make sense to me, as that would mean that the interrupted processor could go to more than one routine to resolve the interrupt. How would it know which to go to ?

    The flexibility allowed by MELabs by not predetermining the label in the command just means that you can call your interrupt handler what you like. It doesn't mean that there can be more than one and that they are differentiated by having different labels.

    OK.. now to the question! The 'ON INTERRUPT' statement reference on MELabs PIC BASIC Pro support website, clearly states before giving the syntax example, that "More than one ON INTERRUPT may be used in a program"... Is this a typo or have I got it completely wrong?

    Brian Walsh

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

    Default

    Hi Brian,

    It's NOT a typo. You can use all available interrupts simultaneously.

    On any interrupt, the program flow will be directed to the single interrupt handler. Then it's up to you to determine which one fired.

    Each interrupt source has 2 bit's associated with it. An Enable bit (*IE), and an Interrupt Flag (*IF). You need to look in the datasheet to find where those bit's are.

    Then in the interrupt handler, check BOTH the enable bit and the interrupt flag to determine if a particular interrupt has triggered.

    For example, to have the RB Port change and Timer1 interrupts, it might look something like this...
    Code:
    RBIE    VAR INTCON.3
    RBIF    VAR INTCON.0
    TMR1IE  VAR PIE1.0
    TMR1IF  VAR PIR1.0
    TMR1ON  VAR T1CON.0
    
    OldBits VAR BYTE
    NewBits VAR BYTE
    
    
    OldBits = PORTB   ; End the mismatch
    RBIF = 0          ; clear the flag
    RBIE = 1          ; enable PORTB change interrupts
    
    TMR1IF = 0        ; clear TMR1 interrupt flag
    TMR1IE = 1        ; enable Timer1 interrupts
    TMR1ON = 1        ; Start the Timer
    
    ON INTERRUPT GOTO INTHandler
    
    Main:
        PAUSEUS 20
    GOTO Main
    
    DISABLE
    INTHandler:
        IF RBIE and RBIF THEN
            NewBits = PORTB  ; end the mismatch
            RBIF = 0         ; clear the flag
            ; handle RB port change interrupt here
            OldBits = NewBits
        ENDIF
    
        IF TMR1IE and TMR1IF THEN
            TMR1IF = 0       ; clear the flag
            ; handle Timer1 interrupt here
        ENDIF
    RESUME
    ENABLE
    hth,
    DT

  7. #7

    Default Single interrupt handler

    Darrel,

    Thanks for the prompt response. There seems to be some confusion and perhaps I did not make myself clear.

    I think I understand that all enabled interrupts are available at any time to cause the processor to go to the interrupt handler.

    My point was that there can only be ONE interrupt handler (the single interrupt handler referred to in your reply) and that that single interrupt handler is referenced by a unique instance of the 'ON INTERRUPT GOTO' statement within the program.

    Can you provide a sample of code showing the viable use of multiple 'ON INTERRUPT GOTO' statements? Your support of MELabs documentation which states that more than one 'ON INTERRUPT' is permissable in a program suggests that you can.

    My understanding is that the purpose of 'ON INTERRUPT GOTO' is to direct program execution to a unique label when an interrupt, from whatever source, occurs (or rather is detected - in the case of compiler interrupt handling) and to deal with it.

    Having the possibilty of more than one 'ON INTERRUPT GOTO' in a program with the same label would be redundant and having two or more with different labels would suggest the possibilty of multiple interrupt handlers with no way of steering program execution to the right one.

    So, again, as PBP only supports a single global interrupt handler, why does the documentation state that more than one compiler level interrupt re-direction statement is allowed?

    The question is - can more than one 'ON INTERRUPT GOTO' exist in a PBP program in a viable way and if so how can you use them differentially?

    Regards,

    Brian Walsh.

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

    Default

    Oh, I see what you're saying. But it's still not a typo.

    You can have multiple ON INTERRUPT statements, but it gets a little tricky.
    This will be hard to explain, so give me a little time.
    <br>
    DT

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

    Default Multiple ON INTERRUPT GOTO's

    This example should show how you can use multiple ON INTERRUPTS.
    But it's not much use for anything else.

    The key thing to remember here, is that the assignments of the Interrupt Handlers only happens at Compile-Time. Attempting to execute an ON INTERRUPT statement at Run-Time to change the handler will not work.

    As the program gets compiled, starting from the top, the interrupts are considered DISABLED, and no interrupt checks will be placed between the PBP lines of code.

    When it encounters an ON INTERRUPT statement, the status changes to ENABLED, and in between every PBP statement, it will place an Interrupt Check, that jumps to the last assigned Handler.

    In the example below, if an interrupt occurs while the program flow is within the Main loop, then the Handler0 will be jumped to.

    Then when it encounters the second ON INTERRUPT statement, all lines following that assignment will interrupt to Handler1.

    It does not matter if they are subroutines, main routines, or whatever, ANY lines following an ON INTERRUPT will jump to the last known handler (if interrupted).

    It really does get tricky, because then each handler must be capable of handling any interrupt, which leads to multiple copies of the same handler or gosubs to common handlers. Or you have to make sure that before switching modes, ONLY the interrupts that the next mode can handle are enabled, I mean SERIOUSLY Tricky!

    Just remember, It all happens at Compile-Time.

    Code:
    Mode   VAR BYTE
    Mode = 0
    
    ON INTERRUPT GOTO Handler0
    
    Main:
        R0 = R0 ; just some stuff to put int checks between
        R1 = R1
        IF Mode = 1 then DoMode1
        IF Mode = 2 then DoMode2
    GOTO Main
    
    DISABLE
    Handler0:
        ; Interrupt handler for the Main Loop
    RESUME
    ENABLE
    
    ;--------------------------------------------------------
    ON INTERRUPT GOTO Handler1
    
    DoMode1:
        ; Do Mode 1 tasks here
        
        IF Mode = 0 then Main
        IF Mode = 2 then DoMode2
    GOTO DoMode1
    
    DISABLE
    Handler1:
        ; Interrupt handler for Mode 1
    RESUME
    ENABLE
    
    ;--------------------------------------------------------
    ON INTERRUPT GOTO Handler2
    
    DoMode2:
        ; Do Mode 2 tasks here
        
        IF Mode = 0 then Main
        IF Mode = 1 then DoMode1
    GOTO DoMode2
    
    DISABLE
    Handler2:
        ; Interrupt handler for Mode 2
    RESUME
    ENABLE
    hth,
    DT

  10. #10

    Default Multiple ON INTERRUPT GOTOs

    Thanks Darrel. That's quite an explanation!

    Regards,

    Brian Walsh.

Similar Threads

  1. Won't go back to SLEEP after 1st Interrupt
    By jellis00 in forum mel PIC BASIC Pro
    Replies: 32
    Last Post: - 29th June 2009, 09:00
  2. Can't ID interrupt source with this IntHandler??
    By jellis00 in forum mel PIC BASIC Pro
    Replies: 7
    Last Post: - 3rd June 2009, 02:35
  3. Help with Analog Interrupt
    By brid0030 in forum mel PIC BASIC Pro
    Replies: 7
    Last Post: - 13th February 2008, 19:14
  4. NEWBIE: Some basic questions using interrupts
    By JackPollack in forum mel PIC BASIC Pro
    Replies: 5
    Last Post: - 8th March 2006, 03:59
  5. USART interrupt not interrupting right
    By Morpheus in forum mel PIC BASIC Pro
    Replies: 12
    Last Post: - 6th March 2005, 02:07

Posting Permissions

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