Microchip Davidtait First.txt
My First PIC Project
====================
David Tait
david.tait@man.ac.uk
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 http://www.man.ac.uk/~mbhstdj/files/test.gif for a more readable
version).
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
OPTION
LOOP SLEEP
INCF 6,F
GOTO LOOP
END
The program is written for MPASM (Microchip's free assembler available
from http://www.microchip.com). 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:
:0C0000000030660062006300860A0328DE
:00000001FF
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
OPTREG EQU 81H
STATUS EQU 3
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
CLRF TRISB^80H ;SET PORTB TO ALL OUTPUTS
MOVLW 0AH
MOVWF OPTREG^80H ;ASSIGN PRESCALER (1:4) TO WDT
BCF STATUS,RP0 ;SELECT REGISTER BANK 0
INCF PORTB,F ;TURN ON RIGHTMOST LED
BCF STATUS,CARRY ;CLEAR CARRY
LEFT SLEEP ;WAIT FOR WDT TIMEOUT
RLF PORTB,F ;TURN ON LED TO LEFT
BTFSS PORTB,MSB ;REACHED LEFTMOST?
GOTO LEFT ;LOOP IF NOT
RIGHT SLEEP ;WAIT FOR WDT TIMEOUT
RRF PORTB,F ;TURN ON LED TO RIGHT
BTFSS PORTB,0 ;REACHED RIGHTMOST?
GOTO RIGHT ;LOOP IF NOT
GOTO LEFT ;START NEW CYCLE
END
MPASM should assemble the program to give this hex representation:
:100000008601831686010A3081008312860A031056
:100010006300860D861D08286300860C061C0C28CC
:020020000828AE
:00000001FF
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 (david.tait@man.ac.uk)
PROCESSOR 16C84
__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
endm
cblock 0CH ;variable block
n_vals
n_tmp
endc
;**************************;
; 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
retfie
start clrf PORTB
bank1
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
bank0
call ee_init ;transfer table to EEPROM
bank1
bcf EECON1^80H,WREN ;disallow writing to EEPROM
bank0
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
return
; 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
bank0
return
; ee_rd
;
; Reads EEPROM byte at EEPROM location EEADR into EEDATA
ee_rd bank1
bsf EECON1^80H,RD ;start read
bank0
return ;read will be complete on return
end
Here is the MPASM generated hex file (save as PATTERN.HEX):
:020000000E28C8
:0800080009080C060319890127
:10001000442008088600890A0B110900860183160E
:10002000860107308100081583121C2083160811F1
:1000300083128B168B171B2800012C208C008D003F
:1000400089018903890A0908013E2C2088003A2089
:100050008D0B22288901080082070C3408340834EB
:1000600004340434023402340134013402340234DE
:1000700004340434831655308900AA30890088146A
:100080008818402883120800831608148312080079
:02400E00F33F7E
:00000001FF
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
4/Feb/97
file: /Techref/microchip/davidtait/first.txt, 15KB, , updated: 2001/4/17 11:15, local time: 2025/1/12 14:47,
|
| ©2025 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? <A HREF="http://linistepper.com/techref/microchip/davidtait/first.txt"> microchip davidtait first</A> |
Did you find what you needed?
|