Interrupts
The dsPIC30/33 and PIC24 interrupt controller module reduces numerous peripheral interrupt request signals to a single interrupt request signal to the dsPIC30/33 and PIC24 CPU and has the following features:
- Up to 8 processor exceptions and software traps
- 7 user-selectable priority levels
- Interrupt Vector Table (IVT) with up to 62 vectors (dsPIC30) or up to 118 vectors (dsPIC33 and PIC24)
- A unique vector for each interrupt or exception source
- Fixed priority within a specified user priority level
- Alternate Interrupt Vector Table (AIVT) for debug support
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 example iv
IVT_ADDR_T1INTERRUPT
is IVT address of Timer1
interrupt source of the dsPIC 30F3014 MCU. For more information on IVT refer to the dsPIC30/33 and PIC24 Family Reference Manual.
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 Handling
Interrupt service routine is defined in this way :
sub procedure interrupt() iv IVT_ADDR_U1RXINTERRUPT ics ICS_AUTO ' Interrupt service routine code end sub
where :
iv
- reserved word that inform the compiler that it is an interrupt service routine.IVT_ADDR_U1RXINTERRUPT
- appropriate Interrupt Vector.ics
Interrupt Context Saving; Interrupt Context Saving can be performed in several ways :ICS_OFF
- No context savingICS_AUTO
- Compiler chooses whether the context saving will be perfomed or not.
User can explicitly declare starting interrupt routine address using org
directive :
sub procedure interrupt() org 0x600 iv IVT_ADDR_U1RXINTERRUPT ics ICS_AUTO ' Interrupt service routine code end sub
For the sake of backward compatibility, user may write also :
sub procedure interrupt() org IVT_ADDR_U1RXINTERRUPT ' Interrupt service routine code end sub
which is equivalent to :
sub procedure interrupt() iv IVT_ADDR_U1RXINTERRUPT ' Interrupt service routine code end sub
Is is recommended that interrupts are handled in this way for the sake of better readability of the user projects.
Interrupt Example
Here is a simple example of handling the interrupts from Timer1
(if no other interrupts are allowed):
//-------------- Interrupt routine sub procedure Timer1Int iv IVT_ADDR_T1INTERRUPT ics ICS_AUTO '** it is necessary to clear manually the interrupt flag: IFS0 = IFS0 and $FFF7 ' Clear TMR1IF '** user code starts here LATB = not PORTB ' Invert PORTB '** user code ends here end sub
What do you think about this topic ? Send us feedback!