I get enough questions about SBasic that I
figured I ought to do a little SBasic FAQ. So here are answers to
some of the most common questions about SB:
If all you want to do is set or clear an output line, you can use something like:
pokeb PORTB, 1 ; set PB0
pokeb PORTB, 0 ; clear
These lines alter PB0, but they both have the side effect of clearing all other PORTB outputs. If you want to preserve the states of the other output lines, use something like:
pokeb PORTB, peekb(PORTB) or 1 ; set PB0
~peekb(PORTB) and $fe ; clear PB0
The first statement reads the byte at PORTB, ORs that value with a 1, then writes the result back to PORTB. The second statement reads the byte at PORTB, uses the ~ operator to invert all the bits, ANDs that value with $fe to clear PB0, then writes the result back to PORTB.
You can use a similar technique to toggle a selected bit:
pokeb PORTB, peekb(PORTB) xor 1 ; toggle PB0
This statement reverses the state of PB0,
regardless of its initial state.
When the 68hc11 receives an interrupt, the MCU saves the current state of the registers, fetchs the contents of the appropriate interrupt vector, and jumps to that address. So the key element of handling interrupts in SBasic is to ensure that the address of your interrupt routine gets stored in the correct vector address. The following example uses the real-time interrupt (RTI), as it may be the most commonly used.
Here is a typical RTI interrupt service routine (ISR):
interrupt $fff0 ; vector for RTI
if wait <> 0 ; if counter not yet 0...
wait = wait - 1 ; decrement it
pokeb tflg2, %01000000 ; rearm RTI
end ; end of the ISR
You can put this routine anywhere you want in your SBasic source file, but it makes the most sense to put it after your variable declarations but before your MAIN label. The first line in this routine tells SBasic to write the address of this code block to the vector address $fff0, which happens to be the vector address for the RTI interrupt. The POKEB statement clears the RTI interrupt flag, ensuring that the next RTI interrupt will cause control to jump back to this routine again. Finally, the END statement returns control back to the interrupted code so your program can continue where it left off.
But you aren't done yet. You need to add code in the MAIN routine that turns on the specific interrupt subsystem. For the RTI, that code looks something like this:
pokeb tflg2, %01000000 ; clear RTI interrupt flag
pokeb tmsk2, %01000000 ; allow RTI interrupts
interrupts on ; allow
The last statement above unmasks all 68hc11
maskable interrupts. It isn't enough just to turn on specific
interrupts such as the RTI. You also have to clear the
processor's I-bit, which if set masks all maskable interrupts.
Once the I-bit is cleared, the RTI interrupts should begin. If
your code writes a number to variable WAIT, it will begin to
decrement once each 4.1 msecs until it hits 0. Refer to the RTI
ISR code above to see why WAIT changes value on each RTI
The simplest way is to use the servos.bas library file included with the SBasic distribution package. This library contains working code for controlling up to four servo motors, and reduces the entire job to something like:
gosub InstallServo, TOC5
This sets up the 68hc11 timer channel TOC5 to control a servo motor wired to PA3. The code in this library is a little complicated, but worth your time to examine closely. You will learn a lot about how the 68hc11 timer subsystems work. Be sure to have a copy of the Motorola 68hc11 Reference Manual (pink book) handy.
To alter the servo's position, your code must
simply write a 16-bit value to register TOC5. The value written
will generate a servo pulse at PA3 of a unique width. The servo
will only respond to pulses with widths from about 0.5 to 1.5
msecs; these widths correspond to values from about $f400 to
$fc00, though your mileage will vary. So your code can move a
servo to a specified position by writing the appropriate value in
the above range, then waiting for the servo to complete its
That's it for this issue. If you would like more information on using SBasic, send me email at firstname.lastname@example.org and I'll do some more SBasic tips in a later issue.
Keep on keeping on...
"Technology marches on. Over you or through you, take your pick." Attributed to Stewart Brand