When I first heard about the PIC chip, I found a lot of the terminology surrounding the chip to be confusing. It took me a little bit of learning and digging to determine what the heck everyone was talking about. After understanding the hoopla, I found myself very impressed by the PIC series of microcontrollers. In this article, I will try to explain the basics of the chip, and to explain some of the odd terminology used in conjunction with the PIC.
The PIC series of microcontrollers are a product of the Microchip Technology. Microchip is a company that produces microcontrollers, special memory chips, and a host of other really cool products. There are a couple dozen variations on the PIC series of microcontrollers. Common among most of them are single chip operation, availability in One Time Programmable (OTP) packages, and the same instruction set. The basic architecture is the same across the family.
There are two really interesting architecture decisions that were made by Microchip. First is the use of a RISC instruction set, and the other is the Harvard architecture.
RISC stands for Reduced Instruction Set Computer. This means that the instruction set that the chip supports is small, lean, and mean. RISC architectures allow for a useful set of instructions that are typically executed in a single clock. A CISC (Complex Instruction Set Computer) architecture that has much more powerful instructions, but many instructions take several clocks to execute. The 68HC11, for example, is a CISC architecture (well, comparatively speaking anyway!). Some of the HC11 instructions take as many as 5 clocks to execute. The RISC instruction set is a bare minimum set of instructions required to make a decent program work. In fact, it turns out that a decent sized program will typically use ALL of the instructions, save one of the special purpose instructions. Contrast that to the 68HC11 or x86 chips where you would be lucky to use half.
Another interesting feature of the PIC chips is the use of the Harvard architecture. Most computers use something called the von Neumann architecture, where data and program memory is mapped into the same address space. The 68HC11, the 80486, Pentium, and most other machines use this architecture. The Harvard architecture uses a different scheme were the program memory and data memory are not shared, and indeed are even on a seperate bus. This allows the program to be fetched and executed concurrently with data. The Harvard architecture allows for a cleaner pipelining of instructions since there is no contention in fetching data vs program.
|It can be hard to describe a chip in general terms,
so I have picked out a particular example to go on. The
PIC16C84 is a 18 pin microcontroller that has 1k of
EEPROM program space, 36 bytes of RAM, and 64 bytes of
EEPROM Data. It has a few other features, such as a
timer, watchdog timer, and 13 pins of I/O.
Programming the PIC chips requires a low cost programmer that connects to your serial port. The 16C8X family has 1k of onboard EEPROM for program space.
Block Diagram of the PIC16C8X
By looking at the block diagram above, you can see several interesting features. First, note the seperate Program Bus and Data Bus. Thats the Harvard architecture. Another very interesting point is that the program bus is 14 bits wide! For many people, this is a bit of a stumbling block since 14 bits isn't byte divisable. This isn't something most of us are used to. The PIC16C8X series has a 14 bit wide instruction 'WORD'. This means each of the instructions is exactly 14 bits in size. The CPU is still considered to be an 8-bit machine since the basic data size it deals with is 8 bits wide. Other members of the PIC family have different instruction bus sizes. For example, the 16C5X series has a 12-bit instruction word, while the PIC 17CXX series uses a 16-bit instruction word. All are still considered 8-bit microcontrollers.
The PIC series all have only one working register, which is the W register. This is something that requires a little getting used to. However, it turns out that many operations that the RISC core can execute are capable of storing the result in the W register, or in the RAM. In fact, RAM on this chip is considered to be the File Registers. You get 36 bytes total. Other 'File' registers available are the STATUS register, the FSR register, and the Program Counter. One common register that is missing is a stack register. In fact, it turns out that this chip has no data stack at all. There is a call level stack which holds 8 13-bit program counter values for storing return addresses when you make calls or take interrupts. This means you have a limit to the number of subroutines you can make. Each call pushes or interrupt pushes one return value on the return stack.
|An interesting thing about the RISC architecture of
the PIC chips is there are only about 35 instructions
available. The instruction set at first seems very
limiting, but there are ample examples floating around to
show you how to make more complex instructions from these
simple ones. In fact, the standard assembler from
Microchip includes many macros to help create a richer
Instructions such as ADDWF f,d allow for the specification of the destination for the result. The 'd' parameter specifies the destination. A zero in this location specifies the result should go in the W register, and a 1 puts the result back into the file. A commonly defined pair of equates are W = 0 and F = 1 which make the code more readable.
For example, ADDWF 30,F takes the current byte in File Register 30 (ie byte at address 30), adds the current value of the W register, and stores the result back into File Register 30. The W register is unaffected by this operation. The other option is ADDWF 30,W which stores the result in the W register with File Register 30 being unaffected.
An interesting by-product of the Harvard architecture appears when you attempt to use constant data values, such as strings or tables. There are no instructions that allow you to directly address data values in the program memory space. The solution to this problem is clever, though it does seem a little strange right off the bat. While you cannot address program space, you can load literal values into the W register. Therefore, to retrieve a byte value from a constant string, you basically write a little bit of code for each byte that loads the value into the W register. At first, it seems like such extreme overkill that you might want to gag. However, since each WORD in the program space is 14 bits, the Microchip engineers included single word instructions for loading each byte. And, in fact, you can write a routine that returns a value in your string based on an index. This routine requires one program word per character. This was so useful that they also defined a variant on the return instruction, RETLW, which loads a constant value into the W register and executes a RETURN in one instruction.
Here is an example of two strings. Each string is defined with a constant offset called STR_<string name>. To print out the string Banner, you would initialize an index with STR_Banner, move it into W, then call GetStringChar, which will return the character desired. Note that PCL is the low byte of the program counter. This is a way to do an indexed jump. Adding to PCL changes the point of execution.
GetStringChar: addwf PCL,F ; Jump table StringTableStart: Banner: STR_Banner: equ Banner - StringTableStart retlw 0x48 ;'H' retlw 0x65 ;'e' retlw 0x6c ;'l' retlw 0x6c ;'l' retlw 0x6f ;'o' retlw 0x20 ;' ' retlw 0x4d ;'M' retlw 0x6f ;'o' retlw 0x6d ;'m' retlw 0x21 ;'!' retlw 0x0d ; CR retlw 0x0a ;' ' retlw 0x00 ;' ' ErrMsg: STR_ErrMsg: equ ErrMsg - StringTableStart retlw 0x45 ;'E' retlw 0x72 ;'r' retlw 0x72 ;'r' retlw 0x6f ;'o' retlw 0x72 ;'r' retlw 0x0d ; CR retlw 0x0a ;' ' retlw 0x00 ;' '
I hadn't intended on making you an expert in PIC programming, but I did want to show you a little bit about what the instruction set looks like because it is interesting to see what you are in for when programming. I also wanted to highlight some of the tricks that the Harvard RISC architecture requires, such as the retlw instruction and the indexed jump by adding to the PCL register. One more code fragment is shown below. This routine implements a serial output routine in software. Since the 16C84 has no hardware serial port, you have to roll your own:
;************************************************************************ ; Output a byte to the serial port ; ; Arguments: W contains the character to send ; Returns: W contains the character sent ; Errors: None ; ;************************************************************************ Serial_Output: movwf SerialBuf ; This is the value that will be shifted movwf SerialTemp ; Saved for the return value movlw 8 movwf BitCount ; Going to move 8 bits bcf PORTA,TX ; Send the start bit BitOutLoop: call DelayForBaudPeriod rrf SerialBuf,F btfsc STATUS,C bsf PORTA,TX btfss STATUS,C bcf PORTA,TX decfsz BitCount,F goto BitOutLoop call DelayForBaudPeriod bsf PORTA,TX ; Send stop bit, which is high call DelayForBaudPeriod return
As you can see from the above code fragments, the instructions are simple, but get the job done.
As with any new language or system, there is a small learning curve you must overcome. Microchip has made this pretty easy by making great development tools available at a very low cost. Their PICStart Plus programmer can handle programming almost all of the DIP versions of these chips, plus it comes with a really great development environment called MPLAB. The MPLAB is an integrated development environment (IDE) that includes an assembler, editor, simulator, and programmer software in one nicely integrated package. You can write your code, debug it in the simulator, and program a chip from one program. Very nicely done. The software is available on the internet. Check out http://www.microchip.com to see what is currently available.
There are also a healthy number of application notes for the PIC products. Projects can also be found in most of the major magazines.
Perhaps the most impressive thing about the PIC series is the shear number of variants that are readily available. You can choose your own configuration from an impressive list. Some chips have more memory, others more I/O pins, some have built in serial ports, others have A/D, I2C hardware, SPI hardware, and a rich set of other devices. There are tradeoffs, but so far I have found myself able to select chips that have the features I am looking for.
Just for example, here are two parts other than the 16C84.
|The 16C61 is a part that I have been using with great success for my BDM12 product. It is extremely fast, running at 20mhz. Most of its internals are very similar to the 16C84 with some extra goo in the timer area. I have found these parts to be readily available from DigiKey and a number of other sources. You can even get them at Active Electronics in Bellevue if you hit them on a lucky day.|
|If you have the room, and would like lots more I/O, you might find the PIC16C74 a great choice. It has a rich set of features, such as 4k of onboard program memory, and 192 bytes of RAM. It has plenty of I/O pins, and a whole slew of onboard options. This one has a lot in common with the HC11 and would make a pretty decent robot controller. It is availabled in a Windowed part so you can erase it in your EPROM eraser, which is really nice. As another 20mhz part, this one is a real screamer.|
Microchip has been putting out new variations at about 1 a month. The latest variations are the PIC12CXX parts, which are an 8 pin device with 6 available I/O lines, and an onboard clock oscillator. I have not used one of these yet, but I find them to be very interesting.
Another variation is the 16 bit instruction core of the PIC17CXX series, which are really quite powerful, and allow for lots of code space and lots of data space.
The PIC series of microcontrollers are very capable, small, fast, and readily available. They are extremely useful for applications where a physically small part is needed. It is not suited for some purposes, such as lots of text handling or pattern matching. It is perfect for other applications, such as wheel encoding or dedicated subsystem work.
Some of the terminology I hope you now understand are the Harvard architecture, what is meant when someone says a 14 bit CPU, and what a RISC instruction set looks like. I hope I have also provided you a better feel for what these chips are like to program and to design with.
I have been very impressed by the Microchip products. The controllers and the development tools are all high quality. If you need a special purpose controller, the PIC is definitely a great chip to consider.
Many diagrams contained in this article were found on the Microchip website, and on the Microchip 1996 Technical Library CDROM. I hope they don't mind my using them.
PICMASTER, PICSTART, SEEVAL and the Microchip logo and name are registered trademarks of Microchip Technology Incorporated.
PIC is a registered trademark of Microchip Technology Incorporated in the U.S.A.
What else do you want to know? Send me mail and ask away. Kevin Ross