A subroutine can be called any number of times. There can be many subroutines, each performing a different function.
In the code you call the subroutine by using a 'Gosub' command. The pic will remember the position the call was made from and jump to the routine named 'Label:'. The colon after the name Label indicate to the program where the subroutine routine starts.
In the program it will look like this
Label:
code...
code...
Return
code...
code...
Return
Main:
code...
code...
Gosub Label ' The code will jump to the routine named Label
code... ' And return to execute this line next
Goto Main ' redo again...
code...
code...
Gosub Label ' The code will jump to the routine named Label
code... ' And return to execute this line next
Goto Main ' redo again...
To remember the position where a call was made from, the pic uses what is called a stack. A stack is made up of some special registers where addresses are stored. Imagine a stack of dinner plates where plates may be added or removed. Each dinner plate holds the address where the program should return when it is finished with the gosub. The top plate must always be removed before the next one can be used.
It works like this: Each time a call is made, the current program counter is added to the stack.The stored number is called a pointer to the program counter. Each time the code encounters a 'Return', one address position is removed from the stack and the program counter uses it to go back to where the GOSUB was called. The pointer on the stack now points to the previous last position.
The 16 PICs have an 8 high stack register while the 18 PICs have a 31 high stack, which means you can call up to 7 deep GOSUBs for a 16 PIC or 31 deep GOSUBs with an 18 PIC, but don't push your luck with it, if the stack overflows the pic will reset and you won't know why. The same will happen if you do a call to a subroutine and use a 'Goto' to exit the routine instead of a 'Return'. The stack gets added and added to until it overflows. This can easily create the impression that the pic is not running or that it is 'hanging up' (doing nothing).
A Return doesn't have to be at the end of a subroutine
Label:
code...
code...
If A = 1 then Return
code...
Return
code...
code...
If A = 1 then Return
code...
Return
This is an example of what it looks like
Main:
code...
Gosub Buzzer ' This call will jump to the routine named Buzzer
code... ' And return to execute this line next
code...
Gosub Label ' The code will jump to the routine named Label
code... ' And return to execute this line next
Goto Main ' redo again...
Label:
code...
code...
If A = 1 then Return
code...
Return
Buzzer:
code...
code...
code...
code...
Return
End
code...
Gosub Buzzer ' This call will jump to the routine named Buzzer
code... ' And return to execute this line next
code...
Gosub Label ' The code will jump to the routine named Label
code... ' And return to execute this line next
Goto Main ' redo again...
Label:
code...
code...
If A = 1 then Return
code...
Return
Buzzer:
code...
code...
code...
code...
Return
End



Menu
Recent Articles


Using PDS with SPI GLCD based on ST7565R Controller
Graphic LCDs based on the ST7565 are cheaper then GLCDs with other controllers. SPI requires only four pins. If the circuit