1.When using interrupt priority
levels, set IPEN and then select the user-assigned priority level for the
interrupt source by writing the control bits in the appropriate IPRx control
register.
Important: At a device Reset, the IPRx registers are initialized such
that all user interrupt sources are assigned to high priority.
2.Clear the Interrupt Flag Status
bit associated with the peripheral in the associated PIRx STATUS register.
3.Enable the interrupt source by
setting the interrupt enable control bit associated with the source in the
appropriate PIEx register.
4.If the vector table is used
(MVECEN = 1), then set up the start address for the Interrupt
Vector Table using IVTBASE. See the Interrupt Vector Table Contents section for more details.
5.Once IVTBASE is written to, set
the interrupt enable bits in INTCON0.
; Each ISR routine must have a predetermined origin otherwise there will be
; an assembly error because the address is not determined until link time
; which is too late to do the divide by 4 math on the address.; Predetermined addresses must be evenly divisible by 4.
ISRSW CODE 0x3E00; SW interrupt service code here.
BANKSEL PIR0
BCF PIR0, SWIF
RETFIE FAST
ISRHLVD CODE 0x3E40; HLVD interrupt service code here.
BANKSEL PIR0
BCF PIR0, HLVDIF
RETFIE FAST
ISROSF CODE 0x3E60; OSF interrupt service code here.
BANKSEL PIR0
BCF PIR0, OSFIF
RETFIE FAST
IntInit:; Disable all interrupts
BCF INTCON0, GIE, ACCESS
; Set IVTBASE (optional -default is 0x000008)
CLRF IVTBASEU, ACCESS
MOVLW 0x3F
MOVWF IVTBASEH, ACCESS
CLRF IVTBASEL, ACCESS
; Clear any interrupt flags before enabling interrupts
BANKSEL PIR0
BCF PIR0, SWIF
BCF PIR0, HLVDIF
BCF PIR0, OSFIF
; Enable interrupts
BANKSEL PIE0
BSF PIE0, SWIE
BSF PIE0, HLVDIE
BSF PIE0, OSFIE
; Set interrupt priorities if necessary
BANKSEL IPR0
BSF INTCON0, IPEN_INTCON0, ACCESS ; Enable interrupt priority
BCF IPR0, HLVDIP ; Make HLVD interrupt low priority
; Enable interrupts
BSF INTCON0, GIEH, ACCESS
BSF INTCON0, GIEL, ACCESS
RETURN 1; Save SWISR in vector table (IVTBASE+0*2)
ISR1 CODE 0x3F00
DW (0x3E40>>2);(SWISR/4); Save HLVDISR in vector table (IVTBASE+1*2)
ISR2 CODE 0x3F02
DW (0x3E60>>2);(HLVDISR/4); Save CLC2ISR in vector table (IVTBASE+2*2)
ISR3 CODE 0x3F04
DW (0x3E00>>2);(OSFISR/4)
Setting Up Vectored Interrupts
Using XC8
// NOTE 1: If IVTBASE is changed from its default value of 0x000008, then the// "base(...)" argument must be provided in the ISR. Otherwise the vector// table will be placed at 0x0008 by default regardless of the IVTBASE value.// NOTE 2: When MVECEN=0 and IPEN=1, a separate argument as "high_priority"// or "low_priority" can be used to distinguish between the two ISRs.// If the argument is not provided, the ISR is considered high priority// by default.// NOTE 3: Multiple interrupts can be handled by the same ISR if they are// specified in the "irq(...)" argument. Ex: irq(IRQ_SW, IRQ_HLVD)void__interrupt(irq(IRQ_SW),base(0x3008))SW_ISR(void){
PIR0bits.SWIF =0;// Clear the interrupt flag
LATCbits.LATC0 ^=1;// ISR code goes here}void__interrupt(irq(default),base(0x3008))DEFAULT_ISR(void){// Unhandled interrupts go here}void INTERRUPT_Initialize (void){
INTCON0bits.GIEH =1;// Enable high priority interrupts
INTCON0bits.GIEL =1;// Enable low priority interrupts
INTCON0bits.IPEN =1;// Enable interrupt priority
PIE0bits.SWIE =1;// Enable SW interrupt
PIE0bits.HLVDIE =1;// Enable HLVD interrupt
IPR0bits.SWIP =0;// Make SW interrupt low priority// Change IVTBASE if required
IVTBASEU =0x00;// Optional
IVTBASEH =0x30;// Default is 0x000008
IVTBASEL =0x08;}