7. Other PICBASIC PRO™ Considerations

7.1. How Fast is Fast Enough?

By default, the PICBASIC PRO™ Compiler generates programs intended to be run on a PICmicro with a 4MHz crystal or ceramic resonator. All of the time-sensitive instructions assume a 1 microsecond instruction time for their delays. This allows a PAUSE 1000 1000, for example, to wait 1 second and the SERIN and SEROUT command=s baud rates to be accurate.

There are times, however, when it would be useful to run the PICmicro at a frequency other than 4MHz. Even though the compiled programs move along at a pretty good clip, it might be nice to run them even faster. Or maybe it is desirable to do serial input or output at 19,200 baud rather than the current top speed of 9600 baud.

PICBASIC PRO™ programs may be run at clock frequencies other than 4MHz in a couple of different ways. The first is to simply use an oscillator other than 4MHz and don=t tell PBP. This can be a useful technique if you pay attention to what happens to the time dependent instructions.

If you wish to run the serial bus at 19,200 as described above, you would simply clock the microcontroller with an 8MHz crystal rather than a 4MHz crystal. This, in effect, makes everything run twice as fast, including the SERIN and SEROUT commands. If you tell SERIN or SEROUT to run at 9600 baud, the doubling of the crystal speed will double the actual baud rate to 19,200 baud.

However, keep in mind commands such as PAUSE and SOUND will also run twice as fast. The PAUSE 1000 1000 mentioned above would only wait .5 seconds with an 8MHz crystal before allowing program execution to continue.

The other technique is to use a different oscillator frequency and tell PBP of your intentions. This is done through the use of a DEFINE. DEFINE, as demonstrated in the LCDOUT command in a previous section, is used to tell PBP to use something other than its defaults.

Normally, PBP defaults to using a 4MHz oscillator. Adding the statement:


near the beginning of the PICBASIC PRO™ program tells PBP to assume an 8MHz oscillator will be used instead. The acceptable oscillator definitions are:


Minimum delay

3 (3.58)
























* PIC17Cxxx and PIC18Cxxx only.
** PIC18Cxxx only.

Telling PBP the oscillator frequency allows it to compensate and produce the correct timing for COUNT, DEBUG, DTMFOUT, FREQOUT, HPWM, HSERIN, HSEROUT, I2CREAD, I2CWRITE, LCDOUT, OWIN, OWOUT, PAUSE, PAUSEUS, SERIN, SERIN2, SEROUT, SEROUT2, SHIFTIN, SHIFTOUT, SOUND, XIN and XOUT.

Changing the oscillator frequency may also be used to enhance the resolution of the PULSIN, PULSOUT and RCTIME instructions. At 4MHz these instructions operate with a 10 microsecond resolution. If a 20MHz crystal is used, the resolution is increased 5 times to 2 microseconds. There is a tradeoff however. The pulse width is still measured to a 16-bit word variable. With a 2 microsecond resolution, the maximum measurable pulse width would be 131,070 microseconds.

Going the other direction and running with a 32.768KHz oscillator is problematic. It may be desirable to attempt this for reduced power consumption reasons and it will work to some extent. The SERIN and SEROUT commands will be unusable and the Watchdog Timer may cause the program to restart periodically. Experiment to find out if your particular application is possible at this clock speed. It doesn=t hurt to try.

7.2. Configuration Settings

As mentioned earlier, the default configuration settings for a particular device is set in the .INC file with the same name as the device, e.g. 16F84.INC. These settings can be changed at the time the device is physically programmed.

The oscillator defaults to XT on most devices. This is the setting for the default 4MHz oscillator. If a faster oscillator is used, this setting must be changed to HS. Devices with internal oscillators default to INTRC.

The Watchdog Timer is enabled by PBP. It is used, along with the TMR0 prescaler, to support the NAP and SLEEP instructions. If neither of the instructions are used in a program, the Watchdog Timer may be disabled and the prescaler used for something else.

Code Protect defaults to off but may be set to on when the device is physically programmed. Do not code protect a windowed device.

See the Microchip data sheet for the particular device for the configuration data specific to that part.

7.3. RAM Usage

In general it is not necessary to know how RAM is allocated by PBP in the microcontroller. PBP takes care of all the details so the programmer doesn=t have to. However there are times when this knowledge could be useful.

Variables are stored in the PICmicro=s RAM registers. The first available RAM location is $0C for the PIC16F84 and some of the smaller PICmicros, and $20 for the PIC16C74 and other larger PICmicros. Refer to the Microchip PICmicro data books for the actual location of the start of the RAM registers for a given microcontroller.

The variables are assigned to RAM sequentially in a particular order. The order is word arrays first (if any), followed by byte and bit arrays. Then space is allocated for words, bytes and finally individual bits. Bits are packed into bytes as possible. This order makes the best use of available RAM. (For PIC18Cxxx devices, arrays are allocated last.)

Arrays must fit into a single bank on most PICmicros. They may not cross a bank boundary. This effectively limits the length of an individual array. See the previous section on arrays for these limits.

You can suggest to PBP a particular bank to place the variable in:


