Interrupt handling

Please check the frequently asked questions before posting to the forum.
Post Reply
Author
Message
nikola
mikroElektronika team
Posts: 137
Joined: 03 Aug 2004 12:44
Contact:

Interrupt handling

#1 Post by nikola » 27 Jan 2005 16:15

Q: How do I write an interrupt handler for my PIC?

A: Simply declare a procedure named interrupt and place your code there:

Code: Select all

procedure interrupt;
begin
// ISR code
end;
Also, you do not need to save context at the beginning of interrupt routine. mikroPascal saves the following registers at the beginning of the interrupt: W, STATUS, FSR and PCLATH. Upon return from the interrupt routine, content of these registers will be restored.

-

fastbike
Posts: 99
Joined: 20 Aug 2004 05:28
Location: New Zealand

#2 Post by fastbike » 06 Feb 2005 20:32

Q. Why can't I call a routine from the Interrupt procedure?

A. Trying to call a routine from the Interrupt procedure will result in a 142 compiler error "Routine calls from Interrupt are not allowed."

The reasons for this include:

1. Compiler design
All routines use common RAM for placing temp variables. Common RAM needs no bank selecting and it is perfect for the job. Temp variables are much needed when calling a complicated expression.

This rule applies for all routines including interrupt. The compiler can control which routine call another and can effectively prevent overlapping of temp locations between two routines. However, interrupts can occur any time a and cause the overlap. Then your program goes to la-la land.

2. Limitations of the PIC architecture
i.e. limited stack, limited RAM, limited interrupts, etc.

3. Poor program design
The general idea is to keep code execution during an ISR as short as possible. While the ISR is executing all other interrupts are blocked. Some users consider it a sign of bad program design if you need to call another routine from an ISR and to avoid poor performance you should reorganise your code.
A workaround is to use the ISR to set some variable when GPIO, Timer, or other interrupt occurs. In the main routine that variable should be tested, and appropriate function should be called. It means that the actual service routine won't be executed immediately at the time of interrupt. This is acceptable in some cases, and unacceptable in others.

Note. It is best to view ISRs as dispatchers for interrupts events, they should not be a place where the data is analysed/stored/displayed...

Rotary_Ed
Posts: 756
Joined: 26 Dec 2004 23:10
Location: Matthews, NC, USA
Contact:

Interrupts

#3 Post by Rotary_Ed » 29 Apr 2005 00:37

I have a problem with the interrupt procedure in MP - I don't use it. I have discovered that the interrupt flag of a module is set when the interrupt condition is met regardless of whether the interrupt enable is set or clear. That being the case, rather than waste time with the Procedure Interrupt setting a flag or some variable and then polling it in the main code. I simply check for the interrupt flag to be set in the main code. I am a newbie to programming, but I really and truly do not see any benefit with the procedure interrupt in MP since I can't call a routine from it.

I had the early version of MP when you COULD call a routine from the Procedure interrupt and I liked that. I understand the reason's given for stopping that capability. But with that accepted, I now find no reason to use the interrupt procedure in MP. Perhaps it will dawn on me someday the value of the procedure as I gain experience. I know thousands of programmers must find a use for it. But, for now, you could ditch the concept as far as I can see. What benefit?
Rotary_Ed
Matthews, NC USA
Rv-6A N494BW Rotary Powered

LGR
Posts: 3204
Joined: 23 Sep 2004 20:07

#4 Post by LGR » 29 Apr 2005 01:26

If you follow the explaination, you can get everything done in almost real time by setting flags in the interrupt routine, and then servicing the interrupt in the main procedure based on the flag. Sometimes this is good enough, and sometimes it isn't. I have suggested making special routines which don't use local variables so that they can be called from within the interrupt routine, but I don't know if that idea is going anywhere. This is one reason why I am using dsPICs for any serious applications - interrupts can be nested and prioritized. and procedures can be called to any depth. I can hardly wait for dsPIC Pascal to work. :P
If you know what you're doing, you're not learning anything.

User avatar
zristic
mikroElektronika team
Posts: 6608
Joined: 03 Aug 2004 12:59
Contact:

#5 Post by zristic » 29 Apr 2005 08:47

We will post an example of how to call procedure interrupt soon after the versions are released.

Rotary_Ed
Posts: 756
Joined: 26 Dec 2004 23:10
Location: Matthews, NC, USA
Contact:

Interrupts LGR

#6 Post by Rotary_Ed » 29 Apr 2005 21:20

Thanks for the Response LGR. But, I guess I am still missing the big picture. You say setting flags in the procedure interrupt and then servicing the flags in the main routine. What I am doing is simply checking for the interrupt flag in the main routine without ever using the procedure Interrupt to set them. Since the Interrupt flags are set regardless and can be polled in the main routine (why bother with having the procedure Interrupt set other flags?) why do I need the interrupt routine? I am using interrupts for TRM0, CCP, and LVD modules - all work just fine by polling their IFs in the main program. What would having flags set in the Procedure Interrupt gain me over my current method????

Clearly I am misssing something important here, but - sigh- perhaps the light bulb will come on any day now. Perhaps for my applications I should switch to dsPICs - but apparently that compiler is not as mature as the MP at the moment, so will have to wait in any case.


Thanks again
Rotary_Ed
Matthews, NC USA
Rv-6A N494BW Rotary Powered

MustardMan
Posts: 23
Joined: 04 Jul 2006 03:47

#7 Post by MustardMan » 04 Jul 2006 03:55

@Rotary_Ed

A simple example I can immediately see is this...

When an interrupt occurs, it sets a flag - one bit only. If the interrupt occurs a few times before you check the flag, you will only ever know that the interrupt has happened once.

If your ISR increments a variable/byte every time an interrupt occurs, then you know how many times you have missed it. For example, a timer interrupt. If your main loop is too slow for some reason, or has variable execution time, you may miss a 'tick'.
Alternately, a UART interrupt, you would know that you have missed characters (of course, your ISR should actually store the characters, not just count them!)

MM.

Post Reply

Return to “mikroPascal FAQ”