3.1 Interrupts


Interrupts are unexpected events in a sequence of execution of instructions causing an interruption of the normal programme flow. The causes of interrupts can be different. For the family of dsPIC30F microcotrollers, in the transducer or general purpose applications, 41 interrupt sources and 4 types of traps, ranked according to the priority schematic, have been specified.

For each specified interrupt or trap the microcontroller (MCU) has a clearly defined further programme sequence specified by the interrupt vector table (IVT). The IVT contains the initial addresses of interrupt routines for each interrupt source or trap. IVT is located in the programme memory starting at location 0x000004 up to location 0x00007E.

In addition to the interrupt vestor table, in the family of dsPIC30F microcontrollers, the alterante interrupt vector table (AIVT) is also specified. The purpose of the AIVT is to enable the realization of alternate interrupt routines. The AIVT is also located in the programme memory starting at location 0x000084 up to location 0x0000FE.

On the basis of the priorities specified by the special function registers, the interrupt controller is responsible for the preparation and preprocessing of interrupts:

  • IFS0<15:0>, IFS1<15:0>, and IFS2<15:0> are the registers containing all the interrupt request flags. Each source of interrupt has a status bit set by the respective peripherals or external signals. These flags are cleared by the user software.
  • IEC0<15:0>, IEC1<15:0>, and IEC2<15:0> are the registers containing all the interrupt enable control bits. These control bits are used to individually enable interrupts from the peripherals or external signals.
  • IPC0<15:0>, IPC1<15:0>, … IPC10<7:0> are the registers used to set the interrupt priority level for each of the 41 sources of interrupt.
  • IPL<3:0> are the bits containing the current CPU priority level. IPL<3> bit is located in the register CORCON and the remaining three bits IPL<2:0> are in the STATUS register (SR) of the microcontroller.
  • INTCON1<15:0> and INTCON2<15:0> are the registers containing global interrupt control functions. INTCON1contains the control and status bits for the processor trap sources; INTCON2 controls the external interrupt requests behaviour and the use of the alternate vector table by setting the ALTIVT bit (INTCON2<15:0>).

During processor initialization it is necessary to enable interrupts which will be used and assign the corresponding priority levels.

NOTE: Interrupt request flags are set in the IFSx registers irrespective of the interrupt enable bits in the IECx registers. When the conditions for an interrupt to occur are met, the corresponding bits in the IFS are set. Before an interrupt is allowed, the user software has to clear the corresponding IFSx bits because the interrupt controller, upon detecting an interrupt request will not be able to process new interrupt involving these IFSx bits.


Interrupt nesting is enabled by the NSTDIS bit of the control register INTCON1. Nesting of interrupt routines may be optionally disabled by setting this bit. This may be significant if it is necessary to carry out a part of the programme without an interrupt that could change the state which is the basis for this part of the programme or if the interrupt routine changes some variable which are of significance for further execution of the programme.

The priority level of each interrupt is assigned by setting the interrupt priority bits IP<2:0> for each source of interrupt. The bits IP<2:0> are the least significant 3 bits of each nibble (4 bits) within the IPCx register. Bit no. 3 of each nibble iz always zero. The user can assign 7 priority leveles, from 1to 7. Level 7 is the highest and level 1 the lowest priority level for the maskable interrupts, i.e. for the interrupts that could be enabled by the control bits of IECx.

If an interrupt is assigned priority level 0, it is the same as if no interrupt is allowed by the bits set in IECx.

Natural order priority is specified by the position of an interrupt in the vector table (IVT). It is used only to resolve conflicts between simultaneous pending interrupts with the same user assigned priority level. Then, the interrupt of the higher natural level of priority is executed first. As an example, table 3-1 shows for the microcontroller dsPIC30F4013 the interrupt vector table (IVT) with all sources of interrupts, interrupt number in the vector table, and the number which defines the natural order priority.

Highest Natural Order Priority
0 8 0x000014 0x000094 INT0 – External Interrupt 0
1 9 0x000016 0x000096 IC1 – Input Capture 1
2 10 0x000018 0x000098 OC1 – Output Compare 1
3 11 0x00001A 0x00009A T1 – Timer 1
4 12 0x00001C 0x00009C IC2 – Input Capture 2
5 13 0x00001E 0x00009E OC2 – Output Compare 2
6 14 0x000020 0x0000A0 T2 – Timer 2
7 15 0x000022 0x0000A2 T3 – Timer 3
8 16 0x000024 0x0000A4 SPI1
9 17 0x000026 0x0000A6 U1RX – UART1 Receiver
10 18 0x000028 0x0000A8 U1TX – UART1 Transmitter
11 19 0x00002A 0x0000AA ADC – ADC Convert Done
12 20 0x00002C 0x0000AC NVM – NVM Write Complete
13 21 0x00002E 0x0000AE SI2C – I2C Slave Interrupt
14 22 0x000030 0x0000B0 MI2C – I2C Master Interrupt
15 23 0x000032 0x0000B2 Input Change Interrupt
16 24 0x000034 0x0000B4 INT1 – External Interrupt 1
17 25 0x000036 0x0000B6 IC7 – Input Capture 7
18 26 0x000038 0x0000B8 IC8 – Input Capture 8
19 27 0x00003A 0x0000BA OC3 – Output Compare 3
20 28 0x00003C 0x0000BC OC3 – Output Compare 4
21 29 0x00003E 0x0000BE T4 – Timer 4
22 30 0x000040 0x0000C0 T5 – Timer 5
23 31 0x000042 0x0000C2 INT2 – External Interrupt 2
24 32 0x000044 0x0000C4 U2RX – UART2 Receiver
25 33 0x000046 0x0000C6 U2TX – UART2 Transmitter
26 34 0x000048 0x0000C8 Reserved
27 35 0x00004A 0x0000CA C1 – Combined IRQ for CAN1
28-40 36-48 0x00004C – 0x000064 0x0000CC – 0x0000E4 Reserved
41 49 0x000066 0x0000E6 DCI – CODEC Transfer Done
42 50 0x000068 0x0000E8 LVD – Low Voltage Detect
43-53 51-61 0x00006A – 0x00007E 0x0000EA – 0x0000FE Reserved
Lowest Natural Order Priority

Table 3-1. Interrupt vector table of microcontroller dsPIC30F4013


The example shows how dsPIC reacts to a rising signal edge at the pin RF6(INT0). For each rising edge the value at port D is incremented by 1.

NOTE: Pins that can be used for external interrupts are model dependent. This example is made for dsPIC30F6014A


Let us summarize the algorithm how dsPIC processes interrupts in this example. Two ports are used, PORTD as the output to display the number of interrupt events and PORTF as the input; this means that an interrupt will occur when at INT0 (RF6) logic 0 changes to logic 1. In the register IEC0 the least significant bit (IEC0.0) is set for allowing reaction to interrupt INT0. The meanings of other bits are shown in table 3-7. When an interrupt occurs, the function IntDetection is called. How does dsPIC “know” to call exactly this function? By instruction org in the interrupt vector table (see table 3-1) at the memory location 0x000014 is written the function IntDetection.

What does dsPIC do when an interrupt occurs, i.e. when at RF6 logic 1 appears after logic 0? At first, it writes logic 1 in the least significant bit of the register IFS0. Then, it tests if the interrupt INT0 is enabled (the least significant bit of IEC0). If yes, it reads from the interrupt vector table which part of the programme should be executed. mikroC compiler will, at position 0x000014, write the code where function IntDetection starts and dsPIC will execute this function and return to the main program.

Two operations are carried out in the interrupt function. At first, the interrupt flag is cleared (dsPIC does not do that automatically, but leaves this to the user software). Then, the value at port D is incremented by 1 with LATD++.

What would happen if the interrupt flag in the IFS register was not cleared? If this line is omitted, dsPIC will wait until first interrupt, call and execute the function IntDetection. What is the difference? The register IFS0 will still indicate that an interrupt occured. As soon as the microcontroller returns to the main programme and executes one instruction, it would understand that an interrupt occured again and theIntDetection function would be called again. This means that IntDetection function would be executed after each instruction of the main programme. The reader is encouraged to erase the line IFS0.F0:=0; and see what happens.

What is the purpose of while(1) asm nop;? When dsPIC comes to the end of a programme, it starts from the beginning as if reset. However, at the end of the programme the compiler inserts an endless loop to prevent this of happening. This has been inserted here to make the reader aware of the existence of this loop and that reseting dsPIC is not possible.