Prerequisites:
Equipment:
Objective:
Introduction:
Objects are organized into code building blocks called Methods.
In Spin, method names can be used to pass program control and optionally parameter values from one method to another.
When one method uses another method’s name to pass it program control, it’s called a method call.
When the called Method runs out of commands, it automatically returns program control and a result value to the line of code in the Method that called it.
Depending on how a Method is written, it may also receive one or more parameter values when it gets called.
Common uses for parameter values include configuration, defining the method’s behavior, and input values for calculations.
Methods can also be launched into separate Cogs so that their commands get processed in parallel with commands in other Methods.
The Spin language has commands for launching Methods into Cogs, identifying Cogs, and stopping Cogs.
When Spin Methods are launched into Cogs, Global variable arrays have to be declared to allocate memory for the methods to store return addresses, return values, parameters, and values used in calculations.
This memory is commonly referred to as a as stack space.
Following projects will demonstrate techniques for writing methods, calling methods, passing parameters to methods, and returning values from methods.
They also demonstrate using method calls in commands that launch instances of methods into separate Cogs, along with an overview of estimating how much stack space will be required for one or more Spin Methods that get executed by a given Cog.
To control the Output on Port P26 we will use the circuit in Figure 3-7a or in Figure 3-7b.
'' AnotherBlinkerMRX.spin PUB Blink | port, rate, reps port := 26 ' assign LED port rate := clkfreq/3 ' assign rate = 3Hz reps := 19 ' assign reps (repetitions) dira[port]~~ ' Set port to OUTPUT outa[port]~ ' Set port LO repeat reps * 2 ' Define loop repetitions waitcnt(rate/2 + cnt) ' Wait for 1/2 of cycle !outa[port] ' Toggle port
Above Object (AnotherBlinkerMRX.spin) makes LED on Port P26 blink 19 times at 3 Hz frequency, the output to P26 is basically a "square wave" at 3 Hz with 50% duty cycle. Run the program to verify that if functions properly.
If you are using QSB run 4.3-1_AnotherBlinkerMRX-QSB.spin instead, which makes LED on Port P16 blink.
Now we add another Public Method that waits for push-button press on P10 and then calls the above PUB Blink Method.
To read the Input of P10 we will use the circuit in Figure 3-10.
We will also use CON block to define the Ports for Monitor LED (ledA) on P27 and input push-button (button) on P10.
This added method is PUB Main.
'' CallBlinkMRX.spin CON ledA = 27 ' assign port for Monitor LED button = 10 ' assign port for push button PUB Main repeat outa[ledA] := dira[ledA] := 1 ' Set [ledA] to OUTPUT HI repeat until ina[button] ' Wait until [button] is pressed outa[ledA] := 0 ' Set [ledA] LO Blink ' Call Blink method waitcnt(clkfreq/2*3 + cnt) ' Wait before repeating loop ' 1.5 seconds PUB Blink | port, rate, reps ' Define parameters used in Blink port := 26 ' assign port for ledB rate := clkfreq/3 ' assign rate (number of clock ticks) reps := 9 ' assign reps (repetitions) dira[port]~~ ' Set [port] to output outa[port]~ ' Set [port] LO repeat reps * 2 ' Set loop to number of repetitions (reps * 2) waitcnt(rate/2 + cnt) ' Wait for rate/2 !outa[port] ' Toggle [port]
This Application now has CON block and two PUB Methods.
The first PUB Main calls the PUB Blink after the condition in the repeat loop is satisfied, that is whenever the push-button on Port P10 is pressed.
Once the PUB Blink Method executes, the program control is returned to the PUB Main Method's next statement: waitcnt(clkfreq/2*3 + cnt)
After the 1.5 second wait delay the program loops back to the Start of the repeat command.
If you are using QSB run 4.3-2_CallBlinkMRX.spin instead.
On QSB the Ports are P17 for LED-A, touch pad is P1 and the LED-B is P16.
Now we add a parameter transfer from the first object that calls the Blink Method. Blink (ledB, rateC, repsC) and we also need to change the PUB Blink | port, rate, reps to: PUB Blink (port, rate, reps), this indicates that those parameters will be transferred into this Method in the method call.
'' CallBlinkMRX2.spin CON _clkmode = xtal1 + pll16x ' System clock → 80 MHz _xinfreq = 5_000_000 ledA = 26 ' assign port for Monitor LED button = 10 ' assign port for push button ledB = 27 ' assign port for ledB rateC = (80_000_000/3) ' assign rate Constant '(number of clock ticks) repsC = 9 ' assign reps Constant (repetitions) PUB Main repeat outa[ledA] := dira[ledA] := 1 ' Set [ledA] to OUTPUT HI repeat until ina[button] ' Wait until [button] is pressed outa[ledA] := 0 ' Set [ledA] LO Blink (ledB, rateC, repsC) ' Call Blink method waitcnt(clkfreq/2*3 + cnt) ' Wait before repeating loop 1.5 seconds PUB Blink (port, rate, reps) ' Define parameters used in Blink dira[port]~~ ' Set [port] to output outa[port]~ ' Set [port] LO repeat reps * 2 'Set loop to number of repetitions (reps * 2) waitcnt(rate/2 + cnt) ' Wait for rate/2 !outa[port] ' Toggle [port]
If you are using QSB run 4.3-3_CallBlinkMRX2.spin instead.
On QSB the Ports are P16 for LED-A, touch pad is P0 and the LED-B is P17.
Now we are ready to "separate" the PUB Blink Method from the Application into an independent Object. We will name it: BlinkMRXmethod.spin
'' BlinkMRXmethod.spin PUB Blink (port, rate, reps) ' Define parameters used in Blink dira[port]~~ ' Set [port] to output outa[port]~ ' Set [port] LO repeat reps * 2 'Set loop to number of repetitions (reps * 2) waitcnt(rate/2 + cnt) ' Wait for rate/2 !outa[port] ' Toggle [port]
Now we make few changes in the original CallBlinkMRX.spin Application that contained the two PUB Methods and we will make this new Application call this now separate Object.
Once compiled the functionality of the new CallBlinkMRXmethod.spin Application will be the same.
So that the application would function properly we need to define the Propeller chip's clock frequency and the assign the proper number of ticks to the [rate] in CON block, this is because we can not use clkfreq in the CON definition.
We also need to assign an alias to the called object, in this case we will refer to the BlinkMRXmethod.spin with alias of Blinker .
The OBJ block is used for this alias definition assignment:
OBJ Blinker : "BlinkMRXmethod"
Note that in the definition the .spin is omitted.
Important !
The called Object (BlinkMRXmethod.spin) MUST be saved in the same computer file folder where the Application that calls it (CallBlinkMRXmethod.spin) is also saved.
If both Objects are not in the same computer file folder, an error will be generated during Compile.
'' CallBlinkMRXmethod.spin CON _clkmode = xtal1 + pll16x ' System clock → 80 MHz _xinfreq = 5_000_000 ledA = 27 ' assign port for Monitor LED button = 10 ' assign port for push button ledB = 26 ' assign port for ledB rateC = (80_000_000/3) ' assign rate constant ' (number of clock ticks) 3Hz repsC = 9 ' assign reps constant (repetitions) OBJ Blinker : "BlinkMRXmethod" ' assign alias to called object PUB Main repeat outa[ledA] := dira[ledA] := 1 ' Set [ledA] to OUTPUT HI repeat until ina[button] ' Wait until [button] is pressed outa[ledA] := 0 ' Set [ledA] LO Blinker.Blink(ledB, rateC, repsC) ' Call Blink method in Blinker alias waitcnt(clkfreq/2*3 + cnt) ' Wait before repeating loop 1.5 seconds
Run the CallBlinkMRXmethod.spin application to verify that if functions properly.
In the top right pane of the Propeller Tool you should see how the two Objects are nested:
Currently this page is still under development, so please check back periodically for new links to pages as we add them to this list.
Click the link in the list below to navigate to a detailed webpage about the listed subject.
Parallax Propeller Book - Table of Content