start. The only caveat is this: Due to the limit of internal variables used by SX/B operations, we cannot multiply a word
variable by itself and return the result to that same variable.
The following line of code will generate a compiler error:
tmpW1 = tmpW1 * tmpW1
We can use the other operators here ( +, -, / ), just not
operators that involve multiplication ( *, */, and ** ).
Most of the SX/B instructions have been upgraded to
work with Word variables, and a new variant of the DATA
directive, called WDATA lets us store Word values for use
with READ. The use of 16-bit values extends to I/O ports,
as well. In SX/B 1.5x, there are three 16-bit pseudo ports:
RBC, RCD, and RDE; the last two only apply to the
SX45/52.
Here’s a simple demo that shows how we can use the
RBC port on an SX28:
Start:
TRIS_B = %00000000
TRIS_C = %00000000
RBC = %00000000_00000001
Main:
DO
DELAY 75
RBC = RBC << 1
LOOP UNTIL RBC = %10000000_00000000
DO
DELAY 75
RBC = RBC >> 1
LOOP UNTIL RBC = %00000000_00000001
GOTO Main
The program starts by making the RB and RC ports
outputs — we have to do it this way because there is no
TRIS_RBC port. The RBC port gets initialized and falls into
a loop that simply ping-pongs the lit LED back and forth.
Note the use of the underscore character in the comparison
statement to make visualization of the 16-bit value easier.
Since this program uses a subroutine called DELAY, and
we might want to do delays with 16-bit values, let’s look at
the construction of subroutines in SX/B 1.5x.
For DELAY, we’ll use the following declaration:
DELAY
SUB
1, 2
This will let us pass a one- or two-byte value to DELAY.
Here’s the actual subroutine code:
‘ Use: DELAY ms
‘ — ‘ms’ is delay in milliseconds, 0 - 65535
DELAY:
IF __PARAMCNT = 1 THEN
tmpW1 = __PARAM1
ELSE
tmpW1 = __WPARAM12
ENDIF
PAUSE tmpW1
RETURN
The construct of this subroutine is useful in many
other situations as it allows us to pass bytes or words to
the same subroutine. When we pass a byte, __PARAMCNT
(internal variable) will be set to one by the compiler and
the parameter is passed in __PARAM1. When we pass a
word, __PARAMCNT will be set to two and the value
passed in __WPARAM12. Of course, we’ll use a
word-sized variable in the subroutine so that we can
handle anything passed to it.
FUNCTIONAL SUBROUTINES
With the addition of 16-bit variables, a mechanism
needs to be developed that would enable Word values to
be returned from a subroutine; this is accomplished with
the FUNC definition. This lets us define a function that can
return up to four bytes (two words).
FUNC differs from SUB in that we will first specify how
many bytes are to be returned, then the minimum and
maximum parameter count used by the subroutine code for
the function. Let’s say that we wanted a function that would
return a 32-bit product from two numbers — can we do it?
Yes, of course! We don’t have 32-bit values in SX/B, so we
have to handle the words separately. Let’s start with the
function definition:
MULT32
FUNC
4, 2, 4
This definition says that the function, MULT32, will
return four bytes, and that the caller must pass between two
and four bytes to it. This means that we could return the
product of two bytes, a word and a byte, or two words.
Note that the second option — multiply a word and a byte
— can create some trickery for our subroutine construction,
so we must make a decision about the order that values are
passed. Let’s decide that we will pass the word value first,
then the byte. Here’s the code for that function:
MULT32:
IF __PARAMCNT = 2 THEN
tmpW1 = __PARAM1
tmpW2 = __PARAM2
ENDIF
IF __PARAMCNT = 3 THEN
tmpW1 = __WPARAM12
tmpW2 = __PARAM3
ENDIF
IF __PARAMCNT = 4 THEN
tmpW1 = __WPARAM12
tmpW2 = __WPARAM34
ENDIF
tmpW3 = tmpW1 ** tmpW2
tmpW2 = tmpW1 * tmpW2
RETURN tmpW2, tmpW3
As with the DELAY routine we did earlier, this code
uses the __PARAMCNT variable to determine what is being
passed and how to collect the parameters from the caller.
The second choice, when __PARAMCNT is three, assumed
that the first value passed is the word and the second is the
byte. With the parameters collected, the rest is easy; the **
September 2006 13