Interrupts

The PIC32MX generates interrupt requests in response to interrupt events from peripheral modules. The Interrupt module exists external to the CPU logic and prioritizes the interrupt events before presenting them to the CPU.
The PIC32MX Interrupts module includes the following features :

ISRs are organized in IVT. ISR is defined as a standard function but with the iv directive afterwards which connects the function with specific interrupt vector. For more information on IVT refer to the PIC32 Family Reference Manual.

Configuring Interrupts

The PIC32MX interrupt controller can be configured to operate in one of two modes :

Interrupt Priorities

In the Multi Vector Mode, the user is able to assign a group priority and group subpriority level to each of the interrupt vectors. The user-selectable priority levels range from 1 (the lowest priority) to 7 (the highest).
If an interrupt priority is set to zero, the interrupt vector is disabled for both interrupt and wake-up purposes. Interrupt vectors with a higher priority level preempt lower priority interrupts.

The subpriority will cause that when two interrupts with the same priority are pending, the interrupt with the highest subpriority will be handled first. The user-selectable subpriority levels range from 0 (the lowest subpriority) to 3 (the highest).

Interrupts and Register Sets

The PIC32MX family of devices employs two register sets, a primary register set for normal program execution and a shadow register set for highest priority interrupt processing.

Interrupt Coding Requirements

In order to correctly utilize interrupts and correctly write the ISR code, the user will need to take care of these things :

  1. Write the Interrupt Service Routine. You may use Interrupt Assistant to easily write this routine.
  2. Initialize the module which will generate an interrupt.
  3. Set the correct priority and subpriority for the used module according to the priorities set in the Interrupt Service Routine.
  4. Enable Interrupts.

Interrupt Service Routine

Interrupt service routine is defined in this way :

sub procedure interrupt() iv IVT_ADC ilevel 7 ics ICS_SOFT
  ' Interrupt service routine code
end sub

where :


User can explicitly declare starting interrupt routine address using org directive :

sub procedure interrupt() org 0x9D000000 iv IVT_ADC ilevel 7 ics ICS_SOFT
  ' Interrupt service routine code
end sub

Function Calls from Interrupt

Calling functions from within the interrupt routine is possible. The compiler takes care about the registers being used, both in "interrupt" and in "main" thread, and performs "smart" context-switching between two of them, saving only the registers that have been used in both threads. It is not recommended to use a function call from interrupt. In case of doing that take care of stack depth.

Use the DisableContextSaving to instruct the compiler not to automatically perform context-switching. This means that no register will be saved/restored by the compiler on entrance/exit from interrupt service routine.
This enables the user to manually write code for saving registers upon entrance and to restore them before exit from interrupt.

Interrupt Example

Here is a simple example of handling the interrupts from Timer1 (if no other interrupts are allowed):

program Timer1_interrupt

sub procedure Timer1Int() iv IVT_TIMER_1 ilevel 7 ics ICS_SRS
  T1IF_bit = 0             ' Clear T1IF
  LATB = not PORTB         ' Invert PORTB
end sub

main:
  AD1PCFG = 0xFFFF         ' Initialize AN pins as digital
  TRISB  = 0               ' initialize PORTB as output
  LATB   = 0xAAAA          ' Initialize PORTB value

  TMR1 = 0                 ' reset timer value to zero
  PR1 = 65000              ' Load period register

  T1IP0_bit = 1            ' set interrupt
  T1IP1_bit = 1            ' priority
  T1IP2_bit = 1            ' to 7

  TCKPS0_bit = 1           ' Set Timer Input Clock
  TCKPS1_bit = 1           ' Prescale value to 1:256

  EnableInterrupts         ' Enable all interrupts

  T1IE_bit = 1             ' Enable Timer1 Interrupt
  ON__T1CON_bit = 1        ' Enable Timer1

end.
Copyright (c) 2002-2012 mikroElektronika. All rights reserved.
What do you think about this topic ? Send us feedback!
Want more examples and libraries? 
Find them on LibStock - A place for the code