<<Previous |
4. PICBASIC PRO™ Basics
4.1. Identifiers
An identifier is, quite simply, a name. Identifiers are used in PBP for line labels and variable names. An identifier is any sequence of letters, digits, and underscores, although it must not start with a digit. Identifiers are not case sensitive, thus label, LABEL, and Label are all treated as equivalent. And while labels might be any number of characters in length, PBP only recognizes the first 31.
4.2. Line Labels
In order to mark statements that the program might wish to reference with
GOTO or GOSUB commands, PBP uses line labels. Unlike many older BASICs, PBP doesn't allow line numbers and doesn't require that each line be labeled. Rather, any PBP line may start with a line label, which is simply an identifier followed by a colon (:).here: Serout 0,N2400,["Hello, World!",13,10] Goto here
4.3. Variables
Variables are where temporary data is stored in a PICBASIC PRO™ program. They are created using the
VAR keyword. Variables may be bits, bytes or words. Space for each variable is automatically allocated in the microcontroller=s RAM by PBP. The format for creating a variable is as follows:Label VAR Size{.Modifiers}
Label
is any identifier, excluding keywords, as described above. Size is BIT, BYTE or WORD. Optional Modifiers add additional control over how the variable is created. Some examples of creating variable are:dog var byte cat var bit w0 var word
There are no predefined user variables in PICBASIC PRO™. For compatibility sake, two files have been provided that create the standard variables used with the BASIC Stamps:
Abs1defs.bas@ and Abs2defs.bas@. To use one of these files, add the line:Include "bs1defs.bas"
or
Include "bs2defs.bas"
near the top of the PICBASIC PRO™gram. These files contain numerous
VAR statements that create all of the BASIC Stamp variables and pin definitions.However, instead of using these "canned" files, we recommend you create your own variables using names that are meaningful to you.
The number of variables available depends on the amount of RAM on a particular device and the size of the variables and arrays. PBP reserves approximately 24 RAM locations for its own use. It may also create additional temporary variables for use in sorting out complex equations.
4.4. Aliases
VAR
can also be used to create an alias (another name) for a variable. This is most useful for accessing the innards of a variable.fido var dog ' fido is another name for dog b0 var w0.byte0 ' b0 is the first byte of word w0 b1 var w0.byte1 ' b1 is the second byte of word w0 flea var dog.0 ' flea is bit0 of dog
The variable modifiers may also be used as part of variables in a
statement:b = w0.byte0
OPTION_REG.7 = 0
Modifier |
Description |
BIT0 or 0 |
Create alias to bit 0 of byte or word |
BIT1 or 1 |
Create alias to bit 1 of byte or word |
BIT2 or 2 |
Create alias to bit 2 of byte or word |
BIT3 or 3 |
Create alias to bit 3 of byte or word |
BIT4 or 4 |
Create alias to bit 4 of byte or word |
BIT5 or 5 |
Create alias to bit 5 of byte or word |
BIT6 or 6 |
Create alias to bit 6 of byte or word |
BIT7 or 7 |
Create alias to bit 7 of byte or word |
BIT8 or 8 |
Create alias to bit 8 of word |
BIT9 or 9 |
Create alias to bit 9 of word |
BIT10 or 10 |
Create alias to bit 10 of word |
BIT11 or 11 |
Create alias to bit 11 of word |
BIT12 or 12 |
Create alias to bit 12 of word |
BIT13 or 13 |
Create alias to bit 13 of word |
BIT14 or 14 |
Create alias to bit 14 of word |
BIT15 or 15 |
Create alias to bit 15 of word |
BYTE0 or LOWBYTE |
Create alias to low byte of word |
BYTE1 or HIGHBYTE |
Create alias to high byte of word |
4.5. Arrays
Variable arrays can be created in a similar manner to variables.
VAR Size[Number of elements]Label
Label
is any identifier, excluding keywords, as described above. Size is BIT, BYTE or WORD. Number of elements is how many array locations is desired. Some examples of creating arrays are:sharks var byte[10]
fish var bit[8]
The first array location is element 0. In the
fish array defined above, the elements are numbered fish[0] to fish[7] yielding 8 elements in total.Because of the way arrays are allocated in memory, there are size limits for each type:
Size |
Maximum Number of elements |
BIT |
256 |
BYTE |
96* |
WORD |
48* |
* Processor dependent. See the section on memory allocation for more information.
Arrays must fit entirely within one RAM bank on most PICmicros. They may not span RAM banks on 14-bit or 17Cxxx devices. (Arrays may span banks on 18Cxxx devices. Byte- and word-sized arrays are only limited in length by the amount of memory.) The compiler will assure that arrays will fit in memory before successfully compiling.
4.6. Constants
Named constants may be created in a similar manner to variables. It can be more convenient to use a constant name instead of a constant number. If the number needs to be changed, it may be changed in only one place in the program; where the constant is defined. Variable data cannot be stored in a constant.
CON Constant expressionLabel
Some examples of constants are:
mice con 3
traps con mice * 1000
4.7. Symbols
SYMBOL
provides yet another method for aliasing variables and constants. It is included for BS1 compatibility. SYMBOL cannot be used to create a variable. Use VAR to create a variable.SYMBOL lion = cat ' cat was previously created using VAR SYMBOL mouse = 1 ' Same as mouse con 1
4.8. Numeric Constants
PBP allows numeric constants to be defined in the three bases: decimal, binary and hexadecimal. Binary values are defined using the prefix '
%' and hexadecimal values using the prefix '$'. Decimal values are the default and require no prefix.100 ' Decimal value 100 %100 ' Binary value for decimal 4 $100 ' Hexadecimal value for decimal 256
For ease of programming, single characters are converted to their ASCII equivalents. Character constants must be quoted using double quotes and must contain only one character (otherwise, they are string constants).
"A" ' ASCII value for decimal 65 "d" ' ASCII value for decimal 100
4.9. String Constants
PBP doesn't provide string handling capabilities, but strings can be used with some commands. A string contains one or more characters and is delimited by double quotes. No escape sequences are supported for non-ASCII characters (although most PBP commands have this handling built-in).
Lcdout "Hello" ' Output String (Short for "H","e","l","l","o")
Strings are usually treated as a list of individual character values.
4.10. Ports and Other Registers
All of the PICmicro registers, including the ports, can be accessed just like any other byte-sized variable in PICBASIC PRO™. This means that they can be read from, written to or used in equations directly:
PORTA = %01010101 ' Write value to PORTA anyvar = PORTB & $0f ' Isolate lower 4 bits of PORTB and place result in anyvar
4.11. Pins
Pins may be accessed in a number of different ways. The best way to specify a pin for an operation is to simply use its PORT name and bit number:
PORTB.1 = 1 ' Set PORTB, bit 1 to a 1
To make it easier to remember what a pin is used for, it should be assigned a name using the
VAR command. In this manner, the name may then be used in any operation:led var PORTA.0 ' Rename PORTA.0 as led High led ' Set led (PORTA.0) high
For compatibility with the BASIC Stamp, pins used in PICBASIC PRO™ Compiler commands may also be referred to by number, 0 - 15. These pins are physically mapped onto different PICmicro hardware ports dependent on how many pins the microcontroller has.
No. PICmicro Pins |
0 - 7 |
8 - 15 |
8-pin |
GPIO* |
GPIO* |
18-pin |
PORTB |
PORTA* |
28-pin (except 14C000) |
PORTB |
PORTC |
28-pin (14C000) |
PORTC |
PORTD |
40-pin |
PORTB |
PORTC |
*GPIO and PORTA do not have 8 I/O pins.
If a port does not have 8 pins, such as PORTA, only the pin numbers that exist may be used, i.e. 8 - 12. Using pin numbers 13 - 15 will have no discernable effect.
This pin number, 0 - 15, has nothing to do with the physical pin number of a PICmicro. Depending on the particular PICmicro, pin number 0 could be physical pin 6, 21 or 33, but in each case it maps to PORTB.0 (or GPIO.0 for 8-pin devices, or PORTC.0 for a PIC14C000) .
Pins may be referenced by number (0 - 15), name (e.g.
Pin0, if one of the bsdefs.bas files are included or you have defined them yourself), or full bit name (e.g. PORTA.1). Any pin or bit of the microcontroller can be accessed using the latter method.The pin names (i.e.
Pin0) are not automatically included in your program. In most cases, you would define pin names as you see fit using the VAR command:led var PORTB.3
However, two definition files have been provided to enhance BASIC Stamp compatibility. The file
Abs1defs.bas@ or Abs2defs.bas@ may be included in the PICBASIC PRO™ program to provide pin and bit names that match the BASIC Stamp names.Include "bs1defs.bas"
or
Include "bs2defs.bas"
BS1DEFS.BAS
defines Pins, B0-B13, W0-W6 and most of the other BS1 pin and variable names.BS2DEFS.BAS
defines Ins, Outs, B0-B25, W0-W12 and most of the other BS2 pin and variable names.When a PICmicro powers-up, all of the pins are set to input. To use a pin as an output, the pin or port must be set to an output or a command must be used that automatically sets a pin to an output.
To set a pin or port to an output (or input), set its TRIS register. Setting a TRIS bit to 0 makes its pin an output. Setting a TRIS bit to 1 makes its pin an input. For example:
TRISA = %00000000 ' Or TRISA = 0
sets all the PORTA pins to outputs.
TRISB = %11111111 ' Or TRISB = 255
sets all the PORTB pins to inputs.
TRISB = %11111111 ' Or TRISB = 255
Sets all the even pins on PORTC to outputs, and the odd pins to inputs. Individual bit directions may be set in the same manner.
TRISA.0 = 0
sets PORTA, pin 0 to an output. All of the other pin directions on PORTA are unchanged.
The BASIC Stamp variable names
Dirs, Dirh, Dirl and Dir0-Dir15 are not defined and should not be used with the PICBASIC PRO™ Compiler. TRIS should be used instead, but has the opposite state of Dirs.This does not work in PICBASIC PRO™:
Dir0 = 1 ' Doesn’t set pin PORTB.0 to output
Do this instead:
TRISB.0 = 0 ' Set pin PORTB.0 to output
or simply use a command that automatically sets the pin direction.
4.12. Comments
A PBP comment starts with either the
REM keyword, the single quote ('), or the semi-colon (;). All following characters on this line are ignored.Unlike many BASICs,
REM is a unique keyword and not an abbreviation for REMark. Thus, variables names may begin with REM (although REM itself is not valid).4.13. Multi-statement Lines
In order to allow more compact programs and logical grouping of related commands, PBP supports the use of the colon (
:) to separate statements placed on the same line. Thus, the following two examples are equivalent:W2 = W0 W0 = W1 W1 = W2 is the same as: W2 = W0 : W0 = W1 : W1 = W2
This does not, however, change the size of the generated code.
4.14. Line-extension Character
The maximum number of characters that may appear on one PBP line is 256. Longer statements may be extended to the next line using the line-extension character (_) at the end of each line to be continued.
Branch B0,[label0,label1,label2,_ label3,label4]
4.15. INCLUDE
Other BASIC source files may be added to a PBP program by using
INCLUDE. You may have standardized subroutines, definitions or other files that you wish to keep separate. The Stamp and serial mode definition files are examples of this. These files may be included in programs where they are necessary, but kept out of programs where they are not needed.The included file
=s source code lines are inserted into the program exactly where the INCLUDE is placed."modedefs.bas"INCLUDE
4.16. DEFINE
Some elements, like the clock oscillator frequency and the LCD pin locations, are predefined in PBP.
DEFINE allows a PBP program to change these definitions, if desired.DEFINE
may be used to change the predefined oscillator value, the DEBUG pins and baud rate and the LCD pin locations, among other things.These definitions must be in all upper case. If not, the compiler may not recognize them. No error message will be produced for DEFINEs the compiler does not recognize.
See the appropriate sections of the manual for specific information on these definitions. A complete list of DEFINEs is in Appendix B.
DEFINE OSC 4 'Oscillator speed in MHz: 3(3.58) 4 8 10 12 16 20 25 32 33 40
4.17. Math Operators
Unlike the BASIC Stamp, the PICBASIC PRO™ Compiler performs all math operations in full hierarchal order. This means that there is precedence to the operators. Multiplies and divides are performed before adds and subtracts, for example. To ensure the operations are carried out in the order you would like, use parenthesis to group the operations:
A = (B + C) * (D - E)
All math operations are unsigned and performed with 16-bit precision.
Math Operators |
Description |
+ |
Addition |
- |
Subtraction |
* |
Multiplication |
** |
Top 16 Bits of Multiplication |
*/ |
Middle 16 Bits of Multiplication |
/ |
Division |
// |
Remainder (Modulus) |
<< |
Shift Left |
>> |
Shift Right |
ABS |
Absolute Value* |
COS |
Cosine |
DCD |
2n Decode |
DIG |
Digit |
DIV 32 |
31-bit x 15-bit Divide |
MAX |
Maximum* |
MIN |
Minimum* |
NCD |
Encode |
REV |
Reverse Bits |
SIN |
Sine |
SQR |
Square Root |
& |
Bitwise AND |
| |
Bitwise OR |
^ |
Bitwise Exclusive OR |
~ |
Bitwise NOT |
&/ |
Bitwise NOT AND |
|/ |
Bitwise NOT OR |
^/ |
Bitwise NOT Exclusive OR |
*Implementation differs from BASIC Stamp.
4.17.1. Multiplication
PBP performs 16x16 multiplication. The '
*' operator returns the lower 16 bits of the 32-bit result. This is the typical multiplication found in most programming languages. The '**' operator returns the upper 16 bits of the 32-bit result. These two operators can be used in conjunction to perform 16x16 multiplication that produces 32-bit results.W1 = W0 * 1000 ' Multiply value in W0 by 1000 and place the result in W1 W2 = W0 ** 1000 ' Multiply W0 by 1000 and place the high order 16 bits (which may be 0) in W2
The
>*/= operator returns the middle 16 bits of the 32-bit result.W3 = W1 */ W0 ' Multiply W1 by W0 and place the middle 16 bits in W3
4.17.2. Division
PBP performs 16x16 division. The '
/' operator returns the 16-bit result. The '//' operator returns the remainder. This is sometimes referred to as the modulus of the number.W1 = W0 / 1000 ' Divide value in W0 by 1000 and place the result in W1 W2 = W0 // 1000 ' Divide value in W0 by 1000 and place the remainder in W2
4.17.3. Shift
The '
<<' and '>>' operators shift a value left or right, respectively, 0 to 15 times. The newly shifted-in bits are set to 0.B0 = B0 << 3 ' Shifts B0 left 3 places (same as multiply by 8) W1 = W0 >> 1 ' Shifts W0 right 1 position and places result in W1 (same as divide by 2)
4.17.4. ABS
ABS
returns the absolute value of a number. If a byte is greater than 127 (high bit set), ABS will return 256 - value. If a word is greater than 32767 (high bit set), ABS will return 65536 - value.B1 = ABS B0
4.17.5. COS
COS
returns the 8-bit cosine of a value. The result is in two=s complement form (i.e. -127 to 127). It uses a quarter-wave lookup table to find the result. Cosine starts with a value in binary radians, 0 to 255, as opposed to the usual 0 to 359 degrees.B1 = COS B0
4.17.6. DCD
DCD
returns the decoded value of a bit number. It changes a bit number (0 - 15) into a binary number with only that bit set to 1. All other bits are set to 0.B0 = DCD 2 ' Sets B0 to %00000100
4.17.7. DIG
DIG
returns the value of a decimal digit. Simply tell it the digit number (0 - 4 with 0 being the rightmost digit) you would like the value of, and voila.B0 = 123 ' Set B0 to 123 B1 = B0 DIG 1 ' Sets B1 to 2 (digit 1 of 123)4.17.8. DIV32
PBPs multiply (*) function operates as a 16-bit x 16-bit multiply yielding a 32-bit result. However, since the compiler only supports a maximum variable size of 16 bits, access to the result had to happen in 2 steps: c = b * a returns the lower 16 bits of the multiply while d = b ** a returns the upper 16 bits. There was no way to access the 32-bit result as a unit.
In many cases it is desirable to be able to divide the entire 32-bit result of the multiply by a 16-bit number for averaging or scaling. A new function has been added for this purpose: DIV32. DIV32 is actually limited to dividing a 31-bit unsigned integer (max 2147483647) by a 15-bit unsigned integer (max 32767). This should suffice in most circumstances.
As the compiler only allows a maximum variable size of 16 bits, DIV32 relies that a multiply was just performed and that the internal compiler variables still contain the 32-bit result of the multiply. No other operation may occur between the multiply and the DIV32 or the internal variables may be altered, destroying the 32-bit multiplication result.
This means, among other things, that ON INTERRUPT must be DISABLEd from before the multiply until after the DIV32. If ON INTERRUPT is not used, there is no need to add DISABLE to the program. Interrupts in assembler should have no effect on the internal variables so they may be used without regard to DIV32.
The following code fragment shows the operation of DIV32:
a Var Word b Var Word c Var Word dummy Var Word b = 500 c = 1000 Disable ' Necessary if On Interrupt used dummy = b * c ' Could also use ** or */ a = DIV32 100 Enable ' Necessary if On Interrupt used
This program assigns b the value 500 and c the value 1000. When multiplied together, the result would be 500000. This number exceeds the 16-bit word size of a variable (65535). So the dummy variable contains only the lower 16 bits of the result. In any case, it is not used by the DIV32 function. DIV32 uses variables internal to the compiler as the operands.
In this example, DIV32 divides the 32-bit result of the multiplication b * c by 100 and stores the result of this division, 5000, in the word-sized variable a.
4.17.9. MAX and MIN
MAX
and MIN returns the maximum and minimum, respectively, of two numbers. It is usually used to limit numbers to a value.B1 = B0 MAX 100 ' Set B1 to the larger of B0 and 100 (B1 will be between 100 & 255) B1 = B0 MIN 100 ' Set B1 to the smaller of B0 and 100 (B1 can’t be bigger than 100)
4.17.10. NCD
NCD
returns the priority encoded bit number (1 - 16) of a value. It is used to find the highest bit set in a value. It returns 0 if no bit is set.B0 = NCD %01001000 ' Sets B0 to 7
4.17.11. REV
REV
reverses the order of the lowest bits in a value. The number of bits to be reversed is from 1 to 16.B0 = %10101100 REV 4 ' Sets B0 to %10100011
4.17.12. SIN
SIN
returns the 8-bit sine of a value. The result is in two=s complement form (i.e. -127 to 127). It uses a quarter-wave lookup table to find the result. Sine starts with a value in binary radians, 0 to 255, as opposed to the usual 0 to 359 degrees.B1 = SIN B0
4.17.13. SQR
SQR
returns the square root of a value. Since PICBASIC PRO™ only works with integers, the result will always be an 8-bit integer no larger than the actual result.B0 = SQR W1 ' Sets B0 to square root of W1
4.17.14. Bitwise Operators
Bitwise operators act on each bit of a value in boolean fashion. They can be used to isolate bits or add bits into a value.
B0 = B0 & %00000001 ' Isolate bit 0 of B0 B0 = B0 | %00000001 ' Set bit 0 of B0 B0 = B0 ^ %00000001 ' Reverse state of bit 0 of B0
4.18. Comparison Operators
Comparison operators are used in
IF..THEN statements to compare one expression with another. These comparisons are unsigned. They cannot be used to check if a number is less than 0.
Comparison Operator |
Description |
= or == |
Equal |
<> or != |
Not Equal |
< |
Less Than |
> |
Greater Than |
<= |
Less Than or Equal |
>= |
Greater Than or Equal |
If i > 10 Then loop
4.19. Logical Operators
Logical operators differ from bitwise operations. They yield a true/false result from their operation. Values of 0 are treated as false. Any other value is treated as true. They are mostly used in conjunction with the comparison operators in an
IF..THEN statement. The operators supported are:
Logical Operator |
Description |
AND or && |
Logical AND |
OR or || |
Logical OR |
XOR or ^^ |
Logical Exclusive OR |
NOT AND |
Logical NAND |
NOT OR |
Logical NOR |
NOT XOR |
Logical NXOR |
If (A == big) AND (B > mean) Then run
Be sure to use parenthesis to tell PBP the exact order you want the operations to be performed.
<<Previous |