Let's find out together what makes a PIC Tick!

Main Menu

Interrupt On Change Example

Started by GDeSantis, Jan 01, 2022, 06:24 PM

Previous topic - Next topic


Interrupt On Change (IOC) is a hardware feature in most PIC devices which is available on select I/O pins. When the hardware senses a port pin change in state, low to high or high to low, an interrupt will occur and set a bit in an appropriate register.

Once the bit is detected, an interrupt service routine can be run to implement any custom code for your application.

In the example, the following commands allow subroutine 'INT SERVICE ROUTINE' to execute in response to an IOC event:

        IOCAF.0 = 0         ;Clear PORTA.0 IOC Flag
        While IOCAF.0 = 0: Wend           ;Loop while IOCAF.0 = 0

To confirm IOC functionality, a core-independent PWM module operating at 100 Hz is connected to PORTA.0 to trigger IOC events.

Lastly, since a trigger pulse occurs every 10 milliseconds, the interrupt service routine must fully execute within this time to not miss an IOC event.


I don't know much about the PIC16F1575 device, but I don't think you are using interrupts?
You are simulating Interrupt On Change. Is that what you intended?

Best regards


Correct, the article posted on the forum pertains to Interrupt on Change which is not the same as using an external Interrupt or something similar in your program.


The feature is called Interrupt On Change.

Hard to see how that applies if you're not using interrupts, which that code example doesn't do.
All it does is poll the change flag (which can be useful I suppose if that's what you're after).


Also check errata before using IOC, many PIC devices have issues with IOC.


A nice piece of code and thanks for adding it.

IOC (Interrupt On Change) can be used within a state machine mechanism, so the interrupt flag is set when the pin changes, then the main program loop will detect a pin change even after the pin has gone back to normal and reset the flag for the next time.

When used correctly, the IOC on any pin is a great advantage. I use it for rotary encoder readings and the rotary encode can be attached to "any" two pins on the device:

' Check if it is the Rotary Encoder's movement that has triggered the IOC interrupt
    If IOC_RC0_IntFlag = True Then                              ' Is it an Interrupt On Change for PORTC.0?
        Enc_tTriggered = True                                   ' Yes. So set the rotation triggered flag (must be reset in the main program)
        Enc_bPinStore = %00000000                               ' Clear the variable Enc_bPinStore
        Enc_bPinStore.0 = Enc_Pin1                              ' Place the condition of pin Enc_Pin1 into bit-0 of Enc_bPinStore
        Enc_bPinStore.1 = Enc_Pin2                              ' Place the condition of pin Enc_Pin2 into bit-1 of Enc_bPinStore
        If Enc_bPinStore = %00000000 Then                       ' Is Enc_bPinStore 0?
            Enc_tDir = Enc_cClockwise                           ' Yes. So indicate that it is a clockwise movement
            If Enc_wCounter < 65535 Then                        ' \
                Enc_wCounter = Enc_wCounter + Enc_bIncDecValue  ' | Increment the rotation counter
            EndIf                                               ' /
        Else                                                    ' Otherwise...
            Enc_tDir = Enc_cAntiClockwise                       ' Indicate that it is an anti-clockwise movement
            If Enc_wCounter > 0 Then                            ' \
                Enc_wCounter = Enc_wCounter - Enc_bIncDecValue  ' | Decrement the rotation counter
            EndIf                                               ' /
        IOC_RC0_ClearIntFlag()                                  ' Clear the IOC flag for PORTC.0