5.4.2 Supporting Interrupts for PIC® Devices with Hardware Interrupt Vectors

This section demonstrates how to enable interrupts in the application code using High/Low Interrupt Vectors for PIC18s and the standard interrupt vector for PIC16s.

Description: The following section will walk through the setup of an application that is blinking the LED using a timer interrupt instead of using the Delay driver. This section will use the High/Low Priority Interrupt Vectors on the PIC18F47Q10 Curiosity Nano.
Note: The projects used in this example can be created by following the Creating a Bootloader Client for PIC® Devices and the Creating an Application for PIC® Devices sections of this document but on the PIC18F47Q10 Curiosity Nano.

For PIC18 devices that have hardware interrupt vectors, the bootloader must be configured to use the same form of interrupts. Follow the steps below to enable interrupt support in the application and bootloader.

  1. Set the bootloader project as the main project. From the Projects tab, right click on the project folder and select Set as Main Project.
    Figure 5-81 5-86. Set the Bootloader as the Main Project
  2. Open MCC by clicking the icon in the toolbar.
    Figure 5-82 5-87. Open MCC
  3. Open the Interrupt Manager tab and click the slider for Enable High/Low Interrupt Priority.
    Figure 5-83. Set High/Low Interrupt Priority
  4. Open the Project Properties tab and navigate to the XC8 Linker > Additional options. Add -Wl,-Pintcode=0x8,-Pintcode=0x18 to the text box in the middle of the window.
    Note: PIC16 devices will not need to remap any vector as it will be handled by the compiler.
    Important: Add the linker setting into all configurations.
    Figure 5-84. Set the Bootloader Intcode and Intcodelo Linker Setting
  5. Click the Generate button and then merge the required changes into the interrupt.c and interrupt.h files while leaving the added changed from before.
    Figure 5-85. Regenerate the Bootloader Code and Merge Configuration Changes
  1. Set the application project as the main project. From the Projects tab, right click on the project folder and select Set as Main Project.
    Figure 5-81 5-86. Set the Application as the Main Project
  2. Open MCC by clicking the icon in the toolbar.
    Figure 5-82 5-87. Open MCC
  3. Navigate to the Project Resources tab, and click the red x-box next to the Delay module.
    Figure 5-88. Remove the Delay driver
  4. Navigate to the Device Resources tab and add the TMR0 driver.
    Figure 5-89. Add TMR0
    1. Setup the TMR0 driver to use a time-out of 150 ms or more and then enable the Overflow Interrupt.
      Figure 5-90. Configure the Timer Module
  5. Navigate to the Interrupt Manager tab and flip the switch for High/Low Interrupt Priority.
    Note: PIC16 devices do not have a priority on the interrupt vector. Simply calling the enable function in the main.c is enough to enable the interrupts on the device.
    Figure 5-91. Enable High/Low Interrupt and Set the New Base Address
  6. Generate the new timer code and observe the new files being generated in the Output window.
    Figure 5-92. Regenerate and Merge the MCC Code
  7. Open the Project Properties tab and navigate to the XC8 Linker > Additional options. Add -Wl,-Pintcode=0x<Application Start Address> + 0x8,-Pintcode=0x<Application Start Address> + 0x18 to the text box in the middle of the window.
    Note: PIC16 devices will not need to remap any vector as it will be handled by the compiler.
    Important: Add the linker setting into all configurations that you need to offset the interrupt vector psects.
    Figure 5-93. Set the Application Intcode and Intcodelo Linker Setting
  8. Lastly, update the main.c to blink the LED using the overflow interrupt callback. Remove the calls to the Delay driver and update the main.c similar to the example below.
    Figure 5-94. Update the Blinking LED Code to Use Interrupts
  9. In some cases you will want to use the low priority interrupt vector inside of the bootloader code, doing so will result in a compilation failure due to the fact that we provide a placeholder function for the low priority vector by default. To correct this error, simply uncomment the dummy function that gets generated in the bl_interrupt.c file.
    Figure 5-95. Multiple Interrupt Functions Error

    To correct this error, simply comment out the below placeholder function located inside of the bl_interrupt.c file.

    /**
     Dummy Function
     */
    void __interrupt(low_priority) BL_LowPriorityInterrupt_Placeholder(void)
    {
        NOP();
    }
    Figure 5-96. Low Priority ISR Placeholder