Multiple Interrupts using TMR0 and Interrupt On Change (IOCB) simultaneously


+ Reply to Thread
Results 1 to 6 of 6
  1. #1
    Join Date
    Aug 2006
    Location
    SWITZERLAND (french part)
    Posts
    802

    Default Multiple Interrupts using TMR0 and Interrupt On Change (IOCB) simultaneously

    Hi there,

    Here's one more thread about multiple interrupts use (...) but after hours of reading, I still can't find THE information I'm looking for or in other words, the info I can understand.

    I know Darrel made everyone's life much easier with his routine, but I would like to understand how multiple interrupts are to be handled "in a perfect world".

    I have made a program (see code hereunder) where I have involved two interrupts: TMR0 and an IOCB (Interrupt on Change) on PORTB.6 .

    As the TMR0's interrupt seems to work perfectly (= it toggles every second as it has to), the IOCB will work too but in a fuzzy way. In fact, the IOCB will sometimes light the IOCB_LED shortly, sometimes this LED will remain ON, sometimes it won't even light.

    Maybe I need to trigger the rising or falling edge of the push-button's action and also if and how to debounce it especially in an interrupt handler.

    Does my interrupt handling routine make sense? How can it be done a cleaner, simpler way?

    Any info?

    Code:
    ' PIC 16F690
    @ __config _FCMEN_OFF & _IESO_OFF & _BOR_OFF & _CPD_OFF & _CP_OFF & _MCLRE_OFF &_PWRTE_OFF & _WDT_OFF & _INTRC_OSC_NOCLKOUT
    
    '-------------------------------------------------------------------------------
    ' Registers   76543210
    OPTION_REG = %00000101 'PORT A&B Pull-Ups / TMR0 prescaler
    OSCCON     = %01100000 'Internal RC set to 4Mhz - not to be used with XTal
    INTCON     = %00101000 'INTerrupts CONtrol
    ANSEL      = %00000000 'Disable analog inputs Channels 0 to 7
    ANSELH     = %00000000 'Disable analog inputs Channels 8 to 11
    ADCON0     = %00000000 'A/D Module is OFF
    CM1CON0    = %00000000 'Comparator1 Module is OFF
    CM2CON0    = %00000000 'Comparator2 Module is OFF
    WPUA       = %00000000 'Weak pull-ups
    IOCA       = %00000000 'interrupt on change
    TRISA      = %00000000 'Set Input/Output (0 to 5)
    PORTA      = %00000000 'Ports High/Low (0 to 5)
    WPUB       = %01000000 'Weak pull-ups
    PORTB      = %00000000 'Ports High/Low (4 to 7)
    IOCB       = %01000000 'interrupt on change
    TRISB      = %01000000 'Set Input/Output (4 to 7)
    TRISC      = %00000000 'Set Input/Output (0 to 7)
    PORTC      = %00000000 'Ports High/Low (0 to 7)
    
    DEFINE OSC 4
    
    '-------------------------------------------------------------------------------
    ' Variables
    Ticks    VAR BYTE
    Ticks    = 0
    Old_bits VAR BYTE
    New_bits VAR BYTE
    P_Button VAR PORTB.6
    TMR0_LED VAR PORTA.4  'indicates a TMR0 INTerrupt
    IOCB_LED VAR PORTA.5  'indicates a IOCB INTerrupt
    
    
    '覧覧覧覧覧覧覧覧覧覧覧覧覧覧覧覧覧覧覧覧覧覧覧覧覧覧覧覧覧覧覧覧覧覧覧覧覧覧覧
    ' Start program
    '覧覧覧覧覧覧覧覧覧覧覧覧覧覧覧覧覧覧覧覧覧覧覧覧覧覧覧覧覧覧覧覧覧覧覧覧覧覧覧
    
    ON INTERRUPT GOTO ISR
    
    MAIN:
        Old_bits = PORTB
        ' do some things here
        GOTO MAIN
    
    
    '-------------------------------------------------------------------------------
    ' Interrupt routine
    '-------------------------------------------------------------------------------
    ISR:
        DISABLE
        
            ' TMR0
            IF INTCON.2 = 1 THEN
                INTCON.2 = 0
                TICK_INT:
                    Ticks = Ticks + 1
                    IF Ticks < 61 THEN DO_NOTHING
                    Ticks = 0
                    TOGGLE TMR0_LED
                DO_NOTHING:
            ENDIF
        
            ' IOCB
            IF INTCON.0 = 1 THEN
                INTCON.0 = 0
                New_bits = PORTB
                IF (New_bits.6 <> Old_bits.6) THEN 'PORTB.6 has changed
                    TOGGLE IOCB_LED
                ENDIF
                Old_bits = New_bits
            ENDIF    
    
        RESUME
        ENABLE
    END
    Roger

  2. #2
    Join Date
    May 2013
    Location
    australia
    Posts
    2,032

    Default Re: Multiple Interrupts using TMR0 and Interrupt On Change (IOCB) simultaneously

    with a quick look I can see these issues


    from the data sheet

    For enabled interrupt-on-change pins, the present
    value is compared with the old value latched on the last
    read of PORTB to determine which bits have changed
    or mismatch the old value. The 僧ismatch outputs are
    OR壇 together to set the PORTB Change Interrupt flag
    bit (RABIF) in the INTCON register (Register 2-3).
    This interrupt can wake the device from Sleep. The user,
    in the Interrupt Service Routine, clears the interrupt by:
    a) Any read or write of PORTB. This will end the
    mismatch condition
    .
    b) Clear the flag bit RABIF.
    A mismatch condition will continue to set flag bit RABIF.
    Reading or writing PORTB will end the mismatch
    condition and allow flag bit RABIF to be cleared. The latch
    holding the last read value is not affected by a MCLR nor
    Brown-out Reset. After these Resets, the RABIF flag will
    continue to be set if a mismatch is present.
    since you are continually reading portb in your main loop the mismatched condition is probably being masked.

    and secondly according to the manual
    Code:
     DISABLE  should go here 
    ISR:
        DISABLE    not here    
            ' TMR0
            IF INTCON.2 = 1 THEN
                INTCON.2 = 0
                TICK_INT:
                    Ticks = Ticks + 1
                    IF Ticks < 61 THEN DO_NOTHING
                    Ticks = 0
                    TOGGLE TMR0_LED
                DO_NOTHING:
            ENDIF
        
            ' IOCB
            IF INTCON.0 = 1 THEN
                INTCON.0 = 0
                New_bits = PORTB
                IF (New_bits.6 <> Old_bits.6) THEN 'PORTB.6 has changed
                    TOGGLE IOCB_LED
                ENDIF
                Old_bits = New_bits
            ENDIF    
    
        RESUME
        ENABLE
    END

  3. #3
    Join Date
    Jan 2009
    Location
    Miami, Florida USA
    Posts
    628

    Default Re: Multiple Interrupts using TMR0 and Interrupt On Change (IOCB) simultaneously

    Hi,

    Why don't you use Darrel's interrupts? It's a lot easier than ON INTERRUPT GOTO ISR.

    Also, it is much easier to include a line in your MAIN routine that monitors the state of a switch. You can use the pullup resistors in PORTB, a switch, and a line of code with an IF statement to do what you want. Of course, you need to de bounce the switch.
    "No one is completely worthless. They can always serve as a bad example."

    Anonymous

  4. #4
    Join Date
    Nov 2005
    Location
    Bombay, India
    Posts
    899

    Default Re: Multiple Interrupts using TMR0 and Interrupt On Change (IOCB) simultaneously

    If you look into the PBP manual, you will notice that PBP does not handle interrupts like they are meant to be. They are polled. So, there is a lot of latency involved.

    "Using ON INTERRUPT, when an interrupt occurs PBP simply flags the event and immediately goes back to what it was doing. It does not immediately vector to your interrupt handler. Since PBP statements are not re-entrant (PBP must finish the statement that is being executed before it can begin a new one) there could be considerable delay (latency) before the interrupt is handled."
    You should get used to using assembler interrupts in PBP. Much more power and deterministic. Read "interrupts in Assembler" in the manual. Better still, use Darrels' interrupt code as suggested by rsocor01

  5. #5
    Join Date
    Nov 2005
    Location
    Bombay, India
    Posts
    899

    Default Re: Multiple Interrupts using TMR0 and Interrupt On Change (IOCB) simultaneously

    If you look into the PBP manual, you will notice that PBP does not handle interrupts like they are meant to be. They are polled. So, there is a lot of latency involved.

    "Using ON INTERRUPT, when an interrupt occurs PBP simply flags the event and immediately goes back to what it was doing. It does not immediately vector to your interrupt handler. Since PBP statements are not re-entrant (PBP must finish the statement that is being executed before it can begin a new one) there could be considerable delay (latency) before the interrupt is handled."
    You should get used to using assembler interrupts in PBP. Much more power and deterministic. Read "interrupts in Assembler" in the manual. Better still, use Darrels' interrupt code as suggested by rsocor01

  6. #6
    Join Date
    Aug 2006
    Location
    SWITZERLAND (french part)
    Posts
    802

    Default Re: Multiple Interrupts using TMR0 and Interrupt On Change (IOCB) simultaneously

    Thanks a lot for your info.

    For the time being, I'll try to keep it as simple as possible, correct my current code according to Richard's and Roscor's remarks
    Roger

Similar Threads

  1. 18F2420, instant interrupts, and TMR0
    By dhickman in forum mel PIC BASIC Pro
    Replies: 7
    Last Post: - 11th March 2009, 19:33
  2. 18F2620 tmr0 and interrupts
    By astouffer in forum mel PIC BASIC Pro
    Replies: 2
    Last Post: - 8th March 2009, 01:56
  3. help: TMR0 interrupts disabling PORTAchange interrupts???
    By xnihilo in forum mel PIC BASIC Pro
    Replies: 4
    Last Post: - 19th August 2008, 16:10
  4. 3 Timer Interrupts Running simultaneously
    By emavil in forum mel PIC BASIC Pro
    Replies: 1
    Last Post: - 20th February 2007, 04:49
  5. Programming Multiple PICs Simultaneously
    By Archangel in forum General
    Replies: 13
    Last Post: - 16th January 2007, 20:42

Posting Permissions

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