View previous topic :: View next topic |
Author |
Message |
Don_J
Joined: 13 Apr 2005 Posts: 7
|
Interrupt routine end |
Posted: Tue Jan 17, 2012 1:43 pm |
|
|
I am new to C programming, but have a long background in assembler programming. In C when the interrupt routine ends, where does the code go back to. In asm when an interrupt occurs, the current program counter (PC) is pushed to the stack. At the end of the interrupt routine if you execute a return the PC is pulled from the stack and the program picks up where it was. If you don't want that to happen there are asm instructions to adjust the stack and you would jump to some other place you code.
I don't know how to control the code at the end of the interrupt routine. Can you give me some guidance on this.
Thanks, Don |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
|
asmboy
Joined: 20 Nov 2007 Posts: 2128 Location: albany ny
|
|
Posted: Tue Jan 17, 2012 2:40 pm |
|
|
I know your issue having BT,DT,GT-TS
I learned the ropes in terms of the CCS support for ints by doing a file search of the examples folder - looking for the sequence "#INT" -
and after seeing the various examples - figured it out. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Jan 17, 2012 2:56 pm |
|
|
Upon rereading your post more carefully, I see that you want to jump
somewhere else instead of returning.
What PIC do you have ? The 16F-series have a hardware stack and
there are no stack manipulation instructions. So your PIC is the first thing
we need to know.
If you just want to jump to the start of the program upon getting an
interrupt, there is the reset_cpu() function.
Or tell us where you want to jump to in your program.
Here's a sample program which shows how to use reset_cpu() in a
timer interrupt routine:
http://www.ccsinfo.com/forum/viewtopic.php?t=29718&start=8
Note: This is a rarely used programming construct. It's not normally
done and not normally needed. |
|
|
Don_J
Joined: 13 Apr 2005 Posts: 7
|
|
Posted: Wed Jan 18, 2012 3:22 pm |
|
|
Thank you for all your comments. I think I should have been clearer in my question.
I am using a 18f2520. I think I have a good idea on how to do what I need in asm, but I would rather stay at a high level. Here is the scenario I am working with. The program is ramping up the speed of a motor by adjusting the PWM. We take a hardware interrupt and in the interrupt we shut the motor down as fast as possible. At the end of the interrupt routine I don't want to go back to ramping up the motor. I would like to go somewhere else and start to manage why we took the interrupt. My question is, is this a valid use of the Goto in C and if so is there a return address left in the stack from when the interrupt first occurred? If so do I need to pull the address off the stack to clean up the stack pointer? |
|
|
Mike Walne
Joined: 19 Feb 2004 Posts: 1785 Location: Boston Spa UK
|
One possible solution. |
Posted: Wed Jan 18, 2012 3:34 pm |
|
|
Could you set a flag in the interrupt routine, then use main to respond to the flag?
Mike |
|
|
asmboy
Joined: 20 Nov 2007 Posts: 2128 Location: albany ny
|
|
Posted: Wed Jan 18, 2012 3:47 pm |
|
|
Quote: |
We take a hardware interrupt and in the interrupt we shut the motor down as fast as possible. At the end of the interrupt routine I don't want to go back to ramping up the motor.
|
Thats enough to get the idea - may I assume that the interrupt is some sort of
"failsafe /protective" routine ?? triggered by a change in a port B int line ?
if so -
Code: |
// in your GLOBAL declarations
INT1 protect_flag=0;
// and any time you want to restart motor
protect_flag=0; // rearm the shut down INT handler
set_pwmx_duty(whatever )
// NEXT - inside your INT handler -add this :
if(!protect_flag) { // only do this IF protect flag=0
set_pwmx_duty(0); // as fast a shutdown as you could ask for
protect_flag=1; // register globally - don't do this again till rearmed
}
... complete your ISR remembering to do
input_B(); // to clear the B interrupt
|
|
|
|
RF_Developer
Joined: 07 Feb 2011 Posts: 839
|
|
Posted: Thu Jan 19, 2012 3:24 am |
|
|
Don_J wrote: | My question is, is this a valid use of the Goto in C? |
What? Jumping out of an ISR into mainline code? No, no, and again no. Yes, you would have to at the very least restore the stack, and indeed the entire processor context which has been saved for you by the unseen CCS interrupt vectoring code.
Please realise that C is NOT assembler. Come to that C# is not C either. You need to ditch most if not all of your assembler habits and learn a lot of new constructs and code patterns: C ones. One thing I'd strongly advise is don't learn about goto in C. If your inclination to use it is to prematurely jump out of an ISR then you REALLY need to forget it... totally. I'm serious! It does have use, for example for error exit from a deeply (as in six or more levels of blocking) nested routine such as in some, and only some, parsers.
Quote: |
and if so is there a return address left in the stack from when the interrupt first occurred? If so do I need to pull the address off the stack to clean up the stack pointer? |
Yes, and more that is not so obvious. That compounded by the lack of stack manipulation instructions, and the lack of what would be considered a "proper" stack. Recursion and reentrancy are a nightmare on PICs.
Anyway your application is motor control. That means a few usec here or there is nothing, hundreds of us are mere blips: glitches of no consequence. Tens of milliseconds barely even have any effect. So, what does "fast as possible" really mean in that situation? Simply setting a flag and dealing with it in the normal run of main loop code should be more that satisfactory. Unless, of course, you've stuck delay_ms() calls in there too...
In my applications (professional) I deal with RF devices that can blow themselves up in ns, and they have. No code can deal with that :-(
RF Developer |
|
|
|