If specific bank requests are made, those are handled first. If there is not enough room in a requested bank, the first available space is used and a warning is issued.

You can even set specific addresses for variables. In most cases, it is better to let PBP handle the memory mapping for you. But in some cases, such as storage of the W register in an interrupt handler, it is necessary to define a fixed address. This may be done in a similar manner to bank selection:

w_store VAR BYTE $20

Several system variables, using about 24 bytes of RAM, are automatically allocated by the compiler for use by library subroutines. These variables are allocated in the file PBPPIC14.RAM and must be in bank 0 (or bank A on 18Cxxx devices).

User variables are prepended with an underscore (_) while system variables have no underscore so that they do not interfere with each other.


BASIC Stamp variables B0 - B25 and W0 - W12 are not automatically allocated. It is best to create your own variables using the VAR instruction. However if you want these variables to be created for you, simply include the appropriate file, BS1DEFS.BAS or BS2DEFS.BAS, at the beginning of the PICBASIC PRO™ program. These variables allocate space separate and apart from any other variables you may later create. This is different than the BS2 where using the canned variables and user created variables can get you into hot water.

Additional temporary variables may be generated automatically by the compiler to help it sort out equations. A listing of these variables, as well as the entire memory map, may be seen in the generated .ASM or .LST file.

If there is not enough RAM memory available for the variables, an unable to fit variable in memory error message will be issued.

7.4. Reserved Words

Reserved words are simply that - words that are reserved for use by the compiler and may not be defined as either variable names or labels. These reserved words may be the names of commands, pseudo-ops, variable types or the names of the PICmicro registers.

The pseudo-ops, variable types and commands keywords are listed in their appropriate sections. The names of the PICmicro registers are defined in the file PIC14EXT.BAS. If the files BS1DEFS.BAS, BS2DEFS.BAS or MODEDEFS.BAS are included, the definitions inside essentially become reserved words and may not be redefined.

7.5. Life After 2K

Yes, there is life after 2K using the PICBASIC PRO™ Compiler.

PICmicro MCUs have a segmented code space. PICmicro MCU instructions in 14-bit core parts such as Call and Goto only have enough bits within them to address 2K of program space. To get to code outside the 2K boundary, the PCLATH register must be set before each Call or Goto.

PBP automatically sets these PCLATH bits for you. There are a few restrictions imposed, however. The PICBASIC PRO™ library must fit entirely into page 0 of code space. Normally this is not an issue as the library is the first thing in a PICBASIC PRO™ program and the entire library is smaller than 2K. However, attention must be payed to this issue if additional libraries are used.

Assembly language interrupt handlers must also fit into page 0 of code space. Putting them at the beginning of the PICBASIC PRO™ program should make this work. See the upcoming section on assembly language for more information.

The addition of instructions to set the PCLATH bits does add overhead to the produced code. PBP will set the PCLATH bits before any Call or Goto instruction on 12-bit core PICmicro MCUs with more than 512 words of code space, 14-bit core devices with more than 2K of code space and PIC17Cxxx devices with more than 8K of code space.

There are specific PICBASIC PRO™ instructions to assist with the 2K issues.

BRANCHL was created to allow branching to labels that may be on the other side of a 2K boundary. If the PICmicro has 2K or less of program space, BRANCH should be used as it takes up less space than BRANCHL. If the microcontroller has more than 2K of code space, and you cannot be certain that BRANCH will always act within the same page, use BRANCHL.

The assembler may issue a warning that a page boundary has been crossed. This is normal and is there to suggest that you check for any BRANCHes that may cross a page boundary.

7.6.  12-Bit Core Considerations 

Because of the architecture of the 12-bit core PICmicro MCUs, programs compiled for them by PBP will, in general, be larger and slower that programs compiled for the other PICmicro MCU families. In many cases, choosing a device from one of these other families will be more appropriate. However, many useful programs can be written and compiled for the 12-bit core devices.

The two main programming limitations that will most likely occur are running out of RAM memory for variables and running past the first 256 word limit for the library routines. These limitations have made it necessary to eliminate some compiler commands and modify the operation of some others.

The compiler for 12-bit core PICmicro MCUs uses between 20 and 22 bytes of RAM for its internal variables, with additional RAM used for any necessary temporary variables. This RAM allocation includes a 4 level software stack so that the BASIC program can still nest GOSUBs up to 4 levels deep. Some PICmicro MCU devices only have 24 or 25 bytes of RAM so there is very little space for user variables on those devices. If the Unable to Fit Variable error message occurs during compilation, choose another PICmicro MCU with more general purpose RAM.

12-bit core PICmicro MCUs can call only into the first half (256 words) of a code page. Since the compiler's library routines are all accessed by calls, they must reside entirely in the first 256 words of the PICmicro MCU code space. Many library routines, such as I2CREAD, are fairly large. It may only take a few routines to overrun the first 256 words of code space. If it is necessary to use more library routines that will fit into the first half of the first code page, it will be necessary to move to a 14- or 16-bit core PICmicro MCU instead of the 12-bit core device.