PDA

View Full Version : cancelling a GOSUB without RETURN



peterdeco1
- 7th March 2007, 11:01
Hello Everybody. I am bringing up this subject again because on several occasions, my code would be much simpler using a GOSUB that contains a GOTO. However, I was told that not cancelling a GOSUB will cause code failure at some point. I've got an idea that I'm wondering if it would work. Tie MCLR to a port pin. Make the port pin an input. Both pins are tied to B+ through a resistor. In the code where the the GOTO is inside a GOSUB, make that port pin output low. It seems to me that this would reset the PIC and cancel the gosub. Am I correct? Example with 12F629 GPIO.3 (MCLR) attached to GPIO.4. Both tied to B+ through 10K:

BOOTUP:
CMCON = 7 'comparators off
TRISIO = %11111111 'ALL INPUTS
DEFINE OSCCAL_1K 1 ' Set OSCCAL for 1K device
@ DEVICE MCLR_ON, INTRC_OSC, WDT_ON, BOD_ON, PWRT_ON, PROTECT_ON
PAUSE 500 'SETTLE DOWN

START:
DO THIS AND THAT
GOSUB CHECKSWITCH
GOTO START

CHECKSWITCH:
IF GPIO.0 = 1 THEN RETURN
LOW GPIO.4 'WILL THIS CANCEL GOSUB & SEND TO BOOTUP??

mackrackit
- 7th March 2007, 12:00
Hi,
Not knowing anything about your project I would think a hardware re-set could be irritating. If waiting for a LCD to start for example. If you can live with a hardware re-set then you most likely could nest GOSUBs until the problem point is past, then RETURN to a common point.

From the manual:

GOSUB Label
Jump to the subroutine at Label saving its return address on the stack.
Unlike GOTO, when a RETURN statement is reached, execution resumes
with the statement following the last executed GOSUB statement.
An unlimited number of subroutines may be used in a program.
Subroutines may also be nested. In other words, it is possible for a
subroutine to call another subroutine. Such subroutine nesting must be
restricted to no more than four levels deep (12 levels for 17Cxxx and 27
levels for 18Xxxx).

Just a thought.

Dave

HenrikOlsson
- 7th March 2007, 12:52
Hi,
I haven't seen the previous thread you mention so I'm just thinking out loud here.....hoping not to repeat what's already been covered.

When the program GOSUB's a subroutine it pushes the return adress on the top of the stack. So what if you, just before your GOTO instruction, POP the adress from stack, effectivly canceling the GOSUB?

Now, the 16F series doesn't seem to have a way to POP the stack from software but the 18F series does indeed have both a PUSH and POP command so it may be possible....

Any expert insight on this?

/Henrik Olsson.

Jerson
- 7th March 2007, 14:14
Hi Henrik

I have used this technique quite a lot in my project. What you can do is just do a goto BOOTUP instead of a return to end the gosub.

Yes, you are thinking correct. The gosub has pushed something on the stack and it is still there. So what; The bootup code will re-push another value to another location of the stack when it is called again. Remember, the stack rolls over after the 8th level (specifically the 16F917 which I use)

You are just intending to go back to bootup and forget what happened before. So, the goto will work. Even other gosubs will not know about the goto unless you RETURN more than you GOSUB.

Jerson

sougata
- 7th March 2007, 14:30
Hi,

Resetting the PIC via another pin seems technically possible. But I would like to know some example conditions which demands that a GOSUB be cancelled. I sometimes use sbroutines which may be called from other subroutines or just be executed themselve. I just use a software flag (accordingly set before a GOSUB or a GOTO) which decides how to end that routine by a return or a GOTO.

The stack pointer is not readable or writable. And three is no reference for a user initiated PUSH or POP on the mid range manual (I hope I have not skipped anything :D)

On a 18F you can push/pop it you. For reset it can be automatic when you mess up your stack, or by a RESET instruction.

Jersons technic is good as you will not be using the already pushed stack anyway and keep on pushing as if it were empty.