Anda di halaman 1dari 6

PIC Microcontrollers

These amazing devices are very easy to program

Introduction

PIC microcontrollers are made by Microchip Technology, Inc.. They are true computers on a chip,
including program and data memory as well as 'peripheral' devices such as timers, comparators, analog to
digital converters and serial communications. Even the oscillator and reset circuitry can be on-chip so that
all that is required for operation is a power supply. They come in packages as small as six pins, and at
surprisingly low prices. Besides the two power supply pins, all the other pins are multipurpose input-
output connections that are configured for the particular application.

Very popular for experimentation are the circuit boards with programming software using BASIC or C
that runs on a PC, using USB or the Serial port for download to the board. Examples are the BASIC
Stamp provided by Parallax, the PICAXE boards, and the Arduino boards. The MCU's that are used are
not advertised, but the BASIC Stamp and PICAXE use Microchip PIC's (at least in some cases), and the
Arduino uses Atmel MCU's, the ATmega328 or ATmega168 on the Duemilanove board. I think the use
of high-level languages on small microcontrollers is very cumbersome and limiting, so I have not
investigated these systems. Assembly language gives direct and full access to all the facilities of an MCU,
shows exactly what is going on, and is very easy to use.

The PIC MCU's are very well adapted to experimentation because of the excellent information available
from Microchip on their website, the existence of programming tools at reasonable prices, the low prices
of the chips and the simiplicity of use. I recommend the PICkit 2 with the low-pin-count demonstration
board and MPLAB IDE (Integrated Development Environment), which is available for about $75 and
comes with a PIC16F690 MCU (the IDE is actually free). To use it, you will need a good PC with an
available USB port. With this demonstration board, a reasonable variety of 8, 14 and 20-pin Flash-based
MCU's can be programmed. Besides the full-featured 16F690 MCU furnished, I recommend the 14-pin
16F630 or the 8-pin 12F675, a small MCU that includes an analog to digital converter. The IDE includes
a simulator that will let you see how the instructions execute on a wide variety of MCU's, not only those
that the board can program. You should obtain the PIC Midrange MCU Reference Manual (33023a.pdf),
the data sheets for the chips you will study and program, and the assembler and IDE User's Manuals from
the Microchip website. The PIC12F6XX/16F6XX Memory Programming Specification explains how the
chips are programmed with a serial interface, and may be interesting even if you will not use the
information directly. Install the IDE and the PICkit 2 with the CD's furnished, and you will be ready to
go.

The very large variety of Flash-based PIC MCU's available is grouped in families identified by the chip
ID, from the "Baseline" 10F series with 12-bit instructions through the "Mid-Range" 12F and 16F with
14-bit instructions, to the 18F family, which is a further development of the obsolete 17F family. The 18F
family can access external memory. The 16-bit 24F family has an expanded instruction set like that of a
general-purpose microprocessor, as well as 16 working registers instead of just one, as well as 16-bit data
registers and 24-bit instructions, operating from a 3.3V power supply. There are even larger 32-bit
processors as well, which have von Neumann architecture. The experimenter should probably stay with
the 8-bit processors for low cost and ease of use. The PICkit 2 LPC board programs 18 different 8, 14 and
20-pin Mid-Range MCU's. I chose this board because it runs from a USB port and is reasonably priced. A
programming adapter board for the PICkit 2 is available for 10F2XX MCU's. All the PIC MCU's are
programmed by serial data links, and can even be programmed when in a circuit. The identification
marking on the chips is very difficult to read; stickers may avoid confusion.

The assembly language programming for all the 8-bit MCU's is identical. Only the amounts of
implemented memory and the peripherals included are different in the different chips. The Midrange
Reference Manual is a good source of architecture and programming information and should be studied
carefully. These processors use a Harvard Architecture where the instructions and data are stored in
different instruction and data memories. The instructions are 14 bits wide and each occupies one location.
The data are 8 bits wide and occupy the register file memory, organized in four banks of 256 registers
each. The upper locations are the special function registers that control the operation of the MCU. The
instruction (14 bits wide) and data (8 bits wide) buses are not externally accessible.

Most general-purpose microprocessors use the von Neumann architecture instead, where the same
memory holds program and data, which are transferred over a single data bus and accessed by a single
address bus. The stack that holds return addresses for subroutine calls is maintained in this memory and is
addressed by a stack pointer. The stack has greatly expanded use in most general-purpose processor
programs to hold data structures to pass data to subroutines. In the PIC processors, the stack is an 8-level
dedicated memory that stores only return addresses, and so the stack is not used as it is in a von Neumann
processor. In fact, the stack pointer is not externally accessible since this would be of no use. The general
purpose data registers are considered data for all subroutines, so there is no need to pass them to
subroutines, and there is no distinction between local and global data. This greatly simplifies
programming, but of course lacks the power of the von Neumann stack.

The PIC MCU's are reduced-instruction set (RISC) processors. For example, you will find no compare or
branch instructions at all. All branches are made only by instructions that skip the next instruction if a
certain bit is set or cleared, or if an increment or decrement results in a zero. The subtract instruction
affects the zero and carry bits, and you must interpret the bit states with the skip instructions. There are, in
fact, only 35 instructions to learn. The RISC instructions may be combined to perform the same tasks as
the more specialized instructions in larger instruction sets. The 18F family includes some of these
specialized instructions, such as add with carry and subtract with borrow that make multiple-precision
arithmetic easier, as well as conditional branches.

I recommend using assembly programming for using the PIC microcontrollers. Compilers are available
for C and Basic, but this is a very cumbersome way to create small programs and can obscure the basic
operation of the processor. The PIC IDE editor is very helpful, recognizing instructions and other entries.
An assembled program can be single-stepped to verify proper operation with the MPLAB-SIM simulator.
If this is done with care, there will be no need for debugging the target system. A successful assembly
produces a hex file that can be imported to the PICkit 2 programmer and easily written to the target
processor. The program can be edited in the hex file or in the PICkit 2 display if necessary. In fact, I
chose the PIC microcontrollers for experimentation because of the ease of assembly programming. It only
takes a few minutes to assemble a program and write it into an MCU.

There are two ways to address a data register. One way, called direct, is to put the 8-bit data register
address in the instruction. Only the lower seven bits are used (the eighth bit is replaced by the destination
bit, as discussed in the next paragraph). The upper two bits, which specify the memory bank, are taken
from the status register to give the full 9 bits required. The second way is to put the 8-bit address in the
FSR register (address 04). Then, the 9th bit is taken from the IRP bit in the status register when a read or
write to location 00 is performed. This is strange, but is the way they do it. In small MCU's the upper two
banks are not implemented, so an 8-bit address is sufficient and IRP is ignored. It is always necessary to
be aware of which register bank is being addressed and see that the bits in STATUS are properly set.
Remember that in direct addressing the eighth bit of the address is ignored.

In most of the register operations, there is a choice of the destination of the result--either to the
accumulator W or back into the file register itself. In these cases, the destination must be specified as well
as the address. For example, INC 20,0 adds 1 to the contents of register 20 then copies the result in W,
leaving register 20 unchanged, while INC 20,1 puts the incremented value back in 20, leaving W
unchanged. This is rather different from most processors, and can be useful.

Every bit in the registers can be addressed by following the register address by the bit number. The three
bits specifying the bit number replace the 8th address bit and the final two bits of the opcode. For
example, BCF 03,5 clears bit 5 of register 03, while BSF 03,5 sets bit 5 of register 03. It is best to set and
clear bits by the bit operations, not by writing 8 bits to the register and using logical operations.

Hex numbers are the default in the MPASM IDE and need not be specially identified. They must begin
with a valid decimal digit (as in 0A). Decimal numbers are preceded by a "." as in .12, which is
interpreted as 0A. An instruction cycle is four clock cycles, so an oscillator frequency of 4 MHz gives a
1 s instruction cycle. All instructions require one cycle period to execute; if there is a change of program
counter, as in a GOTO or skip instruction, an extra cycle period is required that is essentially a NOP. The
special function registers have the same addresses in all PIC MCU's, which is very convenient.

Programming a PIC Microcontroller

I assume that you have a PICkit 2 and LPC demonstration board with a PIC16F690 MCU, and have
installed the MPLAB IDE v.8.30 and the PICkit 2 v.2.50 from the CD's. Your version numbers may
differ, but I show the ones that I used. You also should obtain a PIC16F630 or other MCU supported by
the board for your program. Jameco handles the 8 and 14 pin MCU's, but not the 20-pin ones. Digi-Key
and Newark sell the 16F690. Microchip will supply any of their products by online order. The Velleman
VM134 programmer, which works from a serial port, will program the baseline 10F200, the 16F84, and a
number of 18F family devices. I have not used this programmer.

Launch the PICkit 2 program. Select Device: Family Midrange Standard, and Device 16F690 should then
be found. VDD should be set at 5.0V. Check the VDD On box to turn on power to the 690, and the LED's
should blink. Press Read, and the program loaded in the 690 should appear in the display. This program
includes a bug that causes the A/D converter to operate improperly, as you can see if you rotate the
potentiometer. The program does not wait for the conversion to be complete. To fix this, change the byte
representing the instruction btfss, 1C9F, to that for btfsc, 189F. Just click the location 1A0 to select it, and
type in the new value. Now press Write to write the corrected program to the 690. Now the LED's blink
more regularly, and you can change the rate with the potentiometer. Note that you cannot change the
configuration byte. It must be specified in the hex file and is not available in normal operation. Under the
File tab select Export Hex and create a hex file for the new program, giving it a suitable name, like
newblink.hex. Study this hex file in Notepad and see how it includes the program data and the
configuration word. The configuration word is in the next-to-last record of the hex file, that begins
02400E00 (400E is just twice the program memory address 2007). The first record, of type 04, only gives
the upper word of the 32-bit addresses, which is 0000. In between are the data records of the program
with byte addresses. The final record is just the standard last record. The hex file is the means of
communication between the IDE and the programmer.

There are 12 lessons furnished with PICkit 2, each of which is complete IDE project. On my computer,
they showed up after installation in the root directory while the other files were placed in Program Files in
the Microchip folder. There is an assembly template file for the 690 and an .INC file for the 690. There
are .INC files for any MCU you may use elsewhere. They are not really necessary, but include a full list
of symbols that you may want to use. There are separate template .asm files for absolute and relocatable
code. When you write a program for the 16F630, or other MCU you may have chosen, put in list
p=16f630 and #include , in that order, as the example shows. Study the .asm files to see how to write
them. Note that labels must start in column 1.

It is a good idea to read important points in the IDE User's manual (document DS51519C). A tutorial is
included early in the manual (Sec. 4.2) that should definitely be studied. The IDE is a complex program,
and the Menu choices should be investigated to see what you can do. It can handle complex programs
with multiple source files, libraries and relocatable code, although we shall not use these features. The
assembler and linker are fully explained in the MPASM User's Guide (document DS33014).

Launch the IDE, and practice creating a new project. The name and the directory must be chosen. Select
the MCU that will be used in the Configure tab, and choose the MPLAB SIM in the Debugger/Select
Tool. We will generate only absolute, not relocatable code, so we will not need the linker. It is all right to
have programmer None. if you select PIC Kit 2, the IDE will recognize the programmer if it is running,
and check that a 630 is installed. Under Project, select New and enter the name and directory. Then you
can add an .asm source file under Add File. We shall work only with one source file, which simplifies
things considerably. Close files you do not need. Note the things you can View, which include the special
function registers, file registers and a disassembly listing. Open the .asm file and note that you can edit it
here. The last line should be the directive "end" which marks the end of assembly. Everything on a line
following a semicolon is a comment and is ignored by the assembler. When you have a created a new
project you will have a Make choice under Project, which will perform the assembly and give you a
report. After a successful assembly, you will be able to single-step through the program by pressing F7 to
execute one instruction. The next instruction to be executed is marked with a green arrow on the .asm file
as well as on the listing file, either or both of which may be displayed. You can watch the changing
values in the registers. The current contents of the W register are also shown. At any time, the value in a
register can be changed by selecting it and typing in the new value. This is valuable experience, and you
should watch the execution of each of the instructions. The User's manual will show how to use
breakpoints and the timer, which can be useful.

If you have a program with only one source .asm file, you can use the Quickbuild feature that generates
only absolute code. If you open an .asm file in the workspace, then the Quickbuild choice will be
available. Just click this to build the program. Be sure that any .inc file is in the same directory as the .asm
file. The output files will be placed in this directory.

It may be useful to review how to revise a program in an MCU. The .asm file may be edited in any text
editor, such as Notepad. When you launch the IDE and choose Project/Open and click on the project file,
the .asm file will be automatically loaded. Of course, it can be edited here, with the help of the color
coding. Click on Project/Build All to reassemble. A successful Build will produce a new hex file
overwriting the old one. Put the target MCU in the LPC board, at the top of the socket, and launch the
PICkit. Choose Device Family/Midrange Standard and the MCU should be recognized. Next, click on
File/Import Hex and double click on the filename. When the file loads correctly, click on Write and the
MCU will receive the new program. It is not necessary to apply power by clicking the power box, unless
you want the program to run in the LPC board. Remove the MCU and restore it to its system. This only
takes a couple of minutes and is very straightforward.

Write a program for the 16F630 that controls any of the four LED's that are connected to PC0-PC3 on the
demonstration board, or detects a push on the pushbutton connected to PA3 that inputs a 0 when pressed.
The 12 lesson programs show how to do this explicitly. I wrote a program that lights two LED's
alternately at about a 1/2 Hz rate. Remove the MCU from the programmer board and put it in a solderless
breadboard. Bypass the VDD with an 0.1 F capacitor and connect LED's through 470 resistors from the
output pins to graound. When you apply power, the program should execute.

The 16F630 has two bandgap calibration bits in the configuration word, bits 12 and 13. Determine what
they are by installing the 16F630 in the demonstration board, and then Reading it. They will be the two
leading bits of the bandgap. The programmer will apparently preserve these bits automatically and will
not show them in the configuration word. Your program should calibrate the oscillator by a call to the last
program location at 3FF and writing W to OSCCAL. Again the PICkit 2 preserves this instruction. Import
the hex file of your program to the PICkit 2. Write the file to the MCU, and the 16F630 should now be
programmed with your program, and executing it. There is a statement that Microchip development tools
will not change calibration bits, but also a statement that they must be read, saved and restored
(apparently when using non-Microchip tools). These bits calibrate the band-gap reference voltage for
brown-out detection and power-on reset and possibly the internal voltage reference for the comparator.
The PIC16F630 that I used had calibration bits 01, and oscillator calibration byte 34 (in the command
RETLW 34).

There is a bit in the PCON register called NOT_POR that is zero after a normal power-on reset. It can be
tested to identify this state, and set to 1 so that a later /MCLR reset can learn that it is a "warm" reset. The
TRIS registers are set to all 1's, and the CMCON register is set to all 0's after an /MCLR reset, so these
registers must be reinitialized after every reset. The CMCON register controls the configuration of the
PA0 and PA1 bits. If configured as outputs in the TRISA register, they will be digital outputs as expected,
but if configured as inputs they will be analog inputs in the reset 000 comparator configuration. To make
them digital inputs, 07 must be written to CMCON.

A good exercise is to write a program that will read from an EEPROM location and display a nibble on
LED's. When it is reset with /MCLR, it will read a nibble from logic switches and store this nibble in
EEPROM, and display it. When the power is removed, and then again applied, the same nibble should be
displayed as when the program last operated. This exercise will show how to use EEPROM to provide
nonvolatile memory for a program. I used a PIC16F630, with LED's on PC0-PC3 and digital inputs on
PA0, PA1, PC3 and PC4. PA3 is configured as /MCLR. I found the curious difficulty with this program
that I could not preset the EEPROM location to be written because the programmer always cleared the
location to FF. Locations that were only read were able to be preset to any value.

Another program exercises the interrupt facility. I used the T0 timer with a 1:256 prescaler to blink an
LED. At an oscillator frequency of 4 MHz the cycle time is 1 s, so the timer would time out and cause
an interrupt every 0.0655 s. I used the interrupt routine to count out 15 of these timeouts, which amounted
to 0.98 s and then to toggle the LED. The T0 interrupt must be enabled by setting T0IE, and the T0IF
cleared at each interrupt. The interrupt is active as soon as GIE is set. The interrupt clears GIE, preventing
further interrupts, pushes the return address on the hardware stack, and goes to instruction location 0x4.
After clearing T0IF, the instruction RETIE pulls the return address into the PC and sets GIE again. In this
example it is not necessary to save the context when interrupted, since the main program will be doing
nothing but waiting, but in general W and STATUS should be saved and restored, as shown in the
assembly template file. There are many sources of interrupts, and they are an important tool in
microcontroller programming.

Atmel AVR Microcontrollers

A very popular line of Flash-memory microcontrollers very similar in capabilities tot the PIC
microcontrollers is manufactured by Atmel as their AVR devices. "AVR" is not an acronym, and has no
particular meaning other than indentifying the MCU core. The AVR programming model is significantly
different from the PIC model. Instead of the W register, there are 32 general purpose registers R0-R31
with ALU access. The 64 I/O Registers are analogous to the Special Purpose Registers of the PIC. 64 or
more data registers make up the remainder of the data space. Only the general purpose registers and the
I/O Registers are bit addressable, not the remainder of the data space. Instructions are maily 16 bits,
though some instructions include a second word that usually holds an address. The operation of moving
(copyin) data is named differently depending on the location of the data. A move is only among the 32 GP
registers. Out and in refer to writing and reading data between the GP registers and the I/O Registers,
while load and store refer to data transfer with the general data memory. Data can be moved between two
GP Registers in a single instruction, since two GP Register addresses (5 bits) fit in the instruction. A full
set of 120 instructions is available, even more in the larger MCU's, which may include multiply and
divide. The add and subtract can either use carry or not, as can the rotate instructions.

The two Fuse Bytes (11 fuses) and Lock Byte (2 lock bits) of the AVR are analogous to the configuration
bits of the PIC, controlling the clock source, watchdog timer, brownout detector and so forth. Serial
programming and an internal clock are configured as the device comes from the factory, so the device can
be programmed by the ISP (in-system programming) 3-wire interface. An instruction cycle is one clock
cycle, not four, as in the PIC. The default clock is a 9.6 MHz clock, divided by 8, so the effective clock
frequency is 1.2 MHz. This can be changed in programming or in software.

The equivalent of the MPLAB is AVR Studio 4, available at no cost from the Atmel website. It includes
an assembler and a simulator. As a programming tool, I am trying the ATAVRISP mkII, which connects
with the target system through a 6-pin ISP connector, and is available from Digi-Key. It should be easy to
make a programming adapter on a solderless breadboard. The ATtiny13 is equivalent to the PIC12F275,
supplied in an 8-pin DIP. The ATtiny24 comes in a 14-pin DIP, equivalent to the PIC16F676. The
ATtiny26 comes in a 20-pin DIP, with 20 I/O pins, and the ATtiny48 has 28 pins. The ATtiny 88 is the
seme except for a larger program memory. This should give some idea of possible devices to experiment
with.
There is now a page on AVR MCU's.

References

The Microchip website is at Microchip. All Microchip products can be purchased online at Microchip
Direct with no minimum order size. Microchip, located in Chandler, AZ had its origin in General
Instruments, becoming independent in 1989.

Another important manufacturer of recent flash-based microcontrollers is Atmel of San Jose, CA,
organized in 1984.

SparkFun Electronics is a Boulder, CO distributor supporting PIC, Arduino, XBee and other interesting
products, such as breakout boards for surface-mount chips.

There is a Wikipedia article "PIC microcontroller" that explains the range of PIC MCU's and gives some
important history, information and sources.

Intel Hex files are explained in a Wikipedia article. Note that byte addresses are used in hex files, while
the PIC program memory uses word addresses. The byte addresses are exactly twice the word addresses,
so the configuration word is at byte address 400E, which is prograqm memory location 2007. The format
used is INHX32, which includes a type 04 linear address record but is otherwise like the INHX8 format.

Anda mungkin juga menyukai