Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

PIC Microcontroller Return from Interrupts ..with a twist

Status
Not open for further replies.

crash@home

New Member
hey all.. I've been working on a project for some time using a PIC, everything in the program works as it should, however and the one issue I'm having is if i trigger an interrupt how can i return to a DIFFERENT point in my main program.
my initial theory was to set a bit in my delay loop then to a bit test at the return address and skip if set but i don't think it would work since my initial address would be from within a delay loop so the instruction that it would skip would essentially be a 'NOP' instruction and then the counter would continue counting down anyway. what i want to do is skip this counter instruction all together and move to the next line of code AFTER the delay.

thinking about it, i have an idea.. but while i work on it..

any ideas?
 
I would suggest it would be EXTREMELY bad practice to try and do such a thing, simply set a flag and test for the flag (in multiple places if required) in the main program.
 
Hi,

Normally in assemble you would pop the old address off of the stack and push the new address onto the stack and execute a return instruction or use a jump instruction, but the PIC doesnt have PUSH and POP instructions for direct use.

What you can do is goto the new address and start the stack over. You'll have to manage the code a little differently that way though. The stack will just wrap.

If you goto a location from within a loop the next return instruction encountered will take you back to the location that called the loop. So you can set a bit inside the ISR and test it within the inner loop of the main loop and goto the set location if needed.
So the ISR will set the bit and will return to the main loop, but after it returns and gets back into the inner loop it will test the bit and goto the new address, and that new address should use a 'ret' instruction to exit rather than something else so that it returns to the caller of the main loop.
The added time for the time to get to the new address will be a little longer because it depends where the main loop or inner loop was when the interrupt occurs. It has to actually get to the test instruction before it can test it, so that will take a variable amount of time but it shouldnt be more that a few instructions.
 
Last edited:
I've been doing what Nigel stated. I even tried setting a new pcl in the interrupt, but that didn't work out all to well, lol.
 
good to see im not the only person experiencing this issue.. i'm not fully understanding what you mean regarding the flags. if i set a flag in the interrupt routine.. then in he delay loop (that id be returning to) test for that flag and if that flag is there.. it would still. if im correct only skip the instruction that follows not the next sequence of instructions to get me out of the delay loop.. ideally what i need is something to be equivalent to a GOTO instruction which will allow me to skip a few lines of code..
 
in my interurupt routien, i check these, then i set a flag bit in a file for that area:

sensors
btfss INTCON, 0 ;iocb flag
goto exit_ir
bsf bump, 7 ;bumper flag bit, bypasses delays
goto exit_ir


In my delay area i just poll for a flag, just as Nigel stated.

Delay_0
btfsc bump, 7 ;sensors flag bit
return (this will skip the rest of the delay and return to where you were previously before the delay)
decfsz counta, f
goto $+2
decfsz countb, f
goto Delay_0
decfsz count1, f
goto d1
retlw 0x00
 
Last edited:
Hi,

The trick is to NOT return from the delay if the bit is set. It doesnt matter WHERE the 'return' is, it will return to the caller of the delay loop.

Pseudo code:

Delay:
OuterLoopStart
InnerLoopStart
TestBit ;must adjust delay counters to account for this extra time
If bit set, goto Address 02
ContinueInnerLoop
ContinueOuterLoop
return

Address 02:
DoStuff()
DoMoreStuff()
return ; note the return here, which returns you to the caller of the delay loop above.

So there are two possibilities:
1. No interrupt: No bit set so delay loop proceeds as usual and returns to the delay caller.
2. An interrupt which sets the bit, then the delay loop exits to the Address 02, and the Address 02 routine returns to the delay caller.

So either way the caller of the delay is returned to eventually.

Note also that the Testbit part requires adjusting the timing values to get the delay to be the same as it was without the Testbit part.
 
Last edited:
This worked for me

The few times I needed what you have in mind, I went away with what Nigel suggests

simply set a flag and test for the flag (in multiple places) if required in the main program.
 
it would still. if im correct only skip the instruction that follows not the next sequence of instructions to get me out of the delay loop.. ideally what i need is something to be equivalent to a GOTO instruction which will allow me to skip a few lines of code..

If that's what you think, no wonder you're struggling.

You don't 'skip the next line if the flag is set', you 'skip the next line if the flag is clear' (i.e. almost every time) - the next line that gets skipped is the goto instruction.

Do you even need to be using interrupts at all?.
 
+1 on Nigel's "set a flag in the interrupt handler that gets checked in main code" recommendation. If you had a writable stack you could simply decrement the stack pointer and rewrite a new address in place of the "pre-interrupt" pushed address but that's not available to you here.
 
Last edited:
+1 on Nigel's "set a flag in the interrupt handler that gets checked in main code" recommendation. If you had a writable stack you could simply decrement the stack pointer and rewrite a new address in place of the "pre-interrupt" pushed address but that's not available to you here.

And I wouldn't consider it a particularly good idea even if it was :D

I would suggest he's probably using interrupts when there's no need to, thus over-complicating matters anyway.
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top