Introduction to PIC 16F84 Microcontroller
Keywords: 16f84, pic tutorial, pic microcontroller, microchip controller, PIC16F84, Hello World, LED, DIP, timer, serial port, RS232, C programming The photo depicts a PIC 16F84 microprocessor. This tutorial serves as guide for absolute beginner to microprocessor. No programming or electrical experience needed to complete understand this tutorial. This text will guild you to the most basic program in controlling the processor such as turn on LEDs at output port, read from an input port, timing control for this type of processor. We will look into example that turn the LEDs on the processor on and off at a specified time rate. This tutorial will give you the most basic library of codes that are useful and can be further manipulate in your future more advance project with PIC Microprocessors.
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Motivation and AudienceThe world of technology is advancing in a faster pace each day. Our common use tools have entered a digital phase where everything is computerized. From analog phone, we evolved to digital phone. In automobile industry, we have on board microprocessor to control fuel injection. Motivated by this great technology evolution, this tutorial will act as your introduction course to the basic of microprocessor.
You need not to have any background in microprocessor nor how to build a rocket to understand this tutorial. You only need the desire to learn, some time in your hand and the will to read through my lack of English Grammar writing and also some parts below.
The rest of the tutorial is presented as follows: o Introduction to 16F84 Microprocessor o Induction to microprocessor programming Part List US-based vendors include Jameco, Digikey, JDR and Radio Shack. Note: Boondog has no association with these vendors. Attempts were acquire all parts from a single vendor. Part numbers for common resistors are not given.
|
|
Introduction to PIC 16F84 Microcontroller This tutorial will walk a beginner to Microcontroller through the basic principle of the PIC family Microcontroller. Mainly focus on the 16F84 just simply because its simpler than other type to understand.
For those who dont know what a Microcontroller is; It is a brain of a digital device that operates in a close loop control process. It has I/O port to take in interrupt or data and send out signal to control relay or just simply a motor or that type of mechanisms. The close up of a Microcontroller Pins and its functions
Ports The PIC 16F84 has two ports; each can be individually program as input or output. PortA is a 5bits/lines (mostly use as input), and portB is 8 bits/lines (normally use as output). You can think of the PIC controller as a fish tank with all the water lines running in and out from it. Some of the line you will hook up to the water coming in, the other for water coming out. Remember, dont mistake the port as a single line; the two ports are each consists of multiple lines that can be use for parallel data transfer.
Introduction to Architecture of PIC 16 The PIC 84 has two separate blocks of memory; Program memory and file registers memory. Program memory: PIC84 is 14 bits and can contain 1K of code. This is important to know because you dont want to write a lengthy program or put to much comment on to a program and it will not fit into the PIC.
File Registers: you can think of this as drawer in a cabinets. Some of the drawers are reserved for special purposes. These register are located at reserve address that the designed for the PIC to recognize and have higher priority then other address when it comes to interrupt (Read on). Below are the most basic ones
Source: Easy Picn, David Benson, p.10 In this section, I only emphasize on the important features that are necessarily to better understand this tutorial. For a more detail explanation, I suggest the book Easy Picn by David Benson
Working register: ***This concept is important***** Picture this; you can only open one drawer of the cabinet at a time. Therefore, to copy and transfer some thing from one drawer to another, you need to have a temporary space to dump data to. To move a shirt from drawer #1 to drawer #3. We do this; open drawer #1, move shirt from drawer #1 to working register, close drawer #1, open drawer #3, move shirt from working register to drawer #3, close drawer #3. This is the only way to move data around the PICs registers.
Program Counter: PIC controller, like many other controller; its execute code line by line. Let say the PIC execute line #1. How does it know to go to line #2 or jump to a section after a goto instruction? Well the Program counter get updated every line after the PIC goes through a line of code. Its keep track of which part of the program to jump to next.
Status Register: Status register keep record of result of operation. Two important items are Zero flag and Carry flag. Imagine this; you subtract decimal base number 5 to number 5. The result is zero. The Status register have a bit that get set to 1 if the result is Zero from any operation has just performed by the controller. Similar with the Carry bit. It detect if there is a carry after an operation. I will emphasize this better in the Programming section.
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Building the circuit This circuit helps to develop a sense of data flow within a PIC controller. Its simply let you controller the I/O of the PIC to turn on a LED at portB, or scan for an interrupt at portA. A quater was there to show the actual size of the board.
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Purposes of the parts? Zip Socket Repeated burn-and-drops during development often require removing and re-inserting the PIC16F84. A zero-insertion-force (ZIF) socket eliminates the risk of accidentally bending the PIC's pins with an IC pulling tool. By releasing the ZIF socket's lever, the chip is easily removed by hand. Closing the lever securely fixes the chip in the socket.
DIP Switch Circuit
An eight position DIP switch is interfaced to Port A (3 of the DIP's switches aren't used). This is equivalent to PortA 0, 1, 2, 3, 4; You can set them on or off easily with the switch. The circuits lay out is not important; but try to arrange everything is a neat design. This will give you less headache to trace any error in wiring or lose connections. If you are thinking of future expansion of the board, build the I/O node connection such that you can easily tap into the input or output to for additional circuit expansion.
LEDs Eight LEDs hook up to Port B. The eight LED will response to the output from PortB corresponded to your program.
Picture of the board with a 4.8 V battery attached
This is the back of the board showing the wiring.
Tips to better and cleaner soldering.
Link to pdf files on cleaner soldering technique: soldering.pdf
Testing the circuit with out the PIC. Power up the circuit with a 5 Volt source. Use a multimeter and check for continuity in every wire that you use. Turn the Dip Switch on and measure the voltage across it. Run a wire from the positive of the source to pin 6-13 of the Zip pocket; the LEDs suppose to light up. And make sure you connect the clock appropriately.
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Programming preparation You will need a text editor to write you code with. The best one is using a note pad that come with every Microsoft window Operating System. Just make sure that when you save it; save it under *.asm extension (Choose Save As, and Save As Type should be set to All Files). Then to convert the files from *.asm to *.Hex you can use MPASM v02.15/ or from microchip to convert your files.
To burn the *.Hex to the chip, you can use PiccallW Programmer/ or from PICALL.com. I use the Picall v0.14a beta and have problem trying to burn the chip. I was able to do it with v0.10d. Its up to you, if you think you can make it work then use which ever version you like. But it v0.10 you have to manually check 378 in LPT port in Setting. Then in hardware setting, chose the appropriate kit that comes with your programmer. Mine was a 74LS06 (the name of a chip on the programmer).
So the steps are: Write the program, compile it into Hex, then burn it into the chip. Then, well feel the sense of accomplishment when you LEDs start to light up the way you want it. :o) |
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
The PIC16F84 device programmer ( PIC16PRO40) For simplicity, we use the PicPro Programmer
******************************BE CAREFUL************************** Do not try to remove the chip from the programmer by your thumb. This is a very idiotic way to break the chips pin. Trust me I was there. Use a chip extractor or a flat head screw driver and carefully remove it .
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Program the PIC as easy as ABC For those who have a little background on programming, you should be able to understand this section after a careful review and you will be able to start programming on your own. And for those who already have experience in assembly language, this will just be a review for you. Lets get started Assembly language
Program Structure Comments: Explain the purpose of the program, type of chip, clock type and frequency, Date and authors name, etc Be descriptive about program but not too lengthy. ;---------------------------------------------------* ; Description * ; * ;---------------------------------------------------*
Header: Header contain instruction information of the type of chip and the base of number system
;---------------------------------------------------* list p=16f84 radix hex ;---------------------------------------------------*
Initialization: Here, you define ports, variables ;--------------------------------------------------* porta equ 0x05 portb equ 0x06 ;--------------------------------------------------* The above code tell the chip that porta is define at Hex address 05 and portb at 06
Program: You insert your program codes here ;----------------------------------------------------------------* Start movlw 0xff ;load w(working register)with 0xff tris porta ;teach portb to be an input movlw 0x00 ;load w(working register)with 0x00 tris portb ;teach portb to be an output ;----------------------------------------------------------------* Even though most books do this in the program section. I prefer initialize the port in the Initialization section.
End: The end statement tell the assembler that this is the end of the program ;----------------------------------------------------------------* end ;----------------------------------------------------------------*
The symbol ; will tell the assembler to ignore everything after it on that particular line.
Example 1: ;--------------------------------------------------------------------- ; FILE: helloLed.asm ; AUTH: P.Oh ; DATE: 1.0 - 04/13/02 15:09 ; DESC: 1.0 - Makes B0,B2,B4,B6 LO and B1,B3,B5,B7 HI ; NOTE: Tested on PIC16F84-04/P. ; Page numbers in code are in Easy Pic'n book ; REFs: Easy Pic'n p. 23 (Predko p. 173 is bogus?) ;---------------------------------------------------------------------- list p=16F84 radix hex ;---------------------------------------------------------------------- ; cpu equates (memory map) myPortB equ 0x06 ; (p. 10 defines port address) ;---------------------------------------------------------------------- org 0x000 start movlw 0x00 ;load W with 0x00 make port B output (p. 45) tris myPortB ;copy W tristate, port B outputs (p. 58) movlw b'10101010' ; load W with bit pattern (p. 45) movwf myPortB ;load myPortB with contents of W (p. 45) circle goto circle ; done end ;---------------------------------------------------------------------- ; at blast time, select: ; memory uprotected ; watchdog timer disabled ; standard crystal (4 MHz) ; power-up timer on ;---------------------------------------------------------------------
Codes cheat-sheet
For more instructions, refer to page 46 of Easy Picn
Some useful algorithms
Datas transfer Remember, you need to use the working register to move data around. This example show how to display count register to portb in binary movf count,w movwf portb
Datas Direction This instruction define the port to be input or output, a Zero is equivalent to output, 1 is input.
movlw b00000000 ;portb, all lines make output movwf portb
movlw b11111111 ;porta, all lines make input movwf porta
Port Read/Write To read from a port, you would move the content of that port into Working Register first.
movf porta, w ;Read line in from porta movwf temp ;Store it into temp space
To write out to output port, just simply copy Working Register to that defined ports name
movwf portb
Loop, Using Counter to control loop In this example, we are making line 0 of porta as a start button, and line 1 is the stop button. We want to detect both button and execute the appropriate process depend on which one was execute.
Loop btfss porta,0 ;Detect button press goto chkb ;If not, check b goto int ;If yes, goto start interupt
chkb btfss porta,1 goto loop goto stop ;If stop button, go to stop
Subroutines
call pause
pause movlw 0xff ; set w = 255 decimal movwf mCount ; mCount = w loadN movlw 0xff ; set w = 255 decimal movwf nCount ; nCount = w decN decfsz nCount, f ; nCount-- goto decN ; if nCount != 0 then repeat nCount-- decfsz mCount, f ; else decrement Count goto loadN ; if mCount != 0 then ; reload nCount to 255 and decrement return ; else exit subroutine
This example illustrates how you would call a subroutine during program execution. For those who are not familiar with subroutine, think of it as stopping in the middle of lunch to get a soda and then come back to eat your sandwich. During the process, you temporary stop eating the sandwich to get the soda for this we use call [label or address here] to jump to the address that the code of subroutine is written. But you have to get back the right point where you have stop eating for this you will use return to return to we the program was left of. We can also use retlw k to return from a subroutine and automatically load Working Register with a constant
Example 2: This program call return_literal.asm
;-------------------------------------------------- ; This program add an offset to a specified register ; and return a predefine value at that address ;-------------------------------------------------- list p=16f84 radix hex ;-------------------------------------------------- org 0x00 Start molw 0x00 ;load w with $00 tris portb ;teach port B all outpts clrf portb ;clear all line on portb to low char molw 0x02 ;test number call seg ;call subroutine movwf portb ;Display result again goto again ;done
seg addwf pc,f ;add w to PC, result in PC retlw 0x3f ;0 seven segment retlw 0x06 ; retlw 0x5b ; The value return are what ever that you are controlling ; If you hook this up to a 7 segment display. Then depends on ; your connections, you will turn on the appropriate bits.
end ;---------------------------------------------------------- ; at blast time, select: ; memory uprotected ; watchdog timer disabled ; standard crystal (4 MHz) ; power-up timer on ;-----------------------------------------------------------
Time control Example 3: timer1_0 - blink an LED at a desired rateExample 1's LED/DIP circuit can be used to experiment with timing routines. The programming objective is to blink the LED attached to line RB0 on Port B every 32.8 milliseconds. The ASM code follows:
; FILE: timer1_0.asm - WORKS! ; AUTH: P.Oh ; DATE: 1.0 - 04/14/02 16:00 ; DESC: 1.0 - Internal timer, blink LED every 32.8 msec ; NOTE: Tested on PIC16F84-04/P. ; Page numbers in code are in Easy Pic'n book. ; 4 MHz crystal yields 1 MHz internal clock frequency. ; "option" is set to divide internal clock by 256. ; This results in 1 MHz/256 = 3906.25 Hz or 256 usec. ; tmr0 bit 7 (128 decimal) is checked, thus yielding ; 128*256 usec = 32.8 msec delay loop ; REFs: Easy Pic'n p. 113 list p=16F84 radix hex ;---------------------------------------------------------------------- ; cpu equates (memory map) portB equ 0x06 ; (p. 10 defines port address) count equ 0x0c tmr0 equ 0x01 ;---------------------------------------------------------------------- org 0x000 start clrwdt ; clear watchdog timer movlw b'11010111' ; assign prescaler, internal clock ; and divide by 256 see p. 106 option movlw 0x00 ; set w = 0 tris portB ; port B is output clrf portB ; port B all low go bsf portB, 0 ; RB0 = 1, thus LED on p. 28 call delay bcf portB, 0 ; RB0 = 0, thus LED off call delay goto go ; repeat forever delay clrf tmr0 ; clear TMR0, start counting again btfss tmr0, 7 ; if bit 7 = 1 goto again ; no, then check again return ; else exit delay end ;---------------------------------------------------------------------- ; at blast time, select: ; memory uprotected ; watchdog timer disabled ; standard crystal (4 MHz) ; power-up timer on ;---------------------------------------------------------------------- To have a 0.5 second delay, we will need to put this in a loop that will need to execute approximately 15 times. cnt equ 0x0b .. movlw 0x0e movwf cnt .. .. delay clrf tmr0 ; clear TMR0, start counting again btfss tmr0, 7 ; if bit 7 = 1 decfsz cnt,f ;Decrement counter until it reach zero. Goto delay return |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Comparing data This section shows you how to compare data in your program. For example, let say you want to check if your input data from porta a arrange in binary base is equal to hex base 5. You would first read move data from porta to Working Register. Then subtract this from hex number 5. Then we will check the zero flag in the Status Register to see if it is set or not. If it is set, this mean that result from the calculation is zero. Therefore out number is hex 5.
movf porta,w ;load porta to Working register and then sublw 0x05 ; subtract 5 from it. Result in W
btfss Status,2 ;check if zero flag is set goto code here ; If not goto code here ; if Yes..
Here is a useful table of to check for flag in the Status Register.
For this code: sublw N ;subtract N from W
Practice good programming style: Be sure to use appropriate comments to describe your code. Example
Molw b00000001 ;Turn on line zero of portb Movwf portb
Well it is obvious that it will make line zero high. But we might want to say, turn on led or buzzer. That way, we dont have to trace back what line Zero really turns on. Timing awareness is important. Let say you want to keep on polling line 0 of porta for detecting people enter a room. Let say the first person enter the room. Then you want your code to jump to a location to execute certain steps. Keep in mind that you dont want to make these codes too lengthy (too much time to execute) because you might not get back to the polling process before the second person enter the room. Therefore your program will not be efficient. |
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Final WordsYou should be able to start coding for the Pic as of now. These basic skills will be the building block for your future works. Dont under-estimate the power of a small chip. With the right program, build a well plan circuit, burn the program to the chip; you can put this chip to work with the computation power greater than any human being. :o) Hope you enjoy the exercise. And hope that you learn something from it. If you have any question regards my tutorial. Click here to email me ReferencesIn print o Easy PIC'n by David Benson at first glance appears to be a tersely written book. After you build and program your first PIC16F84 circuit, you begin to appreciate the book's concise style and excellently explained assembly code. Easy PIC'n as well as PIC'n Techniques is published by Square 1. o Pic your Personal Introductory Course 2nd, John Morton o Picn up the pace by David Benson, Publish by Square1 o Microcontoln Apps, by David Benson. Publish by Square 1 o Pic Basic Programming and Progjects, Dogam Ibrahim, Publish by Biddles Ltd
Web o Boondog http://www.boondog.com/ o A PIC16F84-based ultrasonic sensor. o Cooper Tools http://www.coopertools.com/ o Picall Programmer http://www.picall.com/ o Jameco Electronic http://www.jameco.com/
|
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
|
|
|