please dont rip this site

Microchip Davidtait First

                          My First PIC Project

                              David Tait

The PIC16C84 (or PIC16F84) from Microchip is a really great little
processor.  Being based on EEPROM (or "flash") technology means that
it can be programmed in a matter of seconds and typically it can be
reprogrammed around 1000 times.  Of its 18 pins 13 can be used as
general purpose I/O.  When programmed as outputs the I/O pins are able
to source 20mA and sink 25mA (more than enough to drive LEDs directly
for example).  It is inexpensive and can be programmed with simple DIY
hardware.  Obviously these features make the '84 attractive for many
projects but they also mean that it is an ideal processor for anyone
wanting to learn about microcontrollers.

This short document is meant for people who have just built or
purchased a PIC programmer and are itching to get their '84 doing
something if only to convince themselves that their programmer, PIC or
both are working.  To do this we obviously need to lash together some
simple hardware and this means knowing a little about the PIC.  Here's
a pinout diagram (looking from above):

                    +-----+ +-----+
                RA2 |1    +-+   18| RA1
                RA3 |2          17| RA0
          RA4/T0CKI |3          16| OSC1/CLKIN
              /MCLR |4   16C84  15| OSC2/CLKOUT
                VSS |5          14| VDD
            RB0/INT |6   16F84  13| RB7
                RB1 |7          12| RB6
                RB2 |8          11| RB5
                RB3 |9          10| RB4

The RA* and RB* pins are I/O pins associated with the PIC registers
PORTA and PORTB respectively (RA4 can also be used as an input to the
internal timer and RB0 can be used as an interrupt).  VDD and VSS are
the power pins.  The '84 works over a wide range of voltages but
typically VSS is connected to 0V and VDD to +5V.  The main reset pin,
/MCLR, can simply be tied to VDD (either directly or through a
resistor) because the PIC includes a reliable power-on reset circuit -
all you need to do to reset the PIC is cycle its power.  The processor
needs a clock and the OSC1 and OSC2 pins can be configured for a
variety of different options including crystal and low cost RC
oscillator modes.

A simple circuit that you can use as the basis of your first PIC16C84
project is shown here:

            +-O O---+---------------+--------------------+
            |       |               |                    |
            |       |          +----O----+               |
            | +     |          |   14    | PIC16C84      |
         -------    |   ____   |         |        ____   |
           ---      +--[____]--O 4    16 O----+--[____]--+
         -------         1K    |         |    |   4.7K   |
  4.5V     ---          ____   |         |    |          |
 battery -------    +--[____]--O 10      |   _|_        _|_
           ---     _|_  470    |    5    |   ___ 22pF   ___ 0.1uF
            | -    \ /^        +----O----+    |          |
            |      --- LED          |         |          |
            |       |               |         |          |

(Grab for a more readable

The circuit uses an RC oscillator and one I/O pin (RB4) attached to a
LED.  This is all you need to get the PIC to do something and see it
happening.  Charles Manning (Electronics Australia, April 1996) wrote
an amazingly short (6 word) LED flasher program that you can use with
this circuit:

        LIST    P=16C84
        MOVLW   0
        TRIS    6
        INCF    6,F
        GOTO    LOOP

The program is written for MPASM (Microchip's free assembler available
from  To use the program you'll need to
extract it from this file using a text editor (DOS EDIT is fine), save
it to another file (LIGHTS.ASM for example) then assemble it with
MPASM (using the command "MPASM LIGHTS.ASM") to produce a hex file
LIGHTS.HEX which can then be downloaded to the PIC using your
programmer.  Ignore the warnings from MPASM about TRIS and OPTION
being "not recommended".  Make sure you program the PIC with the
watchdog enabled and the RC oscillator selected.

If don't have MPASM yet here is a hex representation of the program I
prepared earlier:


You can save these two hex records to the file LIGHTS.HEX and skip the
MPASM step.  If you are using one of my PIC programmers you can
download this hex file with the correct configuration by using one of
the following commands:

PP -RW8 LIGHTS.HEX                           (PP V-0.3)
PP -RW LIGHTS.HEX                            (PP V-0.4)
TOPIC -RWG LIGHTS.HEX                        (TOPIC V-0.2)

The program uses the watchdog timeout as a timing source to decide
when to turn the LED on or off; in fact you can get the LED to flash
at different rates by connecting it to a different bit of PORTB
(RB0-RB7, pins 6-13).  This is an unusual use of the watchdog.
Normally the watchdog is used to make sure the PIC is behaving itself
and, unless your program is specifically designed to use it, enabling
the watchdog is a big mistake.  The simple LIGHTS program uses the
watchdog to wake it from "sleep" (i.e. power down) mode; on waking,
the PIC increments the PORTB register - thus changing the states of
RB0-RB7 - and promptly goes back to sleep awaiting the next watchdog
timeout.  The watchdog timer is clocked by an internal RC oscillator
which has nominally the same period on all PICs therefore a
consequence of using the watchdog for timing is that the program will
still work correctly no matter what PIC oscillator configuration or
frequency is actually used (well, the frequency should be at least a
few kHz).  This feature makes the LIGHTS program very useful for
initial testing of almost any PIC protoboard.

The circuit can be modified to give a slightly more entertaining
effect by adding more LEDs.  Connect the first LED to RB0 (pin 6), a
second to RB1 (pin 7), a third to RB2 (pin 8) and so on; it's best to
use at least four LEDs and you can use up to eight (the last one
connected to RB7, i.e. pin 13).  Each LED should be connected in
series with a 470 ohm resistor and wired between the PIC pin and the
-ve battery connection (VSS) just like the one in the schematic
above.  The following program will illuminate each LED in turn obeying
a to-and-fro pattern (remember the display on the car featured in the
old "Knight Rider" TV series?):

        LIST P=16C84
PORTB   EQU     6 
TRISB   EQU     86H
CARRY   EQU     0
RP0     EQU     5
MSB     EQU     3               ;BIT POSITION OF LEFTMOST LED
        CLRF    PORTB           ;ALL LEDS OFF
        BSF     STATUS,RP0      ;SELECT REGISTER BANK 1   
        MOVLW   0AH
LEFT    SLEEP                   ;WAIT FOR WDT TIMEOUT
        RLF     PORTB,F         ;TURN ON LED TO LEFT
        GOTO    LEFT            ;LOOP IF NOT
        RRF     PORTB,F         ;TURN ON LED TO RIGHT
        GOTO    RIGHT           ;LOOP IF NOT
        GOTO    LEFT            ;START NEW CYCLE

MPASM should assemble the program to give this hex representation:


Again you need to tell your programmer to enable the watchdog timer
and RC oscillator.  If you save the four hex records to a file
(WALKLEDS.HEX say) you can download the program using my programmers
by running one of these commands:

PP -RW8 WALKLEDS.HEX                         (PP V-0.3)
PP -RW WALKLEDS.HEX                          (PP V-0.4)
TOPIC -RWG WALKLEDS.HEX                      (TOPIC V-0.2)

As it stands the "LED walking" program is suitable for four LEDs but
you can change the value of MSB if you want to use more - MSB should
be 4, 5, 6 or 7 for 5, 6, 7 or 8 LEDs.

The program avoids using the deprecated TRIS and OPTION instructions
(Microchip don't want you to use them because they may not be
supported by future PICs).  Therefore, unlike the previous program, no
warnings are generated when the program is assembled.  To prevent
MPASM generating annoying messages about the correct use of bank
selection bits I have inverted the most significant bit of any bank 1
register address (e.g. I use TRISB^80H rather than simply TRISB where
the "^" operator denotes bitwise exclusive-OR).  This is just a trick
I've picked up and there are several other ways to silence MPASM; in
fact MPASM allows specific messages to be suppressed.  However, I like
my programs to assemble without generating warnings or messages even
if many of them can be safely ignored.  Getting MPASM to shut up
without resorting to deliberately suppressing warnings and messages
takes a little effort.

As a final example, the following program will give much the same
effect as the 4-LED WALKLEDS program.  You'll notice that even though
it does the same as the previous program this one is much longer and
it's certainly not meant as an example of efficient programming.
Instead it is designed to illustrate a few key PIC idioms and
techniques.  Amongst other things it contains an interrupt handler,
routines to read and write data EEPROM, and shows how table lookups
are implemented on the PIC.  The program contains examples of some of
the more useful MPASM features such as two kinds of macro.  It also
shows such things as how to override the default radix (hex) for
numbers and embed PIC configuration information.  Stylistically at
least it looks more like a "real" PIC program.

; PATTERN.ASM       
; A program designed to illustrate reading/writing data EEPROM
; and timer interrupts.  A table of values is written to EEPROM
; and the processor then executes a "do nothing" loop.  When the
; timer overflows it interrupts the processor and the next value 
; in sequence is read from EEPROM then written to port B where it 
; is displayed on LEDs.  By changing the table any pattern of up 
; to 64 values can be displayed.
; Copyright (C) 1997 David Tait (

	__CONFIG  03FF3                 ;RC oscillator      
PCL     equ     2
STATUS  equ     3                       ;standard register files
PORTB   equ     6
EEDATA  equ     8
EEADR   equ     9
INTCON  equ     0BH
OPTREG  equ     081H
TRISB   equ     086H
EECON1  equ     088H
EECON2  equ     089H

RP0     equ     5                       
Z       equ     2
GIE     equ     7
T0IE    equ     5
T0IF    equ     2
WREN    equ     2
WR      equ     1
RD      equ     0

#define bank0   bcf STATUS,RP0          ;select bank 0
#define bank1   bsf STATUS,RP0          ;select bank 1

magic   macro                           ;magic EEPROM write sequence
	movlw   55H            
	movwf   EECON2^80H
	movlw   0AAH
	movwf   EECON2^80H

	cblock  0CH                     ;variable block  

	; Main program entry point ;

	org     0
	goto    start

	; Interrupt entry point ;

	org     4

; Normally context should be saved before the interrupt service
; routine and restored after but that's not necessary in this program
; because the processor is doing nothing between interrupts.  See
; the PIC datasheet for the recommended procedure.
	movf    EEADR,w
	xorwf   n_vals,w
	btfsc   STATUS,Z                ;EEADR == n_vals?            
	clrf    EEADR                   ;yes, start again at 0
	call    ee_rd                   
	movf    EEDATA,w                ;read EEPROM
	movwf   PORTB                   ;display byte
	incf    EEADR,f                 ;new address
	bcf     INTCON,T0IF             ;clear interrupt flag

start   clrf    PORTB
	clrf    TRISB^80H               ;port B all outputs
	movlw   B'00000111'
	movwf   OPTREG^80H              ;timer 0 prescale 256:1    
	bsf     EECON1^80,WREN          ;allow writing to EEPROM
	call    ee_init                 ;transfer table to EEPROM
	bcf     EECON1^80H,WREN         ;disallow writing to EEPROM
	bsf     INTCON,T0IE             ;enable timer interrupt      
	bsf     INTCON,GIE              ;globally allow interrupts

loop    goto    loop                    ;do nothing forever

; ee_init
; initialise EEPROM from table

ee_init clrw 
	call    lut                     ;get number of table entries 
	movwf   n_vals                  ;and save
	movwf   n_tmp                   ;and again
	clrf    EEADR
	decf    EEADR,f                 ;EEADR = -1
ee_in1  incf    EEADR,f                 ;next address
	movf    EEADR,w
	addlw   1
	call    lut                     ;get associated table entry
	movwf   EEDATA
	call    ee_wr                   ;write to EEPROM
	decfsz  n_tmp,f                 ;another?
	goto    ee_in1                  ;yes
	clrf    EEADR                   ;no, then finished

; lut
; look up table

lut     addwf   PCL,f                   ;add W to PCL to get table entry
	retlw   D'12'                   ;number of entries in table
	retlw   B'1000'                 ;first entry
	retlw   B'1000'
	retlw   B'0100'
	retlw   B'0100'
	retlw   B'0010'
	retlw   B'0010'
	retlw   B'0001'
	retlw   B'0001'
	retlw   B'0010'
	retlw   B'0010'
	retlw   B'0100'
	retlw   B'0100'                 ;last entry
; ee_wr
; Writes byte in EEDATA to EEPROM location at EEADR.  Interrupts
; should be disabled before calling ee_wr.

ee_wr   bank1
	magic				;invoke magic sequence
	bsf     EECON1^80H,WR           ;start write
ee_wr1  btfsc   EECON1^80H,WR           ;write complete?
	goto    ee_wr1                  ;no 

; ee_rd 
; Reads EEPROM byte at EEPROM location EEADR into EEDATA

ee_rd   bank1
	bsf     EECON1^80H,RD           ;start read
	return                          ;read will be complete on return

Here is the MPASM generated hex file (save as PATTERN.HEX):


With my programmers this can be downloaded using:

PP PATTERN.HEX                               (PP V-0.4)
TOPIC -G PATTERN.HEX                         (TOPIC V-0.2)

These projects may not seem very exciting but if you have just built
or bought a PIC programmer and have hurriedly put together the simple
test circuit then seeing a LED flash on and off is exceedingly
gratifying.  I hope you find that out for yourself.  Good luck.

2nd Edition

file: /Techref/microchip/davidtait/first.txt, 15KB, , updated: 2001/4/17 11:15, local time: 2018/1/23 08:17,

 ©2018 These pages are served without commercial sponsorship. (No popup ads, etc...).Bandwidth abuse increases hosting cost forcing sponsorship or shutdown. This server aggressively defends against automated copying for any reason including offline viewing, duplication, etc... Please respect this requirement and DO NOT RIP THIS SITE. Questions?
Please DO link to this page! Digg it! / MAKE! / 

<A HREF=""> microchip davidtait first</A>

Did you find what you needed?

  PICList 2018 contributors:
o List host: MIT, Site host, Top posters @20180123 David C Brown, Isaac M. Bavaresco, Manu Abraham, RussellMc, Van Horn, David, Dwayne Reid, Harold Hallikainen, James Cameron, Sean Breheny, John Gardner,
* Page Editors: James Newton, David Cary, and YOU!
* Roman Black of Black Robotics donates from sales of Linistep stepper controller kits.
* Ashley Roll of Digital Nemesis donates from sales of RCL-1 RS232 to TTL converters.
* Monthly Subscribers: Gregg Rew. on-going support is MOST appreciated!
* Contributors: Richard Seriani, Sr.

Welcome to!