Skip to main content

How to Use Interrupts in Pic and dsPic MicroControllers


Interrupts form the backbone of coding methodology in micro-controllers and their full understanding is vital for programmers willing to craft expert level codes. This tutorial gives all the essential information needed by Pic programmers to start using interrupts in their micro controller codes and applications.

The dsPic30f series micro-controller codes along with the Microchip's development IDE MplabX are used to demonstrate this tutorial here, but the same methodology is applicable on all Pic micro-controllers as well as micro-controllers from other manufacturers.

Users are advised to consult relevant data sheets for exact register and bit names.

What Is an Interrupt in a MicroController?

Interrupt can generally be defined as a function that is triggered on the occurrence of a predefined, hard-linked event in a micro-controller and not by means of normal function call.

This function is usually called an Interrupt Service Routine.

All interrupts have their unique:

  1. Interrupt vector.
  2. Predefined hard-linked event.
  3. Interrupt enable bits in the Interrupt enable register.
  4. Interrupt flag bits in the interrupt flag register.
  5. Interrupt priority.

Interrupt Vector

All interrupts are defined by a specific interrupt vector that is unique to that interrupt only.

Hard-linked Event

The interrupt vector is subsequently hard-linked to the occurrence of a predefined event in a micro-controller for:

  • Receiving data in the UART data buffer.
  • Receiving data on the CAN bus.
  • Compare match of the PWM register values.
  • Completion of the ADC conversion.
  • Many more depending on the type, family and model of the micro-controller.

A table given in the end of this article lists some examples of these hard-linked, interrupt triggering events.

Interrupt Enable Bit

This bit is used to enable the interrupt. An interrupt is activated if this bit is set to one and disabled if this bot is set to zero.

Interrupt Flag Bit

When ever an event linked to the interrupt occurs the interrupt flag is checked. If the interrupt is 0, then the interrupt triggers. If the interrupt flag is not set to zero, the interrupt will not trigger.

Interrupt Priority

When more then one interrupt is to be coded, it must be decided that which one will be served first should a trigger event occurs for both of them. An interrupt priority bit in the Interrupt Priority Control Register specifies the priority for its respective interrupt. Interrupt with the highest priority, i.e., six is served first.

How Interrupts Work in MicroControllers?

Interrupts trigger when any of the events they are hard-linked to, for example those explained above, occurs. They work in the following sequence:

  1. Event linked to an interrupt occurs.
  2. The controller becomes aware of the occurrence of that event and checks the interrupt flag.
  3. If trigger event for more then one interrupts is received then interrupt priority is checked.
  4. If the interrupt flag is clear, it is auto-set and the program counter moves to the respective interrupt vector with the highest priority in the code.
  5. Code in the respective interrupt function starts executing from below the interrupt vector.
  6. After the execution of interrupt service routine is complete, an interrupt flag is cleared upon exiting the routine.
  7. Micro-controller program resumes from the same place from where it jumped to enter the interrupt service routine.
  8. The interrupt executes again if the event re-occurs.

General Procedure and Code to Call an Interrupt

An interrupt may be initialized following these steps:

1) Set the interrupt Enable Bit

The interrupt enable bit for the respective interrupt must be enabled from the Interrupt enable register first so that the interrupt is activated and the occurrence of the respective hard-linked event is enabled to trigger the interrupt.

2) Set the Interrupt Priority Bit

If multiple interrupts are to be used in a code, they may be assigned priorities based on their importance in the application using the Interrupt Priority bits in the Interrupt Priority Control Register.

void Interrupt_Init( void )
    IEC2bits.PWMIE = 1;
    IPC2bits.PWMIP = 1;  

//This function enables the PWM Interrupt enable bit in the Interrupt Enable Control 2 register.
//This function may be called in the main body before while(1) loop by way of normal function call.
// It is better to use an interrupt initialization function if multiple interrupts are to be enabled.
// However it is not necessary to use this function as the command may also be directly written in the main function.
// Interrupt priority is set to 1 (lowest).

3) Pick the respective interrupt vector

Pick the respective interrupt vector and place it in the header of the interrupt function or interrupt service routine. The code below shows how to craft an interrupt service routine from the interrupt vector.

A list of interrupt vectors is also given in this article for reference.

void __attribute__((interrupt, auto_psv)) _PWMInterrupt( void )               
    //your code here
    IFS2bits.PWMIF = 0;

// The tag "_PWMInterrupt" is the distinctive interrupt vector in this function.
// Replacing this with another interrupt vector will also change the type of interrupt.

4) Code the desired operation

The desired operation may be coded in the interrupt function.

5) Clear the Interrupt flag when exiting the function

When exiting the interrupt the respective interrupt flag must be cleared so that the interrupt may be triggered again.

Types of Interrupts

Their may be as many as 50+ types of interrupts in micro-controllers ranging from I2C interrupts, SPI interrupts, quadrature encoder interrupts and timer interrupts depending on the type, family and model.

Some of the interrupts found in pic micro-controllers are given in the table below to enhance understanding.

Guideline table for interrupt vectors and interrupt trigger events.

Interrupt NameInterrupt VectorTrigger Stimulus

PWM Interrupt


PWM compare match between time base register and counting register.

ADC Interrupt


ADC conversion complete

UART Receive Interrupt


Recieving data in UART receive register

UART Transmitting Interrupt


Loading data in UART transmitting register

Fault Interrupt


Logic level change on FLT pin

External Interrupt


Logic level change on Int0/1 pins

Low Voltage Interrupt


Detecting low voltage

This article is accurate and true to the best of the author’s knowledge. Content is for informational or entertainment purposes only and does not substitute for personal counsel or professional advice in business, financial, legal, or technical matters.

© 2018 StormsHalted