Interrupts
Interrupts can be easily handled by means of reserved words interrupt
, interrupt_low
and iv
. mikroBasic PRO for PIC implictly declares procedures interrupt
and interrupt_low
which cannot be redeclared.
For P16 and P18 high priorty interrupts reserved word is interrupt
. Its procedure prototype is :
sub procedure interrupt end sub
For P18 low priorty interrupts reserved word is interrupt_low
. Its procedure prototype is :
sub procedure interrupt_low end sub
You are expected to write your own definition (function body) to handle interrupts in your application.
mikroBasic PRO for PIC saves the following SFR on stack when entering interrupt and pops them back upon return:
- PIC12 family:
W
,STATUS
,FSR
,PCLATH
- PIC16 family:
W
,STATUS
,FSR
,PCLATH
- PIC18 family:
FSR
(fast context is used to saveWREG
,STATUS
,BSR
)
Disable Context Saving
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, except STATUS, WREG and BSR registers in high priority interrupt ('Fast Register Stack').
This exception can be overridden by placing an asm RETFIE 0
instruction at the end of the high priority interrupt routine (with redirecting all routine exits to this instruction).
Thus, DisableContextSaving
directive enables the user to manually write code for saving registers upon entrance and to restore them before exit from interrupt.
P18 priority interrupts

- function with name
interrupt
will be linked as ISR (interrupt service routine) for high level interrupt - function with name
interrupt_low
will be linked as ISR for low level interrupt_low
Function Calls from Interrupt
Calling functions from within the interrupt() routine is now possible. The compiler takes care about the registers being used, both in "interrupt" and in "main" thread, and performs "smart" context-switching between the two, saving only the registers that have been used in both threads. Check functions reentrancy.
Interrupt Handling
For the sake of interrupt handling convenience, new keywords, iv
and ics
, are introduced :
sub procedure Timer0_Interrupt iv 0x000008 ics ICS_OFF ' Timer0 interrupt routine counter = counter + 1 TMR0 = 96 INTCON = $20 end sub
where :
iv
- reserved word that inform the compiler that it is an interrupt service routine.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.
As you can see, now any valid routine name can be used as a interrupt routine name.
Bear in mind that appropriate interrupt vector address must be used (high priority interrupt vector is at 0x000008, while the low priority interrupt vector is at 0x000018) because in any other case compiler will report an error.
Now it is also possible to explicitly declare interrupt routine address :
sub procedure Timer0_Interrupt org 0x600 iv 0x000008 ' Interrupt routine will be placed at the address 0x600 counter = counter + 1 TMR0 = 96 INTCON = $20 end sub
In this way, the user can allocate the interrupt routine by its discretion, except for P16 family, where the interrupt routine must be allocated in the first bank.
Interrupt Examples
Here is a simple example of handling the interrupts from TMR0
(if no other interrupts are allowed):
sub procedure interrupt counter = counter + 1 TMR0 = 96 INTCON = $20 end sub
In case of multiple interrupts enabled, you need to test which of the interrupts occurred and then proceed with the appropriate code (interrupt handling):
sub procedure interrupt if TestBit(INTCON, TMR0IF) = 1 then counter = counter + 1 TMR0 = 96 ClearBit(INTCON, TMR0IF) ' ClearBit is realised as an inline function, ' and may be called from within an interrupt else if TestBit(INTCON, RBIF) = 1 then counter = counter + 1 TMR0 = 96 ClearBit(INTCON,RBIF) end if end if end sub
What do you think about this topic ? Send us feedback!