The PIC Source Book: Introduction

This book is a collection of useful program routines and examples written in Parallax assembly language for the PIC 16C5x series of microcontrollers. With minor changes, these routines may be adapted to the entire PIC 16Cxx series.

The routines are based on the instruction set of the BASIC Stamp ®, a PIC-based single-board microcontroller. A PIC on the Stamp circuit board is programmed with a BASIC interpreter. The PIC reads instructions and data stored in an EEPROM and interprets them to execute control programs.

The Stamp's version of BASIC, known as PBASIC, includes high-level instructions for common control tasks, such as serially sending and receiving data, debouncing pushbuttons, measuring and generating pulses, reading a potentiometer, and producing sound. The routines in this book are clones of those PBASIC commands that (in most cases) function the same way.

There are three audiences for this book:

  1. BASIC Stamp users who want to program the PIC directly in Parallax assembly language, but don't want to leave familiar programming methods behind.
  2. PIC programmers who are looking for a cookbook of routines to speed program development.
  3. PIC programmers who see advantages in prototyping with the Stamp interpreter before moving to the PIC for the final product.

Whichever group you belong to, there are a few prerequisites to using this book effectively. You should have the Microchip and Parallax literature on the PIC hardware and not be afraid to use it. This book is not padded with the manufacturers' data sheets and instructions.

You should be comfortable with the terminology of digital logic and microcontrollers. I'm not going to be shy about using standard abbreviations (such as EEPROM, mA, µs) or computer-science terms (such as bit, byte, loop, hex, binary, AND, OR, XOR). You should also know a little BASIC, since most program structure is explained in terms of PBASIC. Finally, you should have the Parallax assembler software and manuals. You may use programming hardware from other vendors, but the Parallax assembler is required to use these routines.

This book is not a disassembly of the PBASIC interpreter. That's proprietary to Parallax, who would be crazy to give it away. Besides, it includes overhead code to make the language work properly, and upon which each of the commands depends. This would limit the usefulness of a disassembly as a toolkit of standalone routines.

Differences from PBASIC.

These routines were developed by examining what each of the PBASIC instructions does, and then writing assembly code to duplicate its function. In some cases, functionality has been changed slightly to better suit the needs of assembly-language programmers.

Manipulation of the Data-Direction Register.

Some of PBASIC's I/O instructions automatically change a pin's data direction when they execute and then restore it when they are done. The PBASIC environment permits this by keeping a copy of the PIC's tristate (TRIS) register in normal read/write memory. The routines in this book do not work that way. Comments tell you how TRIS should be set up, but the routines do not modify it directly. This avoids causing mysterious bugs as a result of improper TRIS bookkeeping outside the routines. It also keeps the routines small, since many programs do not require any TRIS trickery.

Pin and Port Independence (PPI).

This is one of the great features of the BASIC Stamp--the ability to apply any I/O command to any pin of the Stamp's single I/O port. This goes hand-in-hand with the TRIS manipulations discussed above. All of the I/O routines in this book follow this convention by letting you specify which pin and port to use. Because they don't modify TRIS, it is your program's responsibility to set the port pins to input or output as appropriate.

Many PIC applications use a particular I/O pin for only one or two purposes, and can do without the overhead required to implement pin and port independence (PPI). Although most of the program listings in the book use PPI techniques, the accompanying disk contains non-PPI versions of some of the longer I/O routines.

Merging Routines.

To use the routines presented here, you'll need to merge them, either with each other, or with your own code. This is a straightforward cut-and-paste operation, but can require a little thought and planning. Here are a few hints:

Structure of the Routines.

Most of the code presented in this book is in the form of callable subroutines. While this makes it easy to incorporate the routines into your PIC programs, it also makes it likely that you'll run into two limitations of the PIC architecture; restriction of call destinations to the first half of program-memory pages, and the two-level stack.

When the PIC executes a call, it clears bit 8 of the program counter. This means that if you attempt to call code stored at address 256, you'll end up at address 0 instead. The Parallax assembler won't allow you to make this error; it will halt assembly and supply the line number of the offending call.

 If you use more than a few of these routines in your program, you will very quickly fill the lower 256 words of a program-memory page. What can you do if you run out of lower-half-page code space?

Start by examining the routines you're using and seeing which can be converted to straight-line code. That means inserting them into the body of your program where the call would normally be. Remove any returns (ret) and replace them with jumps (jmp) to appropriate points in your code.

Also, examine the routines and try to strip out code that's not required for your purposes. For example, some of these routines start out by converting timing values to their two's complement. You could save overhead by precomputing these values or consolidating the code that does the conversion.

One last technique is "call forwarding." Put the subroutine label and a jump (jmp) instruction in the lower half of the page. Locate the real guts of the routine, complete with the return (ret) in the upper half of the page. Calling the routine sends program execution to the jmp instruction, which redirects it to the actual subroutine, located elsewhere. This can save your bacon when you need one more subroutine.
 
 

Using this Book with Non-Parallax Tools.

I feel that Parallax assembly language is clearer and more productive than the original Microchip dialect. That's why I use it in my programming, and why I used it to write this book. However, many of you have other PIC tools--most notably the PICStart 16B from Microchip. You can use the Parallax assembler PASM to assemble code for use with these tools. Just add the switch /S after the file name. This suppresses the generation of Parallax-specific configurat ion data (device type, wdt, oscillator, and code-protection settings). PICStart doesn't accept this data. To assemble Serin for a non-Parallax programmer, you'd type:

PASM SERIN /S

If you forget to use the /S, you'll get an address-out-of-range message from your programming software. If you use the /S switch and still get an error message, check the device type in the assembly-language source listing. It may be set for a PIC with more program memory than the one you're programming. For example, the device directive says "16C56" when you are programming a 16C54. If that's the case, evaluate the program to determine whether it will work in a '54. If it will, change the device directive, reassemble the code, and try again.

See: