Main Page
Course Admin
Contest Rules
Project Resources
Team Info
Picture Gallery
Contact Info
  You are here: RoboTag Main Page > Project Resources > Technical > PIC Introduction

Using the MicroChip PIC Microcontroller

A technical overview designed for students

Written January 2000,
William Sitch, B.Eng. (1999)

The PIC is a small 8-bit microcontroller designed primarily for fast input/output control using a small instruction set. The PIC is low-cost (~$15), can be developed for free (free IDE, including simulator), and can be reprogrammed thousands of times (Flash EEPROM - no UV eraser required) from a cheap programmer (~US$10).

This introduction to using the PIC, with emphasis on the fourth-year design project, is as follows:

PIC Basics

For this tutorial we will be focusing on the PIC16F84, available from DigiKey Canada for CDN$10. The features of this MCU are as follows:

  • 8-bit microcontroller (MCU) with 14-bit instruction set
  • 18-pin dual-inline package (DIP) with 13 input/output lines
    • 25mA max. sink per pin, 20mA max. source per pin
  • 35 single-word instruction set, each 400ns at 10MHz
  • DC-10MHz clock, DC-400ns instruction cycle
  • 1024 x 14-bit 'words' of FLASH program memory
  • 68 x 8 bits of program RAM (SRAM)
  • 8-level hardware stack
  • Timer0: 8-bit timer/counter with 8-bit programmable prescaler
  • Power consumption: <2mA @ 5V, 4MHz; <1uA standby at 2V
Detailed explanations of each of the above specifications is included below, along with links to external information sources. The best resource for detailed questions is, of course, the MicroChip datasheets.

8-bit microcontroller, 14-bit instructions - which means all data is stored in chunks of 8-bits, and each instruction requires a 14-bit instruction. The Harvard architecture uses seperate buses for the data and instructions. No floats, doubles, longs, or even integer data types are available, just the standard 'short' from C. Depending on how you wish to represent numbers, you can use the range 0..+255 as straight binary, or from -128..+127 in a two's complement method. While 8-bit arithmetic operations are included, you may require 16-bit operations for accuracy.

18-pin dual-inline package with 13 I/O lines - this is the stereotypical "computer chip", in that it's a small black rectangle and has two rows of metal connections. Of the 18 pins, 13 can be used for input or output, programmed through the porta and portb registers. Each I/O line can be designated as input or output, and tristate buffers are changed accordingly. With the on-chip buffers, the PIC can sink 25mA per pin (50mA per "bank", unfortunately) and can source 20mA per pin (50mA per "bank"). Two I/O lines are required for the clock, two are required for power connections, and the last pin is used as a reset line.

35 single-word instruction set - unlike the computers you have programmed with assembly language, where the instruction set has hundreds of commands, the PIC uses a RISC CPU with only 35 different instructions. A comprehensive list of these instructions is available from the MicroChip datasheets.

DC-10MHz clock, DC-400ns instruction time - this details the speed of the microcontroller. The clock can be run at any frequency up to 10MHz, and often a little faster, whereas the time required for each cycle can be as fast as 400ns. Apart from program branches, which take two cycles, each instruction operates in one cycle. This means, at 10MHz, you can execute some 2,000,000 instructions per second.

1024 x 14-bit 'words' of FLASH program memory - the PIC can handle 1024 program instructions, each consisting of 14-bit words. These instructions are downloaded into the FLASH memory, which retains the code - without power - for some 10,000 years. The code is serially programmed into the PIC via a hardware programmer, which is further detailed in the Programming your PIC section.

68 x 8 bits of program RAM (SRAM) - your program can store 68 bytes of information in the standard SRAM included in the PIC package. This is enough for state variables, counters, constants, and other programming tools, but isn't enough to do serious data logging. To interfacing with additional memory, consult the MicroChip application note "TechBrief: Using SRAM with a PIC16CXX", here.

8-level hardware stack - The 8 x 13-bit hardware stack is implemented to store the program counter (PC) register when a function is referenced with the CALL command. The PC is "popped" off the stack when the function executes a RETURN, RETLW, RETFIE command. The user cannot otherwise access the stack. This means that your program have eight layers of functions without losing track of where it originally came from.

Timer0: 8-bit timer/counter with 8-bit programmable prescaler - the timer/counter module isn't covered in this tutorial. It has features as follows:

  • 8-bit variables
  • read / write
  • 8-bit programmable prescaler
  • internal or external clock
  • edge-rising or falling (external clock)
  • interrupt on overflow from 0xFF to 0x00

Developing your Code

While PIC programming can be simplified by using a C or BASIC compiler, there's nothing quite like getting at the assembly language underneath it all. The MPLAB integrated development environment (IDE) from MicroChip is the best choice - it's free, well supported, and does everything you need it to do.

The MPLAB IDE features the following:

  • MPLAB Project Manager
    • Organizes the different files under one 'project'
    • Interfaces between the editor, assembler, linker, and simulator
  • MPLAB-SIM Software Simulator
    • Features debug capabilities: unlimited breakpoints, trace, examine/modify registers, watch variables and time-stamp
    • Simulates core functions and peripherals
  • MPLAB Editor
    • Programmerís editor to write and edit source files
  • MPASM Universal Assembler
    • Has macro capabilities, conditional assembly
    • Builds the HEX file (machine language)
By far the most important component of the IDE is the integrated software simulator, which allows a designer to trace through their assembly code and watch the registers, RAM, ROM, and I/O ports.

The MicroChip MPLAB IDE is available from here. You'll want the latest version, and you should probably download the manuals and tutorials available for your specific PIC.

Once you've downloaded the file(s), and you've installed them - you'll need an unzipper - you need to install the files. There is a good tutorial associated with the MPLAB IDE, but you should first configure the software as follows:

  • Under the Options menu,
    • Select Development Mode.
    • In the popup window, select the MPLAB-SIM Simulator

Now you can write your code in assembly language, compile and link it to form the actual machine language, called a HEX file, and simulate the PIC running the code. There's a number of good tutorials included with the MPLAB IDE, and you should step through them until you're familiar with the user interface and the features of the development environment.

MPASM Code Examples

The following two MPASM code examples will cleanly compile and download. They both will flash a standard LED connected to portA, bit0. The first example was written for the PIC16F874 and flashes the LED on and off twice a second. The second example was written for the PIC16F84 and flashes the LED at an increasing/decreasing rate.

Both examples are fully commented, and the .HEX files are available for download. As these demonstration programs have worked with my hardware setup, you should try them with your programmer and software to ensure everything is working before trying to download your own code.

PIC16F874 LED Flashing Program:
Download the ASM and HEX files (zipped)

; *** 874flash.asm ***
; flash test program for PIC16F874
; written by William Sitch, Feb. 2000

; initialization stuff
list p=16f874			; set the pic type
__config b'1111111110111101'	; set configuration bits
radix hex			; default to HEX format
include ""		; include the default EQUs

; define variables (general memory starts at 0x20)
nmsec	equ	0x20		; number of millisecond delays
nnop	equ	0x21		; number of NOP delays

; at the reset vector, jump to the code start
	org	0x000
	goto	start

; at the interrupt vector, start the code
	org	0x004
	movlw	0x00	; move 0 into W register
	tris	PORTA	; set portA to be all outputs
	tris	PORTB	; set portB to be all outputs

	bcf	PORTA,0	; turn off pin0 on portA
	call	delay	; delay for 250ms
	bsf	PORTA,0	; turn on pin0 on portA
	call	delay	; delay for 250ms
	goto	flash

	movlw	.250	; move 250d into W register
	movwf	nmsec	; move value into nmsec variable
	movlw	.110
	movwf	nnop	; move 110d into nnop variable
	nop		; 110x "dnop" loop is ~1ms at 4MHz
	decfsz	nnop,F	; dec nnop, skip next result if zero
	goto	dnop
	decfsz	nmsec,F	; dec nmsec, skip next result if zero
	goto	d1ms

PIC16F84 LED Flashing Program:
Download the ASM and HEX files (zipped) here.

; *** 84flash.asm ***
; flash test program for PIC16F84
; written by William Sitch, Feb. 2000

; initialization stuff
list p=16f84			; initialize to the correct PIC type
__config b'1111111111111001'	; set the configuration bits
radix hex			; default to HEX format
include 		; include the default equates

; compiler equates
LED_pin		equ	0x0	; pin0 on portb is LED output

; define variables
num_ms_delay	equ	0x0c	; number of 1ms delays
num_nop_delay	equ	0x0d	; number of double-nop delays
delay_time	equ	0x0e	; amount we should delay by

; define the reset instructions at 0x000
	org	0x000
	goto	start

; define the interrupt start at 0x004
	org	0x004
	movlw	0x00		; moves 0x00 into the W register
	tris	PORTB		; tri-states portb pins to be all outputs
	movlw	b'00011111'
	tris	PORTA		; tri-states porta pins to be all inputs

	movlw	0xff
	movwf	delay_time	; start decrementing from 0xff

	decfsz	delay_time,F	; decrease the delay time
	goto	dec_flash
	goto	init_inc	; start increasing if we overflow
	call	flash
	goto	calc_delay_dec

	movlw	0x00
	movwf	delay_time	; start incrementing from 0x00

	incfsz	delay_time,F	; increase the delay time
	goto	inc_flash
	goto	init_dec	; start decreasing if we overflow
	call	flash
	goto	calc_delay_inc	; flash and keep increasing

	goto	finish		; loop until reset

; =====
; flash function, delays for delay_time ms with led ON and OFF
; =====
	bsf	PORTB,LED_pin	; set the LED on
	movf	delay_time,W
	call	delay		; delay for  msec
	bcf	PORTB,LED_pin	; set the LED off
	movf	delay_time,W
	call	delay		; delay for  msec

; =====
; delay function, pauses for W microseconds
; =====
	movwf	num_ms_delay	; load var with number of d1ms' left
	movlw	d'110'		; 110x d2nop ~= 1ms
	movwf	num_nop_delay	; load var with number of d2nop's left
	nop			; pause
	nop			; pause
	decfsz	num_nop_delay,F	; dec the # of d2nop's left, check zero:
	goto	d2nop		; keep doing d2nops until we're done
			; otherwise:
	decfsz	num_ms_delay,F	; dec the # of d1ms' left, check zero:
	goto	d1ms		; keep doing d1ms' until we're done
			; otherwise:
	return			; return to the program

Serial PIC Programming

Once you have written a short test routine in MPLAB, and it compiles cleanly to the required .HEX file, you need to get the code onto the PIC. The simplest (and cheapest!) method of programming a PIC is to build your own serial programmer, or buy a cheap kit. The idea is to feed the PIC a 5V serial clock and data line, a 13.4V programming line (/MCLR), and a couple of +5V and GND connections.

These five-to-seven connections are all you need to program the extensive MicroChip family of serially-programmable PICs. A low-cost PIC programmer is available from Peter H. Anderson (select the Starter Package for PIC Newcomers). This excellent kit includes a breadboard, all the required parts, detailed assembly instructions, a wall wart, parallel cable, and TWO 16F84 PICs and 4MHz resonators - all for US$49.

There are many other cheap serial PIC programmers available, and if you use scrounged parts from the Department of Electronics, you could probably build a serial PIC programmer for no cost! The style of programmer is often referred to as a "David Tait"-style programmer, as Mr. Tait is known as "the father of printer port PIC programmers". David Tait retired from PICs a while ago, but you can still browse through his huge archive here.

Once you've built and tested the serial programmer (don't be fooled by the parallel port implementation - it only uses one data line for transferring your code), you will need software to interface with the PIC, correctly blow the fuses on the PIC, download your HEX code to the PIC, and verify that the memory locations of the PIC are accurate. This software is offered for hundreds of dollars from MicroChip and the like, but again a much cheaper solution is available.

Bojan Dobaj distributes an excellent software package called P16PRO, which will program almost any MicroChip PICmicro. It's available at, or from his webpage at This software package is freeware for the PIC16F84, and asks for a small donation to program other PICs. While the documentation bundled with the software isn't the best - Bojan is quick to respond to email.

If you're using the P16PRO software with a serial-programmable PIC on an el-cheapo parallel port downloader -- then you're doing something that millions of others have, and you can read the slew of documentation available on the web. If you're using a RadioShack CDN$130 PIC programmer, expect minimal support and no available fix for any problems you encounter. Needless to say, I have an obvious bias.

There are a number of settings associated with the P16PRO software, and several of the settings are subtle. If you've built and tested Peter H. Anderson's basic PIC programmer, as he describes in the documentation, you can use the settings outlined below. For other programmers, you should use trial and error to find the correct settings.

For Peter H. Anderson's programmer:

  • Reboot your computer into DOS mode (or use the DOS-only laptop)
  • Find and execute the P16PRO executable (c:\p16pro\p16pro.exe)
  • Goto the "Settings" menu
  • Select "Device" and pick your PIC
  • Select "Fuses" and set:
    • Oscillator: XT
    • Watchdog Timer: Off
    • Power Up Timer: Off
    • Code Protect: Off
    • (Although we set the configuration bits through software in the two demonstration programs shown above)
  • Select "Other" and set:
    • Your LPT port
    • Save on Exit
    • Show Program Data
    • Show Data for 8X
    • Hex Type INH8M
    • Verify On
    • Blank Check After Erase On
  • Select "Hardware" and set as follows (for the PIC16F84):
+--------------------------  Hardware Setup------------------------+
™    OutData   Clock     Vdd       Vpp       Vpp1       Data In      
™    (+) D0    ( ) D0    ( ) D0    ( ) D0    ( ) D0                  
™    ( ) D1    (+) D1    ( ) D1    ( ) D1    ( ) D1                  
™    ( ) D2    ( ) D2    (+) D2    ( ) D2    ( ) D2                  
™    ( ) D3    ( ) D3    ( ) D3    (+) D3    ( ) D3    ( ) ERROR     
™    ( ) D4    ( ) D4    ( ) D4    ( ) D4    (+) D4    ( ) SELECT    
™    ( ) D5    ( ) D5    ( ) D5    ( ) D5    ( ) D5    ( ) PAPER END 
™    ( ) D6    ( ) D6    ( ) D6    ( ) D6    ( ) D6    (+) ACK       
™    ( ) D7    ( ) D7    ( ) D7    ( ) D7    ( ) D7    ( ) BUSY      
™    ( ) Neg   ( ) Neg   ( ) Neg   (+) Neg   ( ) Neg   ( ) Neg       
™                      < Cancel >    < OK >                          
Note that Vdd and Vpp1 are not actually controlled by this programmer. But, they have to be set to something. The "neg" indicates negative logic. That is, in the case of Vpp, D3 is normally high and the +13.4 programming voltage is off. The programming voltage Vpp is applied when D3 is brought low.

The flip-side of this coin is that you should change the Vpp1 column to be the same as the Vpp column if you're using the PIC16F874. This is because the software wants to use two different voltages, and the standard programmer doesn't support that.

Remember to save this information from the "Settings" menu.

From the main screen of the P16PRO software, load the HEX files available above, cross your fingers, and press F4. If everything is working correctly, the green programming LED will flash, the code will download, and you're done!

Running your Programmed PIC

Now you've got the MPLAB programming environment going, you can compile code into HEX files, you can download the HEX files via the serial PIC programmer, and you have a programmed PIC on your hands! Unfortunately, the PIC doesn't just work. It needs a couple of clock signals, power and ground connections, a pull-up resistor on the active-low reset pin, and a LED connected to the appropriate pin.

The best way to clock the PIC, in my opinion, is with a three-pin ceramic resonator. It's a cheap part, and plugs directly into the PIC clock_on and clock_off pins. Connect the middle pin of the resonator to ground, and the other two pins to pins 15 & 16 (PIC16F84) or pins 13 & 14 (PIC16F874). This is the "XT Oscillator" we defined in the configuration bits of the code, or in the programmer settings.

Download your particular PIC datasheet from MicroChip, and check the pinout. The +5V and GND connections will be on the same pins as was required by the programmer. The clock_in and clock_out pins will be defined in the pinout, and you can also find the pin0, portA connection for the flashing LED.

PIC Links

Here are some highly recommended links for the PIC:

  • MicroChip - MPLAB software development environment, datasheets for PICs
  • Peter H. Anderson - Cheap serial PIC programmer & documentation
  • P16PRO - Shareware serial PIC programmer software
  • David Tait - Archive of PIC information

Main Page
Course Admin
Contest Rules
Project Resources
Team Info
Picture Gallery
Contact Info