ISBN D 0? 1q51,'ra-0
ttnn llilXIJl
E3 PIf@
Mitrrtrcontroller Experiments fsr the Evi| Eenius
Evil6eniu5series 123Robotics Experimentsfor the Evil Genius Electrcnic Gad|etsfot the Evit Genius:28Build'it'yourself Prciec! Electonic Ci/cuits for the Eril GeniL.s:57Lesso^, with Prciects 123 PI(P Microcotltollel Eryeriments fol the Eril Geniut Mechatonics fol the Et il Genius:25 Build-it'youtself Prcject' 50AwesomeAutomoli'e Prcjectsfor the EviI Genius Sotat Energ! Proiectsfor the Evil Genius:16 Buikl'it'yoarselfThemoelectic MechdnicalPrcjects
and
25 Build'it'Yourself Prcjec1 Bionicsfol the Evit GeniLLs: MORE Etectronic Gadgetsfor the Evil Genius:28MORE Build'it'yourself Proiects
1 A 3P I E @
Mitrrotrontroller Experiments for the Evi| 6enius MYKE PREDKO
McCraly-Hill New York Chicago SanFrancisco Lisbon London Madid Mexico Cily Milan New Dcthi SanJuan Seoul Singapore SydDey Toronlo
Catiloging-in-PublicttionData is oDlilc with the Library of Congfcs!
copyrightO 2005byTheMcCraw-Hill CommpinicqInc.All rightsfcscrvedPrinledin thc UniredStolesorAnerica.Exceplaspermittedundcrthe UniledStalcsCoPvrightAct of 1976'to or dislributedin nnyforn or by anymcan$,otslored pnn of thispublicationmaybe reproduced in a dalabaseor rotricvalsyftD.vilhout theprif writLenpcrnhskn ol rhepublishcr' 3 4 5 6 7 8 9 0 Q P D / Q P D0 I 0 9 l J 7 ISBN 0-07145142-0 Thesponhtug edint lot thi\ hook trasJkd!)Bisr Ml the?roductiontttll!tui$r LLC ThcIrt dituctorJol easPMtle A. Pelton.ft wat NetibTinw Tat by l kAllistet PttblishiSService!, th! &v0 ,,a! Ahthory kndi. Ptink anl hantl bt Qu.h.cot/Dubuque.
{}Jlllbk::\,ti,''*t"nrocvored'ocid'riccraPcrconl0ini'saminiDUDor50Pcrccntrccvcred andsalesptomoto useaspr€mirims at specialquanlilydiscounts Mccraw-Hillkloks arcdvailable pleasewrileto thoDirectof tions,or tor usein corponlcLr.iningpro$am$ForInoreinformation, York,NYl0l2l-2298. O' contacr PcmPlaTa.New I'|ofessional,Two ofSpccialSales"McGraw-H
lnformatio! conlainedin this woik hasbeetrobtainedby The Mccraw-Hill Conpa_ bclieledto be reliabloHowever,neithcr nicr lno.("Mccraw-nill") lron sources Mocraw-Hill nor ih authoreSuaranteerhc accuracyor comPlebnessof any informdlbr hcrcir.andneitherMccraw-Hillnor itsauthosshallberesponsible tionpublished dnr eros, onn$iornor danagesarisingoul oi useof thisinfomation.Tbiswork h ural Mccraw Hill and its authos are suPplving with thc underst.nding Dublished informationbut arenot attempnngb renderprofe$ional senicesIi suchserricesare prolesional shoLrldbe soughl. required.tho alsislane of an aPProPnate
ft LOnIenrS gF
w€n w)E w"
w
w.
wt
t F&as i['tq ffii
ffi
asSt J6r!6 iqost
ff
{b .{.
Acknowledgments About the Author
SectionOne Underthe Coversof the PIC16F684 EXPERIMBNT1
I/OPins
EXPERIMENT 2
Configuration word
EXPERIMENT 4
PIC MCU Variable Memory,Registers, and ProgramMemory in Simulating cFlash.c MPLAB IDE
SectionTko IntroductoryC Programming
t3
18
27
C DataTypes
29
EXPERTMENT 7
ConstantFormatting
31
EXIERTMENT10 EXPERTMENT 11 EX?ERTMENT12
EX?ERTMENT13
ConditionalLooping
45
EXPERIMENT 16
TheFor Statement
46
Assignment Statements Expressions lJrtwrse uperators
33 35
LogicalExpressions ConditionalExecution Usingthe If Statement 39 NestedConditional Statements
SectionThree SimplePIC@MCU Applications 51 EXPERTMENT 17
BasicDelays
53
EXPERTMENT 18
PTCkit1 Sequencing StarterKit LEDS
55
BinaryNumberOutput UsingPICkit 1 Starter Kit LEDS
56
EXPERIMENT 20
BasicButtonInputs
58
EXPBRTMEN'r21
DebouncingButtonInputs 59
EXPBRIMENT22
MCLR Operatiorl
6I
EXPBRIMENT23
EndingApplications
63
EXPERIMENT 19
20
EX?ERIMENT6
EXPERIMENT9
EXPERTMENT 15
L4
28
EXPERIMENT8
43
x
VariableDeclaralion Statements
EXPERIMENT 5
q.f,
TheSwitchDecision Statement
EX?ERMENT14
t
Introduction
EXPERTMENT 3
ix
SectionFour C Language Features67 EXPERIMENT24
Functions andSubroutines 69
EXPERTMENT25
GlobalandLocalVariables70
EXPERIMENT26
Defi[esandMacros
7I
EXPERIMENT27
VadableAuays
73
EXPERIMENT28
Structures andUnions
75
EXPERTMEN.T 29
PointersandLists
'76
EXPERTMENT30
Character Strings
79
EXPERIMENT 31
LibraryFunctions
81
4I
SectionFlve PIC16F684Microcontroller 89 Built-in Functions ExPERrrtNT32 Brownout Reset
91
ADC Opcratiotl EXTERIMENT'33
93
34 ComparatolOperation EXpERINIENT
96
EXPER|"I|NT35 Watchdog'l'imer
99
36 ExpERlNlFrNr
Short Timer Delays
UsingTMRo 37 Exr,r,RrNrENr'
Usingl'MRt ComparingClock Oscillators
106
r'40 Pin Rcsislarce LlxPEnt\'lr-tN
t09
PwM SignirlJl t l | 41 Cunerirung F\11 RrN,rE\
Rcaction-TimeTester
140
52 ExPERltvtENT
Rokenbok@Monorail/ Tiaffic Lights
143
LED Seven-Segment Thelmometer
t46
PIC MCU "Piano"
151
Model Railway Switch Colltrol
lfJ
54 EXPDRIMENT
56 PC OperatingStatus ExPERIMENT Display
ExIERIMENT57 Thc asmTemplate.asm
SectionSix Interl'acingProjectsfor the PIC@Microcontroller ll'7
58 ExPERIMENT
ExpLRIMEN]43 Driving a Scvcn_Segmcnt
59 Loadingthe WREG and EXPERTMENT
L\"r Rr\I N"4 |
45 ExPERTMENT
LED Matrix DisPlaYS
,16 LCD Display EXPERTMENT ,lT ExpFtRrNrENl
Filc ard BasicDirectivcs 160
124 126
ProduciDg Random Numbers
128
ExpERrvrENr,l8
Two-Bit LCD Display
129
EXPERI4nNT49
Switch Matrix KeYPad MaPPing
t31
SpecifyingProgram MemoryAddresses
161
SavingIts Coitents
164
60 ExPERtMENT'
Detining Variables
165
6l EXI,ERIMENT
Bitwiselnstructions'i6'7
62 EXPLRTMENT
Additionlnstruclions
168
63 EXPERIMENT
AddLibs: Strange SimulatorResults
170
ll9
M u l t i l ' l cS c v q n - S c g m c t r t 121 LED Displays
156
SectionEisht Introductionto PIC@ MCU Assembly Language 159 Programming
I 42 StolingandRctrieving Exl,r-rRrN4BN t14 Data
DirectlY I-ED DisPlaY homthcPICl6F6U4
.
51 EXPERTMENT
EXlrinrMENT55
104
Mcasulcmcnts
LED Display 138 Pumpkin
53 EXPERIMENT
102 Usiig theTMRoPrescaler
137
50 EXPERTMENT
101
Exl,trtIMENr'38 LongTlnler Delays
f 39 ExPERTMEN
Section Seven SampleC Microcontroller Applications
64 EXPERIMEh*T
Sublractionlnstructions
65 EXPERTMENT
Bank Addressing
Bit lnstructions EXPERTMENT'66
Contents
']71 173 1'75
EXPERTMENT 67
r7'7
Bit Skip Instructions
EXPERIMEh-r 68
ConditionalExecution
178
EXfERTMENT 69
declszLooping
180
EXPERTMENT 70
Subroutines
181
EXPERTMENT 7l
Defining and ImplementingArrays
EXPERTMENT86 PIC MCU Instrument Interface
231
EXPERTMENT8T SoundDetection
235
EXPERTMENT 88 Multiple Miqoswitch Debouncing EXPERTMENT 89 EXPERIMENT 90
EXPERIMENT 72
LogicSimulation Using thePlC16F684
EXPER]MENT 73 TheC "Switch" Statcmont
188
191,
ExPEnIMENT74
Dcfines
ExPEnTNIENT 75
ConditionalAssembly 197
ExPERti\4ENr 76
Macros
194
199
EXPERIMEN].77l6-BitValues/Variables 201 ExPEnTMENT 78 EXPERIMENT 79 EXPERIMENT 80
UniversalDelayMacro 203 High-lavcl Pro$amming 205 lmplementing Read-Only 208
AIrays EXPERIMENT 8l
Data Stacks
210
EXPERTMENT 82
CircularBuffers
212
EXPERTMENT 83 Readingandw ting the
EEPROM Data Memory 214
SectionTen Sensors ExPERrMENr34PIC MCU BS2User lnterfacc
227 224
EXPERTMENT 85 PIC MCU BS2Keypad Interface 230
{",t,
:i i',1'
Light Sensors
23'7 238
I82
SectionNine PIC@Microcontroller AssemblyLanguage '187 ResourceRoutines
f"\
Infiared (IR) Surface Sensor
239
ExpERlMENr9l Intcrfacing10Shary cP2D120 Rangirg Object Sensors
242
ExPERTMENT 92 Do-lt-Yourself IR Object Sensor
243
ExPERTMENT' 93 lR Object-Ranging Sensor
24'7
ExpERTMENT 94 UltrasonicDistancoRangeSensor
249
ExPERrMENr95RoborIRTag
251
SectionDleven Motor Control
255
EXPERIMENT 96 DCMotor Driven Usi g the CCPPWM and Using a Potentiometer Control 257 E x P f R r v F \ r1 , 7 D C M o t o rC o n t r oxl i l t SimpleTMR0 PWM
261
ExpERIMENT98ControllingMultiple Motors with PWM aDd Bs2lntcdace
264
EXPERIMENT 99 Bipolar StepperMotor Control
265
EXpERIMENT 100 UnipolarStepperMotor Control 269 EXPERIMENT 101 Radio-Control Model Scrvo
Control EXPERTMENT 102 Multiple ServoControl SoftwareStructure
Contents
272 2'74
*J
?: !:"{a' iil
RobotBase 103Two-Servo EXPERTMENT 27'7 withBs2lnterface SectionTwelve SolvingProgramming Problemsin PIC@ Microcontroller AssemblyLanguage279 t ultiplicatitrn E \ p r R r M\rr 1 0 4 L i g h l - B iM with a 16-BitProduct 280 ExpERrMENl105 Division of a 16-Bitvalue by an Eight-Bil Valuc 282 a NumberUsing | lu6 Squrring Exr,r'RrMr'\ Finite DifferenceTheory 284 107 Find lhe SquareRool of a EXPERTMENT 28(t 16-BitNumber 108 Converlinga Byte into EXPERIMENT Hex, Three Decimal,T\'r'o Eight Binary ASCII or 289 Bytes 109 Produccthe Even Parity EXPERTMBNT 291 Valuesfor a Byte 1 I0 Sort a List of 10Eight-Bit EXPERTMENT ValuesUsingthe Bubble292 SortAlgo tllrn EXpERIMENT 111 Encrypt and Decrypt ull ASCIIZ SlringUsing a SimpleSubstitution 294 Algolithm E x p E R r \\4r lrl 2
Number Sequence
113 Find the LargestCommon EXPERTMENT FactorofTwo Eight-Bit
Numbers
298
SectionThirteen ZipZaps@Robot 301 EXPERIMEN T 114 Characte zing the
Zipzaps
303
PIC MCU PowerSupply 305 EXPERTMENT'115 116 EXPERTMENT
PIC MCU Electronics 307 PCB
I 17 EXPERIMF,NT
IRTV RemoteControl 310
I18 EXPERIMENT
Molor andSteering Control
311
119 EXPERTMENT
BasicThsk-Control Software
120 EXl ERTMENT
lR RemoteContlol
121 ExPERTMENT
and Lighl Sensors Followirlg
122 EXPERTMENT'
IR ObjectDetection 318 Sensors
123 ExPERTMENT
IR Linc-Followirlg Sensors
Index
C c n e r a t ce F i h o n a c c i
ii$ i--; !'1
# 4_.1 *
i)
t-: vti.r
29'7
Contents
316
320
327
F" 'tr
{'}
FcknouJledgments
!tj..:. i't!
.;:
tlt!!).:tt
;.::!:! rir:i,: :?rra,
-\ri
l't ij
q My edilor at Mccraw-Hill, JudyBass,who consistentlyrespondsto my questionsand suggestions, regardlessof how dunb they are, with good humor and thougltfulness.
This book would not have been possiblewithout t1le help, suggestions,and time from the fbllowing indi viduals: . CarolPopovich,Greg ADderson,Joc Drzewiecki,AndreNemat,and Fanic Duven$ho ha\e helpednre hageol I\4i(rochrn understandwhich productswould be besl suitedfor this book,and havebeenwilliDgto .pcndrimewith me lo undersrand my rcquircand m9nts,answermy legionsof questions, suggestavenuesto follow that hadn't occurred
supportstallfbr HT-Softandlhcir technical quicklyandholping D'ryqucstions answering to cxplailtheiDnerworkingsofthe PICC is Lirccomtiler.The PICC.linc of compilers proand tool for thebcginnct a lrcmcndous lo re.lc:)iunrlrlikc,andoneTncvcrhcsitatc onmlcDCl. andlhes!uBradNorth,RichardBonafede, Schoolilr dentsot RickHansenSccondary Onf.lrio,lbrhelpingmeto learn Missassauga, learn moreabouthowstudenls(andteachers) andthc PIC electronics, aboutprogramming, MCU BlairClarksonaDdDnvcPiloleat the Oltario pushingmeto CentreinToronlo,I'or Sciencc concepts to peoexplairbasicmicrocontroller Sumo" plethatluve built theTAB Electronics Botat a workshopandwantto do norc with ir. lhe BS2i rt'rfaccandRobotIR Tig cxpcrimentsarea direclresultofthiswork.
lo bc oneol lhd be(l lhc PIC MCU continucs .uppo cd dc! ice.on lir)e.3ndI !\ouldlike lo thalk the many individualswho havetaken the time lo put informationand projectson rhe lnlefncla\ \rcll assupporlandhclpntheN trying to better undclstandthe PIC MCU or get their applicalionsup and ruDning.
.
fbr ideas,answcrs Celeslica anditsemployccs questions, to and opPortunities to straDge expandmy lcchnicalhorizons,
.
My daughterMarya,whohasgrownup with a fatherlhatis alwaystryingout ncwprojecls on hcr.Shctricsthemout wilh cnlhusiasm needa bit of despitethclhcl theygenorolly tuningbelorctheyworkperlcctly.
.
for kecpingeverything My wilc Patience, daughler cvcnwhenour youngcst togethcr, Talithawassick,andfor havingdinneron the slove,evcnwilh measkinghc! 10do a"quick read"of a sectionor two.I couldn'tdo anyof it withoulyou.
To all ofyou,thankyoufor all youunselfishhelP expcdences, and andwillingness 1()shareyourideas, enlhusiasm for lhisbook. mgke
Acknouledgments
httpJ/rilirur.mske.Eom
ix
l.-ir (*
Nl"
{tr
s{n ;:.! f*
{,n
,')'$.iifi : ::i,ilfi !i!i:.1.-iti::i1i ii'ii#iirt ill,i:i$[ii]{g{S"*; i{w
Futhor Fbout the M ffi EGH @ W{ €w ffi
$SSg Sr$ss ffi
ffi
KS&&{ffi€
in Torontq Canada,a supplielof printedcircuitboardsto the comMyke hedko isTestArchitectat Celestica, 123Robotitr Prcjectsfor theEvil puterindustry.Aln expedenced author,Myke wroteMccraw'Hill's best-selling Progammingand CustomizingPICMirrc Microconlrolkrs, Genius;PICmicrcMictocontoller PocketRefercnce; RobotContollers;andotherbooks,andis theprincipaldesignerof bothTAB SecondEdition;P/oSramming EElecironics BuiM your Ov,nRobot kits,
h .tJ
5 {)
+-, ,.t
About the Author
Introduction When I wrote my first book on the Microchip PICP microcontroller (commonly abbreviated to "MCU") almost10 yearsago,the mostcommoncriticismI receivedaboutthe book wasthat it took too long to get to the projects.This is quite foreign to me becauseI tend to leam a new device,like a microconftoller,by first reviewingthe datasheets for the part's electrical information,workingat understandingthe architecture andhow it is programmed,and endingwith understandingwhat kind of developmenttools are availablefor the part.Looking over this list of tasks,it is quite obviousthat they cameaboutwith my backgroundand training.Being a teenagerin the 1970sand goingto universityin the early 1980qtherewasn'tthe variety of easy-to-work-with devicesthat are available today,and the sophisticated personalcomputer-based developmenttools that we take for grantedwerenot evenbeingconsidered, let alonebeingdevelopedor sold.My method for learning about a new part is effective for me and a result of the situation I found rnyself in when I first started working with electronics Today you can setup a development"lab" and createa basic applicationfrom scratchfor the PIC MCU in lessthan 20 minutes usingMicrochip's MPLAB@integrated developmentmvironmmt (IDE) andPlckitrM 1 starterkit with HT:.soft'sPICC LiterM c compiler. The purposeof this book is to introduceyou to the MicrochipPIC MCU and help you understandhow to createyour own applications. In this introduction, using the PICkit 1 sl2irterkit printed circuit board. (PCB) andfree developmenttoolsfrom Microchip andHT-Soft,I will showyou how easyit is to createa simplePIC MCU programthat will flashone of the light-emitting diodas (LEDs) on the PICkit 1 starter kit. As you work throughthe book,your understanding of the PIC devicewill increaseto the point where you shouldbe comfortablecreatingyour own complex applications in both the C programming languageaswell asassemblylanguage. The PICkit 1 starterkit (seeFigurei-1) contains everythingyou will needto leam how to createand testyour own PIC MCU applications. This includesa programmerPCB (seeFigurei-2), a universalserial bas (USB) cableto connectthe PICkit 1 starterkit to your PC,a CD-ROM containingthe sourcecodefor the applicationspresentedin this book,two PIC MCUs,an eight-pinPIC12F675,and a 14-pin PIC16F684. In this book,I will be focusingon the PIC16F684becauseits 14pins allow a greatervariety of different applicationsto be built from it, but you will also gain experiencewith the eight-pin PIC12F675.
On the back coverof the book is a web link that you canuseto order a PICkit 1 starterkit for usewith this book.If you do not buy a PICkit 1 starterkit, the sourcecodecanbe dolrinloadedfrom my web site (www.myke.com). In this book, I will be working exclusivelywith Microsoft Windows.I recorrmend that you use the latestversionavailable(at this witing it is Windows,XP SP2)whenworking with the PICC Lite compilerand MPLAB IDE tools usedin the book.Development toolsare availablefor Linux, althoughnot for Apple MacintoshOS/X (but you shouldbe ableto get the Windowssoftwareto work from an emulator).You will find that the softwareworks well underWindows. If you look at the CD-ROMSthat comewith the PICkit 1 starterkit, you will find they havethe MicrochipMPLAB IDE and HT:Soft PICC Lite compiler developmenttools that are usedin the book. Although you could load theseprogramsonto your PC,I recommendthat you downloadthe latestversionsfrom the Microchip and HT-Softweb sites.These tools are continuouslyupdated(duringthe period that this book waswritten,MPLAB IDE had five upgrades, two of them major and changedhow someof the operationsare performed)to includenew featuresand PIC MCU part numbers,and to fix any outstandingproblems.In this book. I usedMPLAB IDE version7.01
Figure il The Microchip PICkit I stsrterkit enablesyou to createyour own PIC MCU applications and to testthem out easily qnd inexpensively.
o.,
o
. i . n , ; :" 3 o . . & q < r . r . , . .
.dG9
EmbeddedSv$em Franc "o san t 0nlelence
.,"-..,,P, I:S:,"f,'i.'::.i'i.Yrf"!.'*...,"-..,
Figure i-? The PICkit I starterkit's PCB consisxof programmercircuitsalong with eightLEDI, a switch, and a potentiometerthat enableyou to easilylearn how to program and accesstheperipheralfeqturesof the PIC MCU.
and PICC Lite compilerversion8.05.With the versions that you use,you may seesomedifferencesin look or operation,but the featurespresentedin this book will all be present.If you are confusedasto how to perform someoperation,you canconsultthe T[torial sectionof MPLAB IDE, which canbe found under the Help pull-down. To start settingup the softwareneededto start go to developingyour own PIC MCU applications, www.htsoft.com, asshownin Figurei-3.PICC Lite is a free,full-featuredC compilerthat supportsquite a few of the differentPIC MCU part numbers(includingthe PIC12F675and PIC16F684includedin the PICkit 1 starterkit package).Next click "Downloads"and then select"PICC Lite (Windows)"(seeFigurei-4).To downloadPICC Lite compiler,you will haveto register with HT-Softat no charge(seeFigurei-5).To do this,follow the instructionson the pageshownin Figurei-4.It shouldgo without sayingthat the page will probablynot look exactlylike the figureshere,due to the delaybetweenwhen I havewritten this and whenyou actuallyaccessthe web site. The retail PICC compileris capableof building codefor literally all the PIC MCU part numbersand doesnot haveany of the restrictionsof the PICC Lite compiler. After registering,the PICC Lite compilerinstallation softwareshouldstart downloadingautomatically. Dependingon your secudtysettings(especiallyif you useMicrosoftWindows/XPServicePack2 or later), the downloadmay be blocked(asin Figurei-6). If this is the case,you may haveto tum off the securityto allow the downloadto take place.Oncethe program hasdownloaded,I recommendselecting"Run" instead of"Save" (seeFigurei-7).Thiswill installthe PICC
StepI - Go to www.htsoft.com
Figure i-3
I d"e:.;,.
Il;,-.
Figurei - q
94-
.J
d
&at'r!
Step2 - PICC Lire Compilerdownloa,l
!l I i;i /,i4.
.-" € rr. , a
. tj.o I
q ..^:i,i;l: d!!:@
ltfi il,f;:i#;il ;i':ii:f .ri::,:.il":ll
Fiqure i-5 customer
1 , 2 3 P I C @l ' l C [ JE x o e r i m e n t s f o r
Step3 - Registeringa an HT-Soft
the Evil
6enius
lib
Edt
r/i4
FMt6
Iode
rgp
Oo* - .,.y' sl td $ j)s..,a$r"-* € 3- + n
:, ffl im I
r,G@ I oownuas > oomos Download P.oducl Demos and Fra€ Software
@
Registratron is requrredto dowrload.lf)€u ha\€ notalreadyregisteredyou willbe redlrectedt0 a pageattowingyouto register, free 0f charge,or tog n Ityou haveprevjou9ty registefed. D6mos
Faee Software
The demoprog€ms belowa€ inbnd€d l0r prosperllve custome6 ofNI.TECHSotwarelo evaluateour prodult beforenaking a prxchasedecision.Tltedemostpically haw 53medeliberalelimilalionscom!rJedt0lhe full, purchasedprcdurt,and also ha!€ an €xpiry,usualt2l
H|T:CH Sdlwar€mak€scenarnlelsions of ils sonwaE pfoduclsavadableasrree sonwdreTh€seproduclsareiree f0rr.ykind oluse, inrludinqeducalrol]al rnd commercirl !se, bulremainlhe propeE of!1lI€c!1 sonwa€ 313l times Allcopy qhl and olhernghlsare resered and nowa*artot
Thesed.mos are provrdedenlirelydlhoul anywamnly. and arelorevalualionpueosss onv, and are notlicensed
Thenee sottvi?fedownloadsdo no!ha!€ a built,tn€xpiry
l;;--__l t"""""".,-l P'((18 I HrrErH | @ f r pr r r u . d i
r@n
,i,";,"";,";".,""
@
f -sere.1 I
t
8051
| I
. l
--,1 w
.
i
1
(Lrnua Prcc,L|TE HitachiHS/300 f 68HC05l 68H411 H - I 0 E f o iP C C 1 8 MEP43|]
z80l I C0nlactsileet0 orqanizea lime llmiledeyalualionollhis
Figure i-6
Step4 - Allowing PICC Lite Compilerfile downloadinWindows/XP SP2
Lite compilerwithout leavingyou with an .exeor .zip file to deletelater. When the PICC Lite compilerinstallationscreen appears(seeFigurei-8),click "Next" and follow the defaults.If you are promptedto load the software/ driversfor MPLAB IDE, do so,asthey will be requiredto usePICC Lite compilerwith the Microchip tools andprovideyou with a truly integrateddevelopmentenvironment,or IDE. The MPLAB IDE is a singleprogramcontainingan editor, assembler, linker,simulator,and PICkit 1 starterkit's programmerinterface,and it will be the only program you haveto run to createPIC MCU applications. PICC Lite compilerwill integratewith MPLAB IDE whenthe latter is installedso you will havea single Windowsprogramfor developingC and assemblylanguageprograms for the PIC MCU. After PICC Lite compileris installed,you will be askedif you want to restartyour computer.Click "No," then powerdown your computer,and power back up.I find that soft resets(onesin which poweris
I . aO ) , * i r *
o i.i; ! r.{.G:..
@ t;,;i
l
e-d
q
l";
Figure i-7
"
Step5 - PICC Lite downloading
not removed)may not resetall the PC'sparameters, and the softwareinstalledon boot may not work properly.Poweringdown and then backup eliminatesthese potentialproblems.
lntroduction
€d-
Step6 - PICC Lite Installer
Figure i-8
With the PC backup,go to Microchip'sweb site (www.microchip.com shownin Figurei-9) and click "MPLAB IDE" or "DevelopmentTools,"followed by "Full Install" (seeFigurei-10).TheMPLAB IDE softwareis quite large(30 MB) andwill take sometime to downloadif you usea dial-upconnection.This time click "Save"insteadof "Run" and store the .zipfile into a temporaryfolder on your PC (seeFigurei-11).You shouldbe ableto unzip the file by double-clickingon it, and the file management softwareon your PC will expandthe file into the directory of your choosing(ideallythe sameone you startedwith). After the MPLAB IDE installfiles are unzipped, double-clickon "Setup" and follow the instructionsto insrallthe MPLAB IDE (seeFigurei-12).If asked, make surethe programminginterfacefor the PICkit 1 starterkit is includedand you will not haveto look at
,
,.!
r ./ , G
n,. a'
,.
dai:l {rnc*rr
WWffi
EE-
rE-E:
"
Figure i-9
'
Elir
Step 7 - Set yotry browser to
www.microchip.com to downloadthe MPLAB IDE as well as PIC MCU Datasheets
..)
. *
.' ,a i
:t'6G
I
t-t- i
.d. .11G..
Fiqure ilO Step8 - MPLAB IDE Download Page on www,microchip.com
r
t
t ; ^ .
;.
J
--4-j9-
t/*..*,Ell
8.. .
SiAl'l.,....'
Figure i-ll Step9 - MPLAB IDE Installfiles stored in a temporaryfolder
any readmefiles (unlessyou want to). If you are promptedto reboot your computer,click "No" and then power down andpower back up,asyou did after installingthe PICC Lite compilersoftware.Do not connectthe PICkit 1 starterkit to your PC usingthe USB cableuntil you are told. That'sit;you've just installeda set of integrated developmenttoolsthat arejust aspowerful assome softwaredevelopmentproductsthat costmany thousandsof dollars.Withthe toolsinstalled,you can copy the sourcecodefiles for the applicationcodeusedin this book from the PICkit 1 starterkit's CD-ROM codefolder into a similar"code" or "Evil Genius" folder under the C drive of your PC.Another source for thesefilescan be found on my web siteat www.myke.com.
l , P 3 P I C @l ' l C UE x o e r i m e n t s f o r
the Evil
6enius
r{ q f*i: i.{
$-i*
kr. Figure i-12 Step10 - MPLAB IDE Installer window
Fisure i-13 Step11 - MPLAB IDE Start Up desktop
Now let's try to createa simpleprogramthat flashes an LED on the PICkit 1 starterkit. To do this,doubleclick on the MPLAB IDE icon that hasbeenplacedon your PC'sdesktop.Whenit first bootsup,the MPLAB IDE desktoplookslike Figurei-13,and is readyfor you to startenteringyour own application.Click "New" andenterthe following codeinto the window that comesup:
#incluale -CONEIG(FCITDIS
& IESODIS
& BORDIS & IINPROIECT
!4CIJRDIS & P!\IRTEN & WMDIS int it nain( )
& INTIO)
'
t PORTA = 0; CUCONo = ?t ANSE J = 0i TRISA{ = 0i TRISAs = 0t (1 == 1) while
Figure iJq Step12 - FirstApplicqtion enteredinto MPLAB IDE Editor wind.owand savetl
{ f o r ( i = 0 r i < R A { = A A 4 ^ 1 t
25000r i++) i
Different partsof this programwill be displayed usingdifferentcolors;don't worry if it looks a bit strange.Theprogramshouldbe savedas"c:\Evil Genius\Flash\Flash.c" (seeFigurei-14).Oncethe programis saved,closethe window that containsit. All programsshouldbe run aspart of an MPLAB IDE projectthat savesoptionsandfeaturesselections specificto the application without requiring you to reloadthem eachtime you start up MPLAB IDE.The first stepis to specifythe projectnameand whereit is goingto be stored(seeFigurei-15).
Figurei-I5 prolect
Introduction
Stepl3 - Creating an MPLAB IDE
r'1 .-i
Figure i-'f6 Step14 - Selectingthe PICC Lite C Compileras the MPLAB IDE Buiki tool
Figure i-18 Step16 - Selectingthe PIC MCU part numberto work with (notethe largenumberof PIC MCUs to choosefrom).
The Flashapplicationis written in the C programming languagefor the PICC Lite compiler.To specify the PICC Lite compiler,click "Project" and then "SelectLanguageToolsuite."Youmay haveto scroll throughthe Active Toolsuiteto find PICC Lite compiler (seeFigurei-16).When you haveselectedit, makesurethat the locationof PICL.exeis correct.If it is not, look for the CIPICCLITE folder on your PC, and point the ToolsuiteContentsto picl.exein the BIN subfolder. When you are working with assemblylanguageprograms,you may haveto perform the sameoperation thereaswell. In this case,the assemblylanguageprograms(suchasmpasmwin.exe) canbe found in the ProgramFiles\MPLAB folder or in its subfolders. Right-clickon "SourceFiles"in the Flash.mcwwindow (seeFigurei-17) and select"Flash.c"from the
folder (whereyou stored c:\Evil Genius\Flash\Flash.c the programearlier).Toload Flash.conto the desktop, double-clickon "Flash.c"in the Flash.mcwwindow. Flash.cwith the projectthat was This will associate just created.Each time you work with a new program,it shouldhavea new projectassociated with it. Next,you will haveto make surethe proper PIC MCU is selectedfor the application.CLick"Configure" and then "SelectDevice,"and find PIC16F684in the list (seeFigurei-18).I'm sureyou will be amazedat the numberof differentPIC microcontrollerpart numbersthat comeup.After working throughthis book,you will discoveryou can programand usethe The vastmajodty of thesechipsin your applications. differencein the part numbersis the numberof pins and interfacingfeaturesbuilt into the PIC MCU. Programmingand interfacingare identicalto what has beenpresentedin this book. Now you are readyto try and "build" the application.You canclick "Project" and then "Build All," or pressCtrl+F10to compilethe applicationand store the resultin a .hexfile that will be programmedinto the PIC MCU later.If any errorsoccur,go back over the codeyou keyedin and compareit to the previous Iisting.Thisis the mostlikely sourceof the problem. Oncethe programhascompiledcorrectly,you will get the summaryinformationshownin Figurei-19,listing the amountof spacerequiredto storeand run the programin a PIC MCU With the programcompiled,plug your PICkit 1 starterkit into a USB cablepluggedinto your PC. Afterwards,the MPLAB IDE screenwill look like Figure i-20with the statuswindow changingto list the Firmwareversionof the PICkit 1 starterkit. If it does
, a:": :
l
.i.,u
,:-,) :t,,1 ir.,.':
Figure i-17 Step15 - Specifyingprojectsourcelile
5
l , a 3 P I C @I ' l ( U E x o e n i m e n t s f o r
the Evil
6enius
Figure i-19 Step17 - Build informationfor "Flash.c"application
not change,then click on the programmer toolbar loIlowedby "SelectProgrammer"and then the PICkit 1 icon.A four-buttonprogrammertoolbar will alsobe displayedon the desktop.Removethe PIC12F675that cameinstalledin the PICkit 1 starterkit and put in the PIC16F684that wasin the PICkit box.Rememberto storethe PIC12F675in a safeplace(usingthe pieceof foam the PIC16F684wason is a goodchoice).Click "Programmer,""Program Device,"or the Program icon (placeyour mouseover the programmericonsto makea button legendappear)to downloadthe applicationinlo lhe PICl6F684.The programming operation will take a few moments(the operationis indicated by a growing bar on the bottom-left corner of the desktop,and a "ProgramSucceeded"message will be shownon the statuswindow,Figurei-21). Oncethe build/compileoperationqfollowedby the deviceprogrammingsteps,are complete,the D0 LED of the PICkit 1 starterkit will start to flash.If it doesn't,you shouldreviewthe sourcecodeand the processof creatingthe project.
Figure i-eO Step I8 - tnformarionprovitled when the PICkit 1 starter kit is pluggedinto the (levelopment PC's USB Port.Note:Four-buttonProgrammer toolbar at the top centerof MPLAB IDE desktop.
Introduction
(evenif it's flashingan LED, asI do in this introduction).The secondtime it will take half aslong,the third a quarter,and so on. Over a fairly short period of time, you will be ableto createapplicationsefficientlythat asthosecreatedby professionals. are assophisticated
Figure i-al Step19 - Thefirst applicationhasbeen programmedinto a PIC16F684and insertedinto the PICkit 1 startedkit connectedto the developmentPC. TheD0 LED shouldnow beflashing!
Seeingyour own PIC microcontrollerapplications working will be an amazingexperiencefor you,and it will give you a senseof pride to know you can do somethingthat only a smallpercentageof the world's populationcan do.Unfortunately,the processof getting thereis full ol frustration,confusion,and hard work.Along with teachingyou about the PIC MCU, the purposeof this book is to help you gain the skills necessary to developyour own applicationswith a minirnumof the inevitablefrustration.confusion,and hard work.
Prerequisites That'sit;you havejust set up a very sophisticated microcontrollerapplicationcodedevelopmentlab and createdyour first application.I realizevery little of the programor the processyou went throughto get to this point makessense,but asyou work throughthe different expedmentsin this book,their functionswill becomemore obviousand easierfor you to useon your own.Justasif you wereto reviewthe datasheets for the part'selectricalinformation,working at understandingthe architectureand how it is programmed will help you understandwhat kind of development tools are availablefor the part. Throughoutthe rest of this book,I will help you learn aboutand work with the PIC MCU. The experimentsrangefrom the very trivial to somevery complex intedacingapplicationsthat are really quite a bit of fun.Thereis a lot of materialin this book and a lot to learn;try to work througheachexperimentin a sectionbeforetaking a break-I would be surprisedif you were ableto get throughthe entirebook in less than a year. As part of the learningexercise,try to developyour own circuitsandcode-this will cementthe knowledge you gainfrom the book and help you build the skills neededto createyour own applications. Don't be afraid to usemy designsand codeasa baseor asa part of yours (usingcut and paste).Playing"what if" can be a lot of fun and very instructive.I believethat before somebodyis comfortableworking on a new deviceand developmentsystem,he or sheshouldhave50 or so of his own applicationsunder his or her belt. Don't be discouragedwhen,at first,your applicationsdon't work.It isn't unusualfor it to take a week or two to get a person'svery fint applicationworking
This book waswritten to be the secondin a sequence (123RoboticsExperiments for theEvil Geniusvtasthe first book) and,assuch,many of the basicelectrical, mechanical, and programmingconceptsusedin this book werepresentedin the first.To understandfully the experimentspresentedin this book aswell to be you will haveto ableto createyour own applications, be familiar with the conceptslistedbelow: .
Basicelectricallaws . Partsof a circuit . Ohm'slaw . . .
Seriesresistances Parallelresistances Kirchoff'svoltagelaw
.
Kirchoff's current law
o
Thevinin'sequivalency Resistormarkings
o .
Semiconductorbasics . Diode operation . LEDs (including7 SegmentDisplays) . Bipolar transistoroperationand pinouts . MOSFET operation
.
Binary electroniclogic . The six basicgates . Diflerentlogictechnologies . . .
l , e 3 P I C o l l C l JE x p e n i m e n t s f o r
The Booleanarithmeticlaws Typesof flip flops Commoncircuits
the Evil
Genius
. o . o
Adders Muxes/Demuxes Counters Shift registersand.linearfeedbackshift registers(LFSRs)
Oscillators . Basicrelaxationoscillator o
Reflexoscillator
. .
Crystalsandceramicresonators 555timer chip Common electronicdevices . 74L op amp . 386audioamplifier .
IR objectsensors Powersupplies . Batteries . 780x/78l0xvoltageregulators .
Switchmodepower supplies Numberingsystems . Scientificnotation . Metdc prefixes r . .
Capacitormarkings Binary numbersand conversions
Hexadecimal numbersandconversions Programmingconcepts . Data types r . .
Variabledeclaration Assignmentstatement Vadablearrays
.
Iflelse/endifstatement
.
While statement
o
Subroutines Microcontroller concepts . Memory organization . .
Input and output pins Specialpin functions
.
Powersupplies
fomments for Teachers and StudentE While the targetaudiencefor this book is Grade 11 (junior) and Grade12 (senior)high schoolstudents preparingfor postsecondaryeducationin engineering,
computerscience,mathematics, or physicalsciences, it shouldbe appropriatefor universitystudentsor technical hobbyistslooking for more informationon programmingand interfacingPIC microcontrollersinto an application.To ensurethat the materialpresented herewould be relevantto high schoolstudents,the Ontario Ministry of Educationcurriculumguidelines for Computer Engineering(found at www.edu.govon .ca/eng/document/curricuUsecondary I gradeLLl2 /tech/tech.html#engineering) havebeenusedasa referencewhen topics,experiments, and materialswere selected. This book shouldbe usefulboth asa course text and asa referencefor both teachersand students. After working throughtheseexperiments, you will not only havea good understandingof how PIC16F684 and PIC12F675microcontrollers(and indeedthe entirePIC family of microcontrollers)are programmedand interfaceto other devices,but you will alsobe well on your way to beingcapableof creating your own sophisticated PIC MCU applications. Readingthroughthe experimentsin this book will not makeyou proficientin creatingyour own PIC MCU application.I am a firm believerin doing,and I would expectthat in any course,there would be many assignments that consistof modificationsof the experimentspresentedin this book.Theseassignments shouldgive studentsthe task of creatingtheir own applicationsand,aspart of the process, planning, wiring,and debuggingthem.For the studentsto becomereasonablyproficientin developingapplications,they shouldbe given10 to 20 applicationsas assignments over the courseof a term in order to familiarizethemselves with the MPLAB IDE software developmentenvironment,the PICkit, and the PIC MCU operation. Along with providinginformationon Microchip PIC microcontrollers(the PIC16F684in particular), electronicsinterfacingprogrammingin C, and assembler programrning, this book attemptsto developand engenderthe importantthinking and problem-solving skillsthat are expectedfrom a graduateengineer. Theseskillsincludethe ability to work independently, perform basictechnicalresearch,createa development plan,and effectivelysolveproblems.Along with being usefulin professionalcareers,theseskills are criticalto your success in collegeand university. The experimentsin this book do not lend themselveswell to group activities-you'll find that it is difficult to dividesmallmicrocontrollerapplicationsinto differenttasksthat can be carriedout by different membersof a group.For this reason,I recommend assignments that are limited asone-studentprojects. Projectsgivenduring the term shouldbe solvablein lessthan 100linesof code(two printed pages)and shouldnot requirea lot of researchon the part of the
lntroduction
...:
;: ,: :.:
student.Insteadtime shouldbe spenttrying to decide the bestway to solvethe programand structurethe software.All of theseprojects,exceptfor a summative project,sholJldbeeasilycompletedin a week or less.
.
H Noteto StudentE: .
.
.
Teachersare very good at figuring out when an assignmentis copied or plagiarized,and getting caughtwill land you and any other students who are involved in trouble.Copyingcodeor circuitry from the Internet or other books will be identified quickly asit is difficult to rework them to fit into your designsystemor style of programming.In any case,cheatingwill not help you gain the necessaryskills for developing your own application(and ultimately passing the course).In short,hand in only your own work and make sure that you can explainthe It will pay how and why of your assignments. off in the long term. spenda few When given an assignrnent, momentsa day on it, no matter what.Don't leaveit until the night before it's due.By doing a little bit of work on it eachday,your subconsciouswill work on the assignment,and when it comestime to finally createit and wdte it up, it will seema lot easier. Don't be afraid to try somethingdifferent.The worst thing that can happenis that it won't work-the upsideis you will discovera way of approachingthe problem that is very efficient and easyto implement.In this book, there are severalexampleswhere I just tried different things and discovereda better solution to a problem than I would haveexpected(and cases where the alternativesolution wasworsethan the original).
|-;
ff t:'"j
.i,"j
ful
H Noteto Teachers: .
;r1
'r{
ii; !r -r''i it-J
10
For teachersconsideringusingthis book asa I would like to emphasize text for their courses, that the materialis designedfor the PIC16F684, PICkit 1,and,to a lesserextent,the PICI2F675. I realizethat investmentshavebeenmadein other PIC (and other) MCUs, in programmers, in and other equipment,but the MPLAB IDE/PICC Lite compilerand PIC16F684/PICkit combinationis an extremelyflexible and costeffectivetool for applicationdevelopment.
.
Tiy to usereal-world situationsfor your assignmentsand try to vary them,both to interest your studentsand to make it harder for them to copy from preexistingmaterials.A good way to is to keep a comeup with theseassignments notebookhandy and record the different things you seein your travels.Toys'R Us, Radio Shack,TheSharperImage,and other retailers can be wonderful sourcesof inspiration. Lead by example.You shouldwork through as many different applicationsuntil you are comfortable doing so and can debugmost of the problemsyou experience.An important tool to be familiar with is the MPLAB IDE simulator. A coupleof teachershave told me that they don't bother with the simulator when they are teachingbecausestudentsprefer to seeflashing lights or somethinghappening.Pleasetry to break this habit and encouragethe use of the simulatorasa tool for verifying the operation of the codeaswell asfor debuggingexecution problems.Using the simulator will give students the ability to seethe program working or not working,and why it is not working before making the effort to wire the application.For virtually all applicationsthat run the first time power is applied,the developershould have demonstratedthe corrgct operation of codeon the simulatorbefore he or she attemDtsto burn it into a PIC MCU.
lcons and Conventions At the start of eachsectionand experiment,you will fild one or more iconsindicating the parts and tools you needto have availableto complete the experiment(s).I havechosento do this rather than providing one central list of parts required for all the experiments in thisbook.Thereasonfor doingthis is to helpyou efficiently plan for the section'sexperimentswithout having to buy many hundredsof dollars of parts (many of which you will not needfor months).I have tried to keep the number of parts to a reasonableminimum by designingasmany experimentsaspossibleto execute within the PICkit 1 starter kit-once the PIC MCU is programmed,the applicationprogrammedinto it can executeon the PICkit 1 starter kit without modification. The iconsusedto specifypartsand operationsare asfollows: At the start of eachsection,I will list the required partsfor the sectionunder this icon (seeFigure i-22).As I indicated,this is a summationof the parts usedin all the exoerimentsof the section.
l , e 3 P I C @l ' l C UE x p e ni m e n t s f o r
the EviI
Genius
F{ !!E
.t a.* !'r,
Figure i-ea
RequiredPartsicon
Figure i-eq
.l*
PICkit I starterkit icon
l ;
':i" i't, ..:}
Figure i-a3
PC/Simulatoricon
Figure i-45
PartsBin icon
Figure i-e6
Toolboxicon
Virtually all of the experimentswill requirea PC (indicatedby Figurei-23)runningWindowsand loadedwith rhe MPLAB IDE and PICC Lite compiler.ThisPC shouldbe runningone of the following versionsof Microsoft Windows: o . . e .
Windows98 SE WindowsME WindowsNT 4.0 SP6aWorkstations(NOT Servers) Windows2000SP2 WindowsXP
And the PC shouldhave32 MB memory (128MB recommended),95MB of hard disk space(1 GB recommended),CD-ROM drive,alongwith Internet Explorer 5.0or greaterwith an Internet connection for installationand online Help alongwith one free USB port. When the PICkit 1 starterkit icon (seeFigurei-24) appearsat the start of an experiment,it meansthat the PICkit is requiredeitherasa platform for the experiment or as a PIC MCU programrner. The PartsBin icon (seeFigurei-25) specifieswhich partsare requiredfor the application.Partsmay be reusedbetweenexperiments The lasticon (seeFigurei-26) liststhe tools requiredto createthe application'scircuit.Youshould not requireany specializedtoolsfor the experiments presentedin this book.Rememberto wearsafety equipmentwhendoingany cuttingor drilling.
In terms of conventionqI will use both StstemInternationale(Sl),better known asthe metric system,and English measurementstogether where possible.I recognize that there are still a number of issueswith specifying the correct measurementsystem,so by listing both I hopetherewill be lessconfusion.Standardelectrical prefixeswill be used,andI assumethe readeris familiar with them.They include the following: k for thousands M for millions m for thousandths p for millionths p for trillionths I restrain from speciffng part numbers except whenI believethat only one manufacturer'spart shouldbe used.Often,equivalentsto variouspartscan be found in surplusand generalelectronicsstoresat a very low cost. For the screenshotsshownin the book, I haveused MPLAB IDE version7.01.I know that after this book
lntroduction
11
goesto press,later and more capableversionsof MPLAB IDE will be available for download from Microchip'sweb site.www.microchip.com The MPLAB IDE functionspresentedin this book will not changefrom version to version (except for fixesto discoveredproblems),so despitesomecosmetic changesin appearance,their operation will not change.I recommend that you alwaysuse the latest versionavailablefrom the Microchipweb sitebecause if you haveproblems,the first recommendationthat you will be givenwill be to try againwith the latest version of the software.
FindingParts When you are first starting out in electronics,it can be difficult to find retailers to provide you with the parts and tools to createyour own circuits.Over time, you will developa network of storesthat havethe parts you need,but if you are startingout or are looking for better suppliers,here are somesuggestions: .
.
Along Mouser Electronics(www.mouser.com). with Microchip products,Mouser also hasan excellentselectionof opto-electronicparts. I find Radio Shack(www.radioshack.com). Radio Shackto have a number of components that I can't find anywhereelse(thermistors, TRIACs) aswell asgood-qualitywire at a reasonableprice.Recently,Radio Shackhas includedsomeMicrochip PIC MCU chipsand the ParallaxBASIC Stampto their catalog. Incal electronicsstores.InToronto,I recommend Supremetronic(www.supremetronic.com) asit hasall the passiveand discreteparts that I need,prototypingPCBs,and other usefulparts that are nice to handleand choosefrom instead of decipheringPDFSon line. Local surplusshops.If you are in the Toronto area,I'm sureyou will recognizeActive Surplus (www.activesurplus.com) by the large stuffed gorilla out front. While having a good selection of electronicparts,surplusstoresoften have a variety of other parts and subassemblies that are perlectfor hackingor designingnew controls.
Digi-Key (www.digikey.com).Ihavenot found a sourceof parts anywherein the world that matchesthe selection,price,and serviceof Digi-Key. Jameco(wwwjameco.com).Another excellent supplierthat carriesMicrochip parts.Also carries a good selectionof robot parts (including gearsand motors).
S*!
i.,,,
o.',..:
ir,"i *;
L2
l,e3 PICo llCUExoeniments fon the Evil
6enius
Section
One
Underthe Eoversof the PlElEFEBq
1Plcl6F684
Before astronomersbeginto investigateand learn more about a star,they make surethey fully understandthe tools they are goingto use.Thetools to be usedare chosenfor their ability to investigatethe specific aspectsof the starthat is to be studied.Althoush a fewdiscoveries havebeenmadewith poorlyundelstoodequipment,the vastmajority of obseruations haveresultedin failure.Justlike astronomers, before we investigateand learn aboutthe MicrochipPICP microcontroller(the PIC16F684specifically), we want to know asmuch aspossibleaboutthe toolswe are goingto be using. The PICkitrM1 starterkit is an excellenttool for learningaboutthe PIC microcontrollerasit includes, alongwith its programmingcapability,a basictestcircuit that you can usewith a PIC MCU. As shownin Figure1-1,the PICkit starterkit providesfrom 8 up to 12individuallyaddressable LEDq alongwith a button input and a potentiometerfor variable-voltage inputs.
The builtin programmerinterfacesto the developmentPC via aUSB port, which is preferableto serial or parallelports.Overall,the PICkit 1 starterkit is almosta perfecttool for learninghow to programthe PIC MCU and interfaceto hardware. When I describedthe PICkit 1 starterkit asbeins almostperfect.it probablysetotf somealarmbellsin your head-this type of qualificationis normallyused to describethingslike a usedcar or a blind date.In this case,I am beingasliteral aspossible.The PICkit 1 starterkit is an extremelygoodproductand an excellent first tool (probablythe bestthat I know of) with which to leam to programand interfaceto the PIC MCU. The threepotentiallynegativeissuesI would like to bring to your attentionregardingthe PICkit 1 starterkit are actuallyquite minor and,to some extent,canbe exploitedto help you better understand how the PIC MCU works. The biggestissuethat will haveto be addressedin this book is the organizationof the PICkit 1 starter kit's LEDs. If you wereto follow the wiring of the eightLEDS and the four I/O pins they are connected to, you would noticethat only two of the pins canbe outputs(asshownin Figure1-2).And if all the I/O pins to which the LEDs are connected(RA5, RA4, RA2, and RA1) weremadeoutputs,you would have multiple LEDs lit if you make any of the I/O ports high.The solutionto this problemis to enableonly two pins asoutputsat a tirne (one high and one low). This allowseightindividuallyaddressedLEDs, but not an arbitrarynumberof LEDS to be on at any siventime.
--ri ., I I
Figure l-'f
EquivalentPICkit I starterkit circuit
13
=:-
--ri " I I
Fiqurel-e
PICkit I stqrterkit LED on
Arbitrary numbersof LEDs canbe turnedon by scanningthroughthe LEDs,just asa TV's electron beamscansacrossthe cathoderay tube,turning on phosphorsone at a time.Thistrick will be demonstratedlater in the book and will be usedto display eightbits of data at a giventime.The organizationof the eightLEDs (alongwith the button andpotentiometer)wasmadeto supporteight-and 14-pinparts in the PICkit 1 starterkit's socket.That organization and the choiceof pins (and how they are organizedon the PIC MCUSthat fit in the PICkir 1 starrerkit's socket)is actuallyquite inspired,asit leavesthe six pins of the 14-pinmicrocontroller'sPORTC available for other uses. The secondproblemis that it takesa few mouse clicksto turn off the power goingto the programmed
part.I seldomrememberto turn off the power,andI doubt you will either.Although the differentPIC microcontrollersare very robustdevicesfrom the elecyou shouldneverpull them trical overloadperspective, from a socketwhile power couldstill be appliedto someof thepins.Althoughlhe zeroinsertion forca (ZIF) socket,which I showyou how to installlater in the book, goesa long way in mitigatingthis problem, you shouldstill be cognizantthat you could potentially be damagingthe PIC16F684everytime you plug it into and unplugit liom the PICkit 1 starterkit while the Plckit is still connected. The final issueto be awareof is the potentialliability of the USB port usedto connectthe PICkit 1 starterkit to the developmentPC.Although most commercialand homePCshavebuilt-in USB ports and versionsof the MicrosoftWindowsoperatingsystem that canaccessthe PICkit 1 starterkit very simply, thereare a numberof PCsin educationaland institutional settingsthat do not havethe requiredports or software.Thereis no easyfix to this problemother than trying to find the fastest,biggest,and mostmodern memoryPC to be usedasa programmingstation. None of thesethreeissuesare major showstoppers -they are reallyjust speedbumps,and they canbe overcomef airly easily.
1-l/0 Pins Experiment
Arguably the mostimportantfeatureof the PIC MCU (I/O) pins.The 12 pins availis its setof inpttt/oLtlp&l ableto the applicationdeveloperallow the microcontroller to sensethe outsideworld and output in differentways.ThePIC16F684tI/O pins are capable of manydifferentfunctionsincludinganalogand difBut asI first startintroferent digitalsignalprocessing. ducingthe chip,I will treat the I/O pins assimple
T4
digitalI/O, capableof sensingor outputtingsimple binarysignals.Themore advancedfeatureswill be addressedlater in the book whenyou becomemore comfortablewith programmingand working with the PIC16F684. The basicPIC MCU digital I/O pin designis shown in Figure1-3.TheIR/S bit controlswhetheror not the pin can output the valuesavedin the PORZ bit. The term TRIS is an abbreviationofTii-State and referencesthe tri-statedriver that candrive the PIC MCU'S pin.When the TRIS bit is low (0), the valuein PORT is driven onto the pin, and the pin is saidtobe rn output mode.whentheTRlS bit is high (1),the PIC MCU pin state,and the data level at is held in a high-impedance the pin canbe read without beingaffectedby the contentsof the PORT bit.This is known asinput mode. RememberingwhichTRIS stateaccountsfor which modeis cuite easvto remember:ATRIS valueof 1
l , a 3 P I C o l ' l C l JE x p e r i m e n ts f o r
the EviI
6enius
CONFIG(INTIO & WDTDIS & PWRTEN & !,ICLRDIS IJNPROTECT \ & UNPROTECT & B O R D I S & I E S O D I S & F C M D I S ) ' int
o
co
&
j;
i,
nain( )
(5
{
o
o
PORTA = 0t C M c o N 0 = 7 r / / Turn off Comparatola A N S E I J = 0 r / / turn of,f, ADC T R I S A { = 0 r / / Make RA4/RA5 Outputs TRISAs = 0t == 1)
whil€(1
(
< 255, < I29,
f o r ( i = 0 r i f o r ( i = 0 ; i
Figirre 1-3 l/O pin
RAI = ri
puts the pin in input mode,and a TRIS valueof 0 puts the pin in output mode.TheTRIS bit valueapproximatesthe first letter of input or of output. By convention,you will seeI/O pins referredto usingthe format
//
tor
(i
RAA = li
Forev€r i.all // j1-1-1,
sinple
Delay
Loop
Si1np16 Delay
lroop
D O LED ON i j
RA{ = 0t
].oop
//
< 255r < 429,
i11) jaa),
//
D0 tED Of,f
= Ot i Ot j //
< 255, < L29,
i11) // jaL>,
Simple
Delay
loop
sinDle
Delay
r.oop
D0 LED On AEain
a,&*
wherethe ampersand(&) representsthe port, and the numbersign(#) representsthe port's pin. So PORTA, pin 4 is known asRA4.This shorthandcanbe a bit confusingbecauseit refersto both the pin and the PORT register.TheTRIS bits are usuallywdtten in the rormat TRIS&*
with & and # beingusedin the sameway asthey are in lhe PORT bil/pindefinilion.Thesenamingconventions are usedfor both C and assemblylanguageprogramming. When I first presentedyou with the cFlash.cin the Introduction,the mannerin which the LED was turned on and off is not easyto see.To help you see the operationof the I/O port and how it affectsthe PICkit 1 starterkit's D0 LED,I createdcPins.c, which turnson and off the LED usingthe PORT andTRIS bits more explicitly. *incluale - Exalnine /* cPiaa.c
Operation
This Progran is a moalificalion wiEh nore e:.plicit writea to bits. RAA - IJED Positive RA5 - IJED tilegativ€
conn€ction cona€ction
nvke Drealko 04.09.15
SectionOne
of
PIC MCU PinE
of -cE1a6h.cthe TRIS and PORT
(i (j
= 0i = oi
i i
TRISA4
= 7i
//
for for
// LED lrrrned out
< 255, i11) < L29, itL), EltlE RA4 irto
Off
f o r ( i = 0 r i < f o r ( j = 0 r j <
//
Eue to
255r r29i
rnput
RA4 Not
i11) // j!!, i
aA4 = Oi ll Reslole oliginaL TRISA4 = 0, // conditions | / / erillw ) // Enal cPins
!{oale Dfivirlg
sifirple
Culrent
Delay
].oop
op€ratingr
Before enteringthe "while (1 == 1)" statement,the codeputsthe RA4 and RA5 pinsin output mode (writesa 0 to them) afterclearingthem (settingall bits to zero).After the while staiement,the codedelaysfor a half secondand then loadsRA4 with a 1,which drivesor sourcescurrentfrom RA4, throughD0, and is laken in,or sinked., by RA5.The codethen waits anotherhalf secondbeforeloadingRA4 with a zero, tuming off D0.Thisshouldbe fairly easyto understand; currentflowsfrom RA4 throughD0 and into RA5. Next,the programwaitsanotherhalf secondbefore loadingRA4 with a zero,turningoff D0.After another half-seconddelay,RA4 is loadedwith a one,andD0 is tumed on again.After anotherdelay,the LED is rumed off by purtingRA4 into inpur mode (the PORT valueof RA4 doesnot change).With RA4 in input mode,no currentcanflow throughD0.After another delay,RA4 bit is put backinto outputmodewith the PORT bit beinglow so the LED will be off.At this point,the programrepeats.
Under the Covensof the PIClbFhAq
L5
This programis a very simpleexampleof how the PORT bits work.With the basicPICkit 1 starterkit circuit, only one LED canbe turned on at any one time, which givesyou an opportunityto try and decodethe schematicof the PICkit 1 starterkit and try to turn on Later differentLEDs or a seriesof LEDS in sequence. in the book,I will presentyou with codethat will do this.But for now you might want to try and modify
cPins.cto turn on other LEDS by putting RA4 and RA5 into input mode,and then selectingtwo other pins to put into output mode and turn on another LED.When you do this,just usethe explicitwritesto the PORT andTRIS bits that I do in cPins.candsave methodsfor controllingthe the more sophisticated LEDS for later.
Experiment2-Eonfi gurationtljord One way the variousPIC microcontrollersdiffer from the otherchipsout there is in their ability to havecertain operatingconfigurationparameterssetwhenthey powerup.The configurationparametersare specified by writing to a specialword in programmemory, known appropiately enoughasthe Configuration Word.When mostusersstartworking with the PIC MCU, understandinghow this word is configuredis ignoreduntil it is time to programa chip and testit in an application,at which point they try to figureout the correctvaluesfor the conligurationword, often getting an incorrectvalue.Most incorrectvalueswill causethe PIC MCU not to powerup or apparentlyresetitself everylew moments. To avoidthis problem,whenI presentedyou with the initial cFlash.cprogram,I includedthe properconfigurationword specificationin the program,which is automaticallyrecognizedby the PICkit 1 starterkit programmerand storedin the PIC MCU, so that it will powerup corectly without any interyentionlrom you. Settingthe configurationfusesmanuallyleavestoo much of an opportunityfor error. The configurationword specificationis the followin the ing statementand startswith two underscores leftmostcolumnof the sourcecode: & WDTDIS & PWRTEN & MCI.RDIS & -CONFIG(INTIO UIIPROTECT \ & BORDIS & IESODIS & FCIIDIS);
This statementenablesthe internaloscillatorof the disablesthe WatchdogTimer,the external PIC16F684, resetpin, the low-voltagedetectcircuitry,and the advancedclockingoptions.Along with this,codeprotectionis disabled,meaningthat the contentsof the chip canbe readout.Note that the parameterwords (calledlabels)havedifferentvaluesfor differentPIC MCUs,and differentPIC MCUs may havedifferent oarameterwordsall together.
16
Each of the parametersof the -CONFIG statement is ANDed togetherto form a valuethat is saved in the configurationword when the PIC MCU is programmed.Thisvaluecould be calculatedmanuallyby readingthe "SpecialFeaturesof the CPU" sectionof the PIC16F684datasheetand creatingthe correct14bit value,or you can take the valuesbuilt into the PICC LiterMcompileror MPASMTMassemblerinclude fileslistedin Table1-1andAND them togetherasI havedonein the previousstatement.ANDing together the includefile valuesforcesthe compileror assembler to calculatethe configurationword valuefor you,saving sometime and ensudngthat the valuesare correct. When specifyingthe valuesfor the configuration word,make surethat everybit of the configuration If a bit is forgotten,then chances word is represented. are the other valueswill make it a 1, which may or may not be the valuethat you want for the configuration word bit.To emphasizethe importanceof havingspecified a label for everyconfigurationword bit, I want to point out that trying to figure out why a PIC MCU won't run properlywhen a configurationword bit is misprogrammedis incrediblydifficult. As I will discusslater in the book, the PIC16F684 internalclock,negatingmuch of hasa high-accuracy the needfor an externalclock (althoughone can be added),the 1N71O,in the -CONFIG, specification enablesthis clock and savesyou from havingto add your own clockcircuitryThe other optionsthat I have selectedwere chosenbecausethey tend to make your life easierand alleviatethe needfor you to comeuP with any specialexternalcircuitry to the PIC microcontroller. you may As you work on your orm applications, experiment values and want to changesomeof these with configurationword options.Chancesare you will end up with a situationwherethe selectedoptionsput the PIC MCU into a statewhereit cannotrun properlv If you end up in this situation,rememberto
l , a 3 P I C o I I C l JE x p e n i m e n t s f o r
the EviI
6enius
Table 1-1 Eonfiguration Fuse Parameter SFeciftcations utth Hffected Bit(sl Listed First Bk #
PICC LIte Label
MPBSM Fssembler Label
13-12 N/A
N/A
Unimplemented;Read as 1
11
FCMEN
_FCMEN_ON
Fail-Safe Clock Enabled
11
PCMDIS
_FCMEN_OFF
Fail-Safe Clock Disabled
10
IESOEN
_IESO-ON
InternallExtemal Switchover Mode Enabled
10
IESODIS
_IESO_OFF
InternallExtemal Switchover Mode Disabled
_BOD_ON
Brownout Detect/ResetEDabled
O9-O8 BOREN 09{8
BOREN_XSLP
BOD_NSLEEP
rr1 t/
u
Comments
tv
F" ly F*
Brownout DetecvReset Disabled in Sleep
09-08 SBOREN
_BOD_SBODEN
Brownout Detecr/ResetControl by SBOREN
09-08 BORDIS
_BOD_OFF
Brownout Detect/ResetDisabled
07
UNPROTECI
-CPD_OFF
EEPROM Data Memory Protect Disabled
07
CPD
_CPD_ON
EEPROM Data Memory Protect Enabled
06
Program Memory Protect Enabled
06
UNPROTECT _CP_OFF PROTECT -CP,ON
05
MCLREN
_MCLRE_ON
_MCLR Pin Function Active
05
MCLRDIS
_MCLRE_OFF
_MCLR Ptr Function Inactive/Pin is Input RA3
04
PWRTDIS
_PWRTE_OFF
70 ms Power Up Delay Timer Disabled
04
PWRTEN
_PWRTE_ON
70 ms PowerUp Delay Timer Enabled
03
WDTEN
;J
_WDT_ON
Enable WatchdogTimer
03
WDTDIS
!'tl
_WDT_OFF
DisableWatchdogTlmer
24
RCCLK
_EXTRC_OSC_CLKOUT I _EXTRC
RC Clock, RA5 Ctockout
24
RCIO
_EXTRC_OSC_NOCLKOUT I RC Clock, RA5 t/O pin _EXTRCIO
24
INTCLK
_INTRC_OSC_CLKOUT I _INTOSC
Intenal Oscillator, RA5 Ctockout
24
INTIO
_INTRC_OSC_NOCLKOUT I .INTOSCIO
Intemal Oscillator, RA4 VO pin
24
EC
_EC_OSC
Extemal Clock on RA5, RA4 I/O Pin
24
HS
_HS_OSC
High Speed (4-20 MHz) Crystal on RA4 & RA5
24
XT
_XTTOSC
Nominal Speed (1-4 MHz) Crystal on RA4 & RA5
24
LP
_LP_OSC
Low Speed (32 kHz-1 MHz) Crystal on RA4 & RA5
N) I
Program Memory Ptotect Disabled
n |J.
q
Ft
0, F.
o 5
{
o changethe configuration fusesback to the default value that I have listed here,and use for most of the experiments.Once retumed to this valuq you can
Section One
changeeachoption individuatly, trying to find the one that causedthe application to stop working.
Under the Covers of the pICItFhAr+
L7
H
lJ-
3-PlE MEUVariableMemorg,Flegisters, ExFeriment L,!
and ProgramMemorg
,:4,',
;.; i. .:l
*:.,,
,.: ..t
.'-t:i*
:.,: ...:
:r.;
,,a
In the introduction,I outlinedsorneof the differences betweena microcontroller(suchasthe PIC rnicrocontroller) and a PC,and I noted that one of the big differencesin the applicationcodewasthe needfor providingcodeto initializevariables.Another differenceis how the applicationcodeloadedinto a PC or a PIC microcontrollerand how it is organized.Inthis experiment,Iwill explainthesedifferences(andthe needfor them) andhelp you understandhow information is organizedin the PIC MCU and someof the issuesthat you mustbe awareof whenyou are programmingthe PIC16F684. When computerarchitecturesare presentedfor the fimt time,somethinglike Figure1-4is shown,which is the standardPrlnceton or von Neumannarchitecture, The importantfeatureof this architectureis that the memory spaceis a singleaddressarea for the program memory,variablememory,andstqckmemortes;the for theseapplicationfeaturesare presented addresses asbeing arbitrary and could be placed annvhere in this addressspace.An interestingsideeffectof this computer architecture is that an errant program could escapefrom the programmemoryarea,start executrng throughthe variablememory stackRAM, register areas,and treat the data asprogramstatements. When a programis built for loadinginto a target Princetoncomputersystem,the file that is loadedinto the computeris organizedto reflectthe memory organizationof the memoryspace.As shownin Table 1-2,the programfile is broken up into segments,each at a differentlocation,with a differentsize,andwith differentinformation.This is a simpleexample;large PC applicationscanhaveliterally dozensof different, code,variable,data,and stacksegmentswhereasa
microcontroller application often only requires only four (reset,code,data,and stack).The compilerand other applicationbuild tools are responsiblefor specifying and allocatingmemoryin the application.
Table 1-2 PrincetonComputerFrchitectureFlpplicationFile 5egmenl and Function Function Reset
Addressapplicationstartsexecutingat. Usuallya golo at the start ofthe applicationcode.
Code
Application code.Startingaddressand sizespecified.
Data
Variablespacefor application.Startingaddressand sizespecified.Initial valuesfor variables.
Stack
Programcounterand data stack.
The PIC MCU is designedto use the Ilarvard computer architecture(seeFigure1-5)in which the program memory and variable memory/register spacesare kept separatefrom eachother.Along with this,the programcounter'sstackis alsokept in a separate memoryspace.The advantageof this method dudng programexecutionis the ability of the processorto the fetch new instructionsto executewhile accessing Bad programscanstill exeprogrammemory/registers. cute,but at leastthey won't try to executedata as of this methodis a loss The disadvantage instructions. of flexibility in applicationorganization(i.e.,changing data or stacksegmentsizesto accommodatedifferent applications).
Memory SDace .*
t; t:
.x :>;
Data Processor and Register lnterface
!"j *: r1 .
X i.'i
Figure f-tl
r.8
Princetonarchitecture
Figure f-5
Harvard architecture
l , a 3 P I C @I I C U E x p e n i m e n t s f o n t h e E v i l
Genius
The programfiles loadedfor PIC MCU and other Harvard computersystemsare much simplerthan the filesloadedinto the Pdncetoncomputersystems. Theseare producedby the MPLAB IDE, end in the extension.hex,and are usuallyreferredto as,,hex files."A typicalPIC MCU hex file consistsof two or three segments, one for applicationcode(startingat the resetaddress),one for the configurationfuses,and an optional one for electricallyerasableprogrammable read-onlymemory(EEPROM) data.For the applicationspresentedin this book,the hex files will consist only of the codeandconfigurationfusesegments. Thereis no needfor definingdifferentareasin the memoryspace. This lastpoint is subtle,but extremelyimportant. Whenyotsdeclarea variablein a Princetoncomputer system,you are speciflng the label to be usedwith the variableaswell asreservinga spacein memoryfor the variable.When you are declarea variablein a Harvard computersystem(like the PIC MCU), you are simply specifyingthe label to be usedwith the variable;there is no need(or any mechanism)to reservespacefor the variable.This meansthat the locationfor variablesin a Haryard computersystemcan be chosenwith much lessrigor than in a Princetoncomputersystem,and the Harvard applicationcan still be expectedto run. The separatememoryareasalsomeanthat initial variablevaluescannotbe loadedinto the datasegmenL in the Harvard computersystemvariablesare initializedfrom programmemory.In termsof hex file space, you saveon the needfor a datasegment,but you do requiremore for the initializationspace.For microcontrollers,this is not an importantpoint becausein either computerarchitecture,variableswill haveto be initialzed by code,becausethe applicationsare not loaded []to memoryastheyarewirh a PC. Although I've probablygivenyou the perception that variables can be placed any.wherewilly-nilly in the PIC MCU, the truth is a bit more complex.As I work throughthe book,I will explainthe variablememory andregisterspacein more detail,but for now I just want to note that they sharethe samespaceand explaina bit about the functionof the registers. What I am casuallycallingthe registersin this experiment are refefied lo as the specialfunction registersby Microchip (and,similarly,what I am calling variablememoryis more properlycalledthefile registers),the specialfunctionregisters(SFRs)listedin Table1-3are usedto monitor the statusof program executionaswell asprovidean interfaceto the hardwareperipheralfunctionsof the PIC MCU. As you read throughthe book, the functionand addressingof theseregisterswill be explainedto you.
SectionOne
Table 1-3 PlEl6FEBqMicrocontroller5DeEialFunction Flegisters
! & !
&,!,
ta
Name
Flddress
INDF TMRO
0x00& 0x80 IndexDataRegister 0x01 TMRoValue
PCL
0x02& 0x82
Low 8 Bits of the ProgramCounter
STATUS
0x03 & 0x83
PIC MCU ProcessorStatus Register
FSR
0x04 & 0x84
PIC MCU Index Register
PORTA
0x05
PORTA I/O Pin Value
9.i
PORTC
0x07
PORTC I/O Pin Value
i.i
PCLATH
0x0A & 0x8A Upper 5 Bits ofthe Program Counter
INTCON
0x0B & 0x8B lnterrupt Control Register
PIR1
0x0C
PeripheralInterrupt Request Register
TMR1L
0x0E
Low Byte of TMR1 Value
Function
TMR1H
0x0F
High Byte of TMR1 Value
T1CON
0x10
TMR1 Control Register
TMR2
0x11
TMR2Value
TMR2CON 0x12
TMR2 Control Register
CCPR1L
0x13
Low Byte of CCP Register
CCPR1H
0x14
High Byte of CCP Register
ft\ $-*
1t'
I E*tl
".,.t-
PWM1CON 0x15
CCP PWM Control Register
ECCPAS
0x16
CCP Auto-ShutdownControl Registet
WDTCON
0x17
WatchdogTimer Control Register
CMCON0
0x18
ComparatorControl Register
CMCON1
0x19
ComparatorControl Register
ADRESH
0x1E
High Bits of ADC Result
ADCONo
0x1F
ADC Control Register
OPTION
va:*
gn
:x
iLJ
0x81
PIC OperationControl Register
TRISA
0x85
PORTA Data Direction Pins
TRISC
0x87
PORTC Data Direction Pins
PIE1
0x8C
Pe pheral Interupt Enable Register
PCON
0x8E
PowerControl Register
OSSCON
0x8F
OSCTUNE 0x90
L,i,
i1r F.t
OscillatorControl Register OsciilatorTLningRegister
ANSEL
0x91
ADC Pin Enable Register
PR2
0x92
TMR2 Period Register
WPUA
0x95
Weak Pull-Up Enable Register
IOCA
0x96
Interrupt on Port ChangeSelect Register
VRCON
0x99
ComparatorVref Control Register
EEDAT
0x9A
EEPROM Data Register
EEADR
0x9B
EEPROM AddressRegister
EECON1
0x9C
EEPROM Control Register
EECON2
0x9D
EEPROM Write EnableRegisrer
ADRESL
0x9E
Low Bits ofADC Result
ADCON1
0x9F
ADC Control Register
U n d e r t h e C o v e r s o f t h e P f C l t F b gq
tf': tii it;*.d
yt"
it fil
{r? 19
Exp e r im entU- S im u l a ti n g c F l a Eh .ci n MP L H BID E
The simulatorbuilt into the MPLAB IDE is probably the leastusedand understoodtool availableto you, which is unfortunatebecauseit is the mosteffective tool that you haveto find and debugproblems.The reasonswhy applicationsare nol simulatedis due to the perceivednotionsthat it is too muchwork and that the programis either very simpleor basedon simple changesto a working program.Old handswill cringe at theseexcusesand rememberhow they learnedthe hard way.PersonalIy,Ineverattemplto burn a programinto a PIC MCU without first simulatingit and makingsurethat it works properly.I alwaysdo this beforeseeingif it will work in the applicationcircuit; by simulatingit first you haveconfidencethat the programshouldrun. In this experiment,I will work throughthe basicsof settingup the simulatorfor an MPLAB IDE project.I havea few commentsregardinghow it shouldbe used but, for the mostpart,I recommendthat you useit for all the experimentsin this book. Someof the initial programming(C and assembler)experimentsare designedto work only in the simulator,but onceagain, you shouldsimulatethe experimentsthat accesshardwarebeforeburningthem so you canunderstandhow theywork and what they are expectedto do.As you gainexperiencewith the simulator,you shouldalso developpersonalstandardsfor displayingdataand what the simulatoris telling you in understanding order to find problemsand gainconfidencein your program. After you havecreateda projectand havebuilt the sourcecodeto ensurethere aren't any syntaxelrors (languageformattingerrors),you shouldenablethe "Select debuggerby clickingon "Debugger,"then "MPLAB Sim" asshownin Figure1-6. Tool,"and After enablingthe simulator,the simulatortoolbar (seeFigure1-7)will appear.The toolbar will allow you to do the following: . Run the simulatedprogramat full speed.On a 2.4 GHz Pentium runningWindowsXP,I find that 1 simulatedsecondexecutesin about 3 seconds,
.
Stop executionat any tirne.A breakpoint,which forcesthe applicationto stop at a specificlocation, can alsobe put in the applicationcodeasI will showpresently. Clicking'Animate" causesthe program to run relatively slowly,so you can watch the flow of the program.I find that this feature is bestused to illustratethe operationof basicoperating concepts. The program (subroutineor function) can be executedone step at a time by clicking |he Step In icon. If the operationof a subroutineor function is well understoodand felt to be correct or if it takesa long time to execute,clicking the S/ep Over icon will causethe simulator to execute the codein the subroutineor function at full speedand stop at the statementfollowing the call to the subroutineor function If you find yourselfin a subroutineor function that is going to executefor a while,you can StepOut of it. After clicking this icon, execution will run at full speed,stoppingat the instruction after the subroutineor function call statement. To restart the simulationfrom power up, click on the Reseticon.This icon will causethe simulated PIC MCU to return to power up conditions and resetthe StopwatchandStimulus functionsaswell.
'fo
setabreakpoifi (whichcausesexecutionto stop when it is encountered)in your program,double-click on the statementat which you wish the breakpointto be placed.Executionwill stopwhen the simulatoris runningor animatingan application,whena breakThe breakpoint'sstatementis not point is encountered. executedbut will executeif the Run.Animate,or one of the Stepiconsis clicked.Figure1-8showscFlash.c with threebreakpointsset and the execvtronrun arrow pointingto the first statementin the program. At this time,you may want to start up your cFlash project,enablethe simulator,and put breakpointsat the threelocationsI havein Figure1-8.Onceyou have donethis,click on the Reseticon and you'll seethat thereis no run arrow.If you click on one of the Stepiconsrepeatedly,the alrow won't appearand you may think that you havenot enabledthe simulator properly. If you click on the Run icon,the programwill stop and the run arrow will appearat the first breakpoint (at "PORTA : 0"). Before the C programstartEthere
l , e l P I C @l ' l C UE x p e r i m e n t s f o r
the EviI
6enius
D d k . , . i
'CIPlCCLrTE\Bll.{flCl a4' C E cfl.sh @, cF ash.c'-O'cF dsh lbf,Zg9 .O .O MA_AA ,t EFOB4 'CleLCO-rT€\all.dPlCt E€'-E cFllsh.lde,'C\vvitig\8to Eli Gei],s\Gd;\cl ash\cFt&h ob , O"cFtash cot -0..F 4i
(
s 0 0 7 0 s 0 0 3 1( s000s I
Figure l-6
{)
hef -O -MPI-IA -l6FdB1
bv!€
1) btres 5) byls !o!ar Bnd 0 RAlt
EnablingMPLAB simulator
is somecodethat setsup the executionenvironment and callsthe C program.Placinga breakpointat the first statementin the programand then clickingon the Run icon after resettingthe simulator,will provideyou with an applicationthat is readyto go from the first statement. Now would be a good time to start single-stepping throughthe program. When you get to thefor statements,you'll seethat the alrow doesn'tmove for eachclick of the Stepicons or evenseeminglyfor the Animate icons.Thesestatementsprovidea half-seconddelayfor the programyou canexecutethroughthem quickly and stop at the statementsafter them by clickingthe Run icon. To understandbetter how long an applicationis taking to execute,click "Debugger"and then,,Stopwatch"to displaythe Stopwatchwindow shownin Figure 1-9.Thiswindowwill showyou how many instructioncycleshaveexecutedand how long it would
5ection One
havetakenif you wereworking with a PIC microcontroller runningat 4 MHz (whichis the defaultexecution speedof the PIC16F684).The simulatedexecution speedcanbe changedby clickingon "Debugger"and then on "Settings;"this pop-upalsoallowsyou to changeother operatingparametersof the simulator. You canalsomonitor the valuesof resisten and variables in your programby addinga Wuchwinclow (seeFigure1-10).Toadd a register,selectit in the pulldown to the dght of 'Add SFR" and click on ,Add SFR;" to add a variable,selectthe oneyou want from the pull-downto the right of 'Add Symbol"and click on 'Add Symbol."For your initial programs,I recornmendthat you alwaysput in the I/O (TRIS and PORT) registersaswell asall the variablesin your program.When you are putting registersand variables into the Watchwindow,you may feel that the method in which they are displayedis suboptimal.Youcan changehow they are displayedby right-clickingon the
U n d e r t h e C o v er s o f t h e P I C l h F h A q
2L
l-,;;;;
l*
. '' ;
iir:
"Animate"
,,Run,, :
z1€
,*.* 91ri
"Pause/Stop" "StePln' i-1..*
Figure l-7
Simulatoractive
::d
Execution at Breakpoint (ArrowOver '8")
'irj
:
Breakpoints Set
t: '.r-i ? . ;:1:
:;;.t i.i
Figure l-B
22
Settingbreakpoints
l , a 3 P I C o I I C I JE x p e r i m e n t s f o r
the Evil
Genius
14 H tU L* 3*t
{u
t t
Slopwatch Window Active (46 Cycles)
?"t *, Figure l-9
Adding Stopwatch l 1
."{ ?";"{
C J
"Watch"Window
nr
1 d
L!4t 'd6 'r
sur**e . |
qdt rd6r
|
4
l.@f---Effi
'f Figure -10 Addine aWatchWindoh,
Section One
Under the Covers of the PICl,tFhAr+
23
r*C
Ddll
Select RegisterNari DisplayType Sizeand Other
al.t
vdPs1tAetodt !d@----
l
kl!b---l '*li;----:j rro&l:-.+
l
Parameters
41
lFlr,iiIb*l htrf
4
'GqJ f@l@-tr_-ffi t r o @
;;:i*,-.;;;'
'f Fiqure I -'f
L"t
'"t .S'r H
U'
*n{ IJJ
Changing Watchdata types
variable,selecting"Properties,"and then changingthe data format asshownin Figure1--11. With the informationI havepresentedhere,you can simulate most of the functions of the code written for the experimentsin this book.Right now,you can just monitor the operationof the code,but in a later experirnent,Iwill showyou how to setspecificinput and register stimulus,which will help you seehow your applicationruns under differentconditions. For now,you canchangeregistervaluesby doubleclicking on their value in the Watch window and putting in new valuesmanually.Addingstimulusto a simulatedprogramtakesa bit more work than the execution,breakpoint,stopwatch,and variabledisplay stepsI've shownhere,but it providesyou with a way to testyour applicationunder constantconditions,rather than dependingon rememberingto set certainvalues manually. One of the nice featuresof the MPLAB IDE simulator intedaceis that it is the sameasthe ICD 2 debuggerand ICE 2000emulatorinterfacesThis meansthat whenyou startworking with thesetools, thereshouldbe only a minimallearningcurvegoing from the simulator.The simulator features I've presentedhere are alsopresentin the debuggerand emu-
24
lator.Debuggersand emulatorsprovidehardware interfacesto the application circuit (actually replacing the PIC MCU in the circuit) that you can monitor, set breakpointsfor, and repeatover differentsectionsof code,justasyou would in the simulator. that At the start of this experiment,I suggested you usethe MPLAB IDE simulatorto test all the applicationcodein this book (and any that you encounter)beforeburningit into a PIC MCU. By doingso you will gainexperiencewith the simulator and learn to comeup with strategiesthat work bestfor you.Additionally,you can experimentwith placing your editing,watch,and stopwatchwindowson the MPLAB IDE desktopin positionsthat makethe most senseto you and that allow you to debugyour applications efficiently.
For Consideration When peoplestart investigatingMicrochip PIC microcontrollers for the first time, they are generally overwhelmedby the numberof differentpart numbers (microcontrollers with differentlealures)thatare
l , e 3 P I C @l ' l C l JE x o e r i m e n t s f o r
the EviI
6enius
available.As I write thiE there are over 250 active PIC MCU part numbersto choosefrom, not including packagingoptions.Most PIC MCUs are available with at least three different packages;eachpart number is available with two operating temperature mnges,and the older parts are availablein different voltage rangesThis means,whenall is told, there are about 2,000differentPIC MCUs and optionsto choosefrom. Over the next two pages,Iwould like to make your choice a bit simpler. There are six rnajor PIC MCU families to choose from as I have outlined in Table 1-4.The PIC16F684 that is featured in this book may seemlike one of the lower-end PIC MCUs, but it is actually a quite flexible memberof the mid-range. The low-end PIC MCU processorarchitecture is available on many of the entry-level parts.The processor is very similar to the mid-range architecture (which is usedin the PIC16F684)but doesnot havesome immediate instructions,doesnot support interrupt requestqcannotsupportlargeamountsof variable memory and doesnot have any advancedperipherals. The mid-rangePIC MCU architectureis the mostpopular architecture(andusedin the PIC16F684),asit supportsmoderateamountsof variablememory advancedperipherals,and interrupts.The PIC17 high-
end architecture is somewhatunique to this familv of microcontrollers althoughit doesiave somesimjLritiesto the low-endand mid-range.The PIC18architecture is really a supersetof the mid-range architecture and it offers a number of featuresthat allow it to accessmore program memory variable memory, and peripheral registersaswell asinstructions that will simplify and speedup traditional applications.Once you are comfortable with programming the mid-range chips and have worked through the experimentsin this book,you shouldn'thaveany problemslearninghow to program and working with the other PIC MCU architectures Most new usersand hobbyistslimit themselvesto the partslistedin Thble1-5.Thesedevicesare all easily programmedeitherby the PICkit 1 starterkir, PICSTART@Plus,ICD 2, or a homegrown programmer (of which there are many different designsavailable for dornload from the Internet). The Microchip ICD 2 is a debuggerinterface that givesyou many of the capabilities of an ln-circuit emulator (ICE) without the extremecostof an ICE. I want to make a few commentson eachof the deviceslistedin Table1-5.The PICSTART Plusis a developmentprogrammer produced by Microchip, which can be usedfor all PIC microcontroller Dart
Table1-4
Il::::!il llc yi::?:::,T1P,'-. l"'"iIi* PICMCU Pmcessor Familg FlrchleEture
Programmlng PtugEm Plgqrithms and ICD Memory Tgpe
PIC10
Low-End (12 Bit)
ICSP and ICD
PIC12
Low-End (12 Bit)
ICSP
PlC12
Memory Slze
Begt4er Size
lO Plns
Featues
Flash
256 to 512 instuctions
16 to 24 bytes
4
Comparator
EPROM (OTP)
512to\,0u instructions
25 to 41 bytes
6
Mid-Range(14 Bit) ICSP and ICD
EPROM (OTp) and Flash
512to2,048 mstructrons
25 to 128bytes
6
Compamtor and ADC, Advanced Timers
PIC14
Mid-Range(14Bit) ICSP
EPROM(OTP) 4096instructions 192bytes
20
Comparator andADC, Advanced Timefi
PIC16
Low-End (12 Bit)
EPROM (OTp) and Flash
512to 2,04a instructions
25 ro 73 bytes
121o20
PIC16
Mid-Range(14Bit) ICSP and someICD
EPROM (OTp) and Flash
512to8,192 instructions
72 to 368bytes
PIC17
"High-End" (16 Bit) Parallel
12 to 33136ADC,Se al to 52 for I/O, Advanced LCD Timerg LCD, USB
EPROM(OTP) 2k to 16k rnsrucnons
272to902bytes 33 to 66
PIC18
"PIC18" (16 bit)
Extemal Bus,Serial I/O, Advanced Timers
EPROM (OTp) and Flash
6,10to 4,096bytes 16to72
ADC,Serial I/qAdvanced Time$
Parallel,ICSP on FlashParts
ICSP and ICD
SectionBne
8k to 64k instructions
Under the Covers of
the PICIEFhAt+
25
qt \J
n
n $l !-.
p-
o
r-t 8' al F.
o t
numbers-in somecasesadaptersare requiredto proanotherPIC MCU part gramthe parts.In somecases, numberhasto be usedto implementthe ICD 2 function for a specificPIC MCU. Although the PICC Lite compileris either restrictedor not availableon some of the PIC MCUs listedin Table1-5,the full product supportseachof thesePIC MCUs and doesnot limit the programsizeor numberof variablesrequiredfor the application.Each of the listedPIC MCUs hasflash programmemory!which meansthat they canbe erased by the programmerbeforeburninga new application into them.All of the PIC MCUs exceptthe PIC16F54 havethe mid-rangeprocessorarchitecture.I included the PIC16F54becausemany earlyintroductorybooks and web sitesreferencethe PIC16C54.and the PIC16F54canbe usedin its placefor theseapplications.Another traditionalbeginner'spart is the PIC16F84A,but I would recommendthat you consider more advancedandfeature-richchiossuchasthe
more advancedchipshave PIC16F627Ainstead.These peripheral aswell asbuilt-in oscilfeatures additional for you to add oscillator the need lators,eliminating circuitryto your application. I chosethe PIC16F684for this book becauseit is a mid-rangearchitecturepart (14 bit), canbe programmedby the PICkit 1 starterkit, and hasICD 2 and PICC Lite compilersupport.This chip alsohasa built-in precisionoscillatorand is tolerant of a wide rangeof operatingvoltages.It alsohasa wide rangeof peripheralsthat make it appropriatefor usewith applicationslike robotics.Tosummarize,Ifeel the ratio PIC16F684givesthe bestcost-to-performance (whenthe PICkit 1 starterkit and PICC Lite compiler is includedin the decision)for a mid-rangepart that couldbe usedin a wide varietyof different applications and would be easyfor somebodylearningto work with the PIC microcontroller.
Table 1-5 FlecommendedFirst PIE MEIJs Pan Number
Numbs Df Plns
PIC16F675 6
PtugEm Memog
Va able Mem1rg
PeipheBls
and Debugqel
PICC Lite su1pott
1,024inslructions 64 bytes
ADC,Timers
PICkit 1 starterkit, PICSTART PIUS,ICD2
Yes
Comparator
Plckit 1 starterkir, PICSTART Plus,ICD 2
No
PIC16F630
12
1,024instructions 64 bytes
PICI6F6U4
12
2,048instructions
l2tl byles
ADC, Comparator, Timers
PICkit 1 starterkit, PICSTART Plus,ICD 2 Using PICI6F688
Yes (Limited Size)
PIC16F54
13
512instructions
25 bytes
None
PICSTART Plus
No
PIC16F84A 13
1,024instrlctions
68 bytes
None
PICSTART Plus
Yes
PICI6F627A 16
1,024instructions 224bytes
PICl6F87x
26
192to 22 to 33 4,096to 8,192instructions 368bytes
Comparator,Timers, PICSTART Plus,ICD 2 SerialI/O ADC,Timers, Seriall/O
l , P 3 P I C @f l C U E x o e r i m e n t s f o r
PICSTART Plus,ICD 2
the Evil
Yes (Limited) JustPICl6F87?A and Limited
Genius
Section
Two
Introductoru f Programming
1Prc16F584
I often seethe C programminglanguagedescribedas the UniversalAssemblyLanguageby peopletrying to put it down.Thisisn't a very fair characterization becauseC is an extremelyflexibleprogramminglanguagethat wasthe developmenttool of choicefor virtually everyoperatingsystemin usetoday,aswell as for a long list of successful businessapplicationsand games. Along with commoncomputerscienceapplications,C is usedto programmore artificial intelligence, computer-aided designsystems, aerospacecontrol systems,andsupercomputerapplicationsthan any other programminglanguage.DespiteacknowledgingC's widespreaduseandpopularity,detractorstend to focuson a few points. C is an incrediblyrich languagethat makesit suitablefor a wide varietyof differentapplications. This richnesscanbe a two-edgedsword;insteadof forcing everydeveloperinto following a commonprogram layout,C allowsa wide of programmingstyles.As I will discussat the end of this section,multiple C statementscan be combined,which canmake codeunreadableto eventhe mostexpertprogrammer.An acknowledgment of C's capabilityto be written into incomprehensible codeis the singlepoint of the yearly"InternationalObfuscatedC CodeContest" (www.us.ioccc.org/) in which the most confusingcode possibleis createdfor prizes. The richnessof the codeis often givenasa reason for why C is hard to learn.I regularlycontestthis with proponentsof BASIC,JAVA, and other programming languages. All theseprogramminglanguageshavea similarnumberof statementtypes,and I do not believe that any one hasadvanlages over anotherto make
programmingwith it more efficient.In termsof readability,poor codecanbe written in any language.Good programsare not the result of the languagedesigner; they are the resultof the programmerthinking about how to approacha problemand clearlyexpressingin their codewhat the programsare doing. Additionally,C is heavilydependenton pointerEa programmingconceptthat manypeoplefind difficult to work with, debug,and understand,especiallywhen readingother people'scode.I admit that I like working with pointers,but this is due to spendingmanyyears understandingwhat pointerscan do whenprogrammedin C and how they can be usedmost efficientlyfor most applications. In this book, I will introduceyou to the basicsof C pointersand try to emphasizeonly the thingsyou haveto know to work with the language. For most C applications, pointers are minimallyrequiredand are often quite transparent to the operationof the program. My major complaintaboutthe C programming languageis one that few peoplecommenton;in its ANSI standardform, C cannotaccessdata smaller than bytes.The versionof C usedin this book canread from and wdte to bits,but you will still requiresome very convolutedcodeto carry out somehardware interfacing. Despitetheseconcerns,C hasa numberof characteristicsthat make it well suitedfor usein this book andfor individuals learningaboutprogramming. Firstly,becausethe languageis over thirty yearsold, a plethoraof bookshasbeenwritten about learningand codingit. Secondly, it is actuallyquite easyto wdte efficientandreadablecodein C, and a good portion of
27
the text in this book is devotedto teachingyou to do just that. Lastly,I believeHT:Soft'sPICC LiterMcompiler is the besthighJeveldevelopmenttool available for the PIC16F684microcontroller,and I'm pleased that it canbe usedin this book to teachyou aboutthe PIC@microcontroller. PICC Lite compilerhasthree thingsgoingfor it that I feel are critical to its usein the book and for use by new users.First,it integratesextremelywell with MPLAB@IDE. As shownpreviously,PICC Lite compiler works not only with MPLAB IDE's basicoperations,but it producesthe necessary information neededby the MPLAB IDE simulator,MPLAB IDE debuggers, and ln-cCircuitemulators(ICEs) to allow source-code-level debugging.I feel this is criticalfor producing,testingand analyzingapplications. Second,PICC Lite compilerproducesvery efficient code.In Section12,I demonstratehow I would solvea numberof math problemsusingassemblylanguage programming.At the start of eachprogram,I have written out the operationof the programin C;you may
want to cut and pastethis examplecodeinto separate C source-code filesand seehow efficientmy assembler is to the codeproducedby PCC Lite. I would be surprisedif my codehad more than 10 percentfewer instructionsthan any application,and I wouldn't be surprisedif there are caseswherePICC Lite version createdcodewith fewerinstructionsthan I did. Finally,the priceof PICC Lite compilercannotbe beat.PICC Lite compileris not a crippledversionof the full productiit includesa1lthe capabilities, including codeoptimizationand simulator/debugger/emulator support,of the full product.Thisis an important point becausewith PICC Lite compilerintegratedinto MPLAB IDE, you havea developmentenvironment with capabilitiesthat would normally costwell over $1,000dollars.Thkentogether,the C programminglanguage,with applicationswritten with an eyetoward readabilityand efficiencyand implementedin the PICC Lite compiler,is the bestmethodof learning aboutthe PIC microcontroller,microcontrollerprogramming,and applicationdebugging.
Experiment 5-Variable Declaration Statements Declaringvariablesin PICC Lite compileris generally assimpleas: int
variableNamet
beforethe main statementof the application.This will createa 16-bitvariablewith the labelVariableName (or whatevervariablenameyou want) that canbe used anywherein your program.In this experiment,I would like to discussa few issuesregardingvariableand hardwareregisterdeclarationsto help you make surethat you cansuccessfully createapplicationseventhough you haveworked throughonly a few experirnentsin the book. VariableName is a label and canstart with any upper-or lowercaseletter or the underscorecharacter. After the startingcharacter,the restof the label canbe any letter,number,or underscorecharacter.Blank characterscannotbe usedin a label;if blanksare encountered, the compilerwill try to divide the character stringsto determinewhich of them are programming statements, directivegor defines.These character restrictionsare alsousedfor subroutineandfunction names, For standardvariables,two optionsexistthat you shouldbe awareol The first is the ability to initialize the variablewhenit is declared.By addingan equals signand a constantvalue,you can setyour variableto
28
a specificvaluefor the programwithout havingto add anotherline later in the code.To initializethe variable r to 47,you would simplykey in:
Another option that is availableto the declaration statementis the constke1'word,which convertsthe declaredvaluefrom a variableto a constant: conat
in!
xconstant
= 47t
In the declarationof xconstant,anytimethe label xConstantis encountered,the compilerreplacesit with the value47.By declaringxconstant asa constant,you canno longerwrite to it. For examplethe statement: xconstant
= 48t
will return an error. If you were to look at the pic16f684.hfile that was put on your hard file whenPICC Lite compilerwas installedin the \PICCLITE\nclude folder,you will see a numberof statementsthat look like: static
volalile
unsigneal
char
tMRlIJ
e 0x08,
Theseare hardwareregisterdeclarationsand involveadditionaloptionsthat you do not needto be
l , a l P I C @l ' l C UE x o e r i m e n t s f o n t h e E v i l
Genius
concernedwith, becauseHT-Soft hastakencareof declaringall the hardwareregistersin the PIC16F684 microcontrollerfor you. I want to saya few wordsaboutvariablenames. Pleasetry to make an effort to make them representative of what they are beingusedfor. I seemany studentscreateprogramswith variablenameslike Reg3 whenthe nameRemainderor PWMValueis much more representative of what the variableis usedfor in the application.Although I recognizethat the variable memoryis limited in the PIC MCU, pleasedo not feel you haveto useone variablefor multiple functions;try to useeachvariablefor one purpose.Usingthe same variablefor multiplepurposescan makewriting your programmore difficult and causeproblemswhen different functionschangea variablein waysthat screw up the operationof other areas.
One areathat alwaysgetsnew programmersconfusedis in the areaof counters.I recommendthat you usethe conventionalvariablenamesof i, j, k, and n. Thesevaluescameinto usewith Fortran,the first highlevelprogramminglanguage,and by usingthem for this functionconsistently, they are immediatelyunderstoodwhenreadingthe code.By namingvariables approp ately,you will find the tasksof trackinghow datais beingprocessedby the applicationand of debuggingthe codemuch easier. As I explainmore aboutthe C programminglanguageto you, I will expandthe variabledefinitionto includearrays,pointers,and local and globalvariables. For the time being,if you keepwith the simpleformat of the variabledeclarationthat I haveqivenyou here. vou will not haveanv Droblems.
ExFeriment6-C Data Tgpes The bit valueis not supportedby the C languagestandard,and I would recommendthat you do not useit for variables.I realizethat a singlebit is usefulforlag variablesrn aprogram,but becausethe bit is not availablein other C implementations, you will not be able
Table 2-1 PICELite ComEilerData Tgpes Dependingon your programmingexperience, the need to specifyvariabledata typesmight seemnew and somewhatominousto you.The restrictedvariable memoryavailableto you in the PIC microcontroller under the PICC Lite compilercanmake the decision on whatvaluesto specifyseemingly moreominous. Therereally is no needfor this apprehension;most variablescan be declaredusingthe lnt datatype wilhout problem. The data typesavailableto you are listedin Thble 2-1.For the mostpart,the data typesfollow Americon NationalStarul.ards lnslinrle(ANSI) standards, or what I call StandardC values,and are availablein C compilen for other processors.This allowsyou to import programsor partsof programs(usuallyreferredto as snippets)that havebeencreatedfor other applications, but you would like to useon the PIC microcontroller. Similarly,if you wereto comeup with somegoodprogramsor algorithms,this could be exportedto other systemsquite easily. Threedeviationsexistin the PICC Lite compiler data typesto ANSI C that I havemarkedin Table2-1.
Tqpe
Bit Size Comment5
bil
I
Booleanvalue-Note: Not a Standard C data type ASCII character/signed integer(-128to 127)
unsignedchar 8
Unsignedinleger (0 1()255)
short
Signedinteger(-32,7681o32,767)
16
unsignedshort 16
Unsignedinleger (0 to 65,536)
int
16
Signedinteger(-32,768 to 32,767). sameasshofi
unsigned int
16
UnsignediDteger(0 to 65,535);same as unsignedshort
long
32
Signedinteger(-2,147.483,648 to 2.14'7 ,483,64'7)
unsignedlong 32
Unsignedinteger(0 to 4,294.961.295)
float
Reat(0 to 1/-6.81(10r3);Assume 3 dig, its of accuracy/default floatingpoint modc;Note:Nota Stanldard C datatype
21
Real (0 to 1/ 6.81(10r3)r Assume6 digits of accuracy/specified usingPICL D32 compilationoption Note: ln StandardC, this is float, not double
5ection Tu-ro I n t n o d uc t o r y C P n o g r a m m i n g
29
to import the codedirectlyto other implementations of the C programminglanguage,and you may end up gettingin a bad habit of working with bit variables. Note that I do not make the samecomment for individual bits in a specialpurposeregister.Theregister bits are uniqueto the PIC MCU and,assuch,would not be involvedin a codeexportto anotherdevice. me float anddoubk (floating point) variabletypes are substantiallysmallerin their PICC Lite compiler forms than in their high-end processorforms.For the most practical applications,you will not seea differencebetweenhow they execute,but you may have issueswith very large numbers or numbers having many digitsof precision.
ut {! I
H-l
As I haveindicated,the C data typesare strongly typed,andwhen you are equatingvaluesbetween typeEyou may get a waming or an error from the compiler indicating that a type conversionis required. If the data is stored in a format compatible with the destination,the simplestway of resolvingthis is to use the type cast,which consistsof placing the desired data type in parenthesisbeforethe sourcevariable.For example,if the variables i and j were different tlpes but data couldbe passedbetweenthem,a simpletype cast.asshownhere.couldbe used: i
= (iTr'ee) j,
The experimentfor this applicationis quite simple; just a few linesof codedemonstratewhat happens with type conversion: ff4
*incluale - rave6tigate /* cTlDe.c PICC lJite cdE)iler
Dala
Type
in
operation
Tbie Program shosra the D€eal for variab].es wheu dlata iE tsransf€rretl.
TtrD€ Casling
ThiB plograln IDE Siltrrlator on1y.
unaler
nlrhe prealko 0{.09.15
is
tlesigrned
tso run
the
of
MPr.al
char float
it jt
main ( )
t i = 47t
)
j = i;
//
can vou Plac€
char
i = i,
//
can you Place
float
(1 == llr while // Enal cTtrp€
//
into
f,loat?
inEo
Loop Forever
When you compilethis application,you are goingto get the message: warningt000l C:\ Evil Genius \c!P!.De\cTtDe. iq)licit converEioa of float to inlege!
c 27
:
is tellingyou that the statement"i = j;" This message When this messagecomes involvesa data conversion. up,you haveto decidewhetheror not to resolveit by usinga typecastor by leavingthewarningasis Rememberthat the two datatypesstoredata in different ways(whichcanbe inferredfrom Table2-1);casting the float type to a char is a bad idea becausewith the type cast,the fkst byte of the float type couldbe passedto the char without beingmodified.In this case, you would leave it asis. For virtually all the applications in this book and for virtually all the PIC MCU applications that you will do on your own,you will only requirethe int data type. This 16-bitbit-variabledata type will handlea reasonably largerangeof valuesaswell aswork with ASCII characters.This data type is handled well natively in the PICC Lite compiler,but for long and floating-point datatypes,additionallibrarieswill haveto be addedto the final application.Theselibrariestake up quite a bit of spaceand can slow down the execution of the appliTo avoidthis spaceissueand cationsignificantly. reducedexecutionperformance,I recommendthat thesedata typesnot be usedunlessabsolutelynecessaryand the impactof their operationis well understood.Later in the book, I will give you a coupleof thoughtson how to simulatethe operationof these data t)?es using8- and 16-bitvadables.
t,,l tt!
'&&* 3C
30
char?
l , a 3 P I C @l l C U E x o e r i m e n t s f o n t h e E v i I
6enius
l-+1
Experiment 7-Constant Formatting .aJ & !{DTDIS & PWRTTN & IICIJRDIS & -CONFIG(INTIO T'NPROTECT \ & I'NPRC},IECT & BORDIS & IESODIS & FC!'DIS) t
iU i-
main( )
{ 't rt
PORTA = 0t CMCONo = 7i // Turn off Corq)arators ANSEIJ = 0r // Turn off JU,C TRISA - 0*49t // E':able PORTA IJED Oull>uts
When I introduceddeclaringvariables,I suggested stronglythat variablenamesshouldbe representative of what the data is usedfor, and if the variablesare usedfor commonfunctions(suchascounters),they shouldbe givenconventionalnames.Thispleais commonto manyprogrammingbooks,but what isn't all that comrnonis a pointer to speciq/ingconstants in the mostappropriatedatatype for the situation. The readabilityof a programcanbe enhancedor damagedby programformatting,by variablenames,or by comments.
Table 2-2 EonstantFormattingOFtionsand 5uggested Best UseE Constant Definition Fomat
Best Use
Decimal
##
Default Value
Hexadecimal
0x##
RegisterCounterValues
Binary
0bf#ffifrfrf Noncounrer RegislerValues '#' Human InterfaceValues
ASCII
while(l
== 1)
l'a-
Ijoop Forever
//
{ ( 0 = = ( P O R T A& ( 1 < < 3 ) ) ) PORTA = '3'// Tuln on Fou! LED8 eLse PORTA = 4r // Turn on Remaining Four if
//
) //
)
IJEDS
erihw Enal cconfu8e
Chancesare,you couldnot understandwhat cConfusedoesby just looking at it.You will probably haveto look at a schematicfor the PICkit 1 starterkit LEDs and applicationinput hardware.By makingfour changesto this prograrn(and turning it into cClear.c),I think you'll agreethat the functionand what is happeningis a lot easierto understand. *incluale - *cconfuse.cz /* ccLear.c a Deobfuscator
after
pasaing
!i, i:?
through
T]hia is lh€ same program as $cconfuse. c-, but with rrore appropriately chosen constant tlata values. nyk€ predlko 0{ . 11. 1s
1= i:-;;
Thereare four waysto specifycomments,asis listed in Thble2-2 alongwith the situationswherethey are bestused.In cconfuse.c,I havecreateda simpleapplicationthat usesdatain differentformats;beforeburning it into a PIC16F684and runningit in a PICkitrM1 starterkit, try to figure out what it does. *incluale - wri!€ /r ccoffus€.c to plcki! Ilaralware in a Confuaing Way This program Derforms function ia obfuscated t]lDes.
CONI,IC ( IIITIO & WDTDIS & PWRTEN & I{CLRDIS IJNPROTECT \ & I'IIPROTECT & BORDIS & IESODIS FCI'IDIS ) i
nain( )
{ PORTA = O' Cl.fCONo = 7; // \tr'r ofg Cornpalators ANSEIJ = 0t // I'urn off ADC TRISA = 0b001001i // EnabLe PORTA LED Outsputss
Interface
wr!ire(1
a simple task. but ils b!' poorly chosen dtata
== 1)
//
looD
Forever
t it
fiE'ke prealko 04.11.15
(0 == 8A3 ) PORTA = 0b010010t
//
Button Presseal, D4, D7 On
PORIA = 0b000100r
//
BI'rt.Eo'r Releaaeal, D5, D5 On
//
, l
5ection Tulo
& &
//
D0, D2,
D1,
D3,
eli'nw Enal cclear
I n t r o d u ct o r y
C Prognamming
31
Threeof the changeswereto convertthe TRISA andPORTA registerassignmentvaluesto binary from decimal,hex,andASCII. I think you will agreethat they wereeffectiveand helpedyou seewhat washappeningin the applicationand the output values.The fourth changewasto eliminatethe complextestof the RA3 (button input pin) and simplydo a bit compare. With the bit compare,you couldeasilylook at the PICkit 1 starterkit schematicand seethat RA3 is connectedto a pulled-uppushbutton. When decidingwhich constantformat to usein your program,you might want to follow theserules: .:t,13 .
$ .i.il
.
-i-,
Use decimalby default.For basicvariableand variablefunctions,decimalis probably most appropriateand easyto read. Use binary when you are working with a register that doesnot containcounterdata.An
.
exampleof this is loadingthe OPTION register with the value0b10011111. Use hexadecimalfor registercountingor result data,Comparinga counter'scurrent valuewith a hexadecimalconstantwould be most appropnate.
.
UseASCII data when human interfacesare involved.Thisincludestext messagingaswell as userinput.
.
Data sizesshouldbe appropriate.Use six bits for the two setsof six-bit PORT andTRIS registers.For other registers,useeight bits.
I think what I am trying to sayin this experimentis bestsummedup by the maxim:"There are 10typesof peoplein this world: thosethat understandbinaryand thosethat don'1."
it t
a::-i
Experiment 8- RssignmentStatements .rj r", il i: t_'j'
1l'-.€ .'].{
,t:; I
c;
If you are familiar with other highJevelprogramming languages, you are awareof the statementtype called the assignment statemezl, which is usedto storedata of a variableof a specified type.In thepreviousexperimentEI havedetaileddifferentdata typesaswell as how variablesare declared.In this experimentI will presenthow assignment statementsare written in C. The basicform for a C assignment statementis: ValldbleNam€
.:;".1
.... ill1.:
1::
= E <pressiont
The labelVariableNameis a variable.declaredas shownin the previousexperiment.The singleequals signindicatesthat the variableis goingto havea new variablevaluestoredin it. I point out the singleequals signbecausethe appearanceof two equalssignsis a logicoperator,asI will explainin a later experiment. The expressionis a data type value that is the same asVariableName. An expressioncanbe a constant,the contentsof a variableor a seriesof mathematicaloper-
32
ations.AlthoughC is somewhattolerantof assigning differentdatatypes,you shouldalwaystry to make surethat the expression's type is the sameasthe variable's,and if it isn't,make sureyou understandany potentialissues. An exampleof a potentialissuebetweendissimilar typesis savinga L6-bitvaluein an eight-bitvariable.In this case,the upper-eightbits will be discarded,which could be a good thing (you are providedwith a simple way of strippingout the most significantbits) or it couldbe bad (with data lost).To avoidthis problem,I tend to declareall variablesasint (16 bit). Finally,the assignmentstatement(and virtually all other statements)is endedwith a semicoloncharacter (;).The semicolonis usedby the compilerto indicate the end of the statement.Theonly statementswhere the semicolonis not requiredare the onesthat end in a right brace(l) character.Whenin doubt,put a semicolon at the end statement;evenif it is unnecessary, the compilerwill treat it asa null stutementand ignoreit. To demonstratethe differentforms of the assignmentstatement.IhavecreatedcAssign.c: *includle - A brief /t cAssign.c Stat€ments This Program Demonstrales Statements work in C.
l , e 3 P I C @l l C u E x o e r i m e n t s f o r
the EviI
l,ooh
at
Assignment
how AaEigrment
6enius
nJake prealko 0 4 . 0 9. 2 4
//
j = 23, //
irt
//
uditiaLized variabl€ D€claration valiabl€ DecLareil with Initial ( Initialization) value assisnment
nain( ) t \ri', aBsigned (or loaaleal The variable with) the conalanl value 47 "i,, aaEigneal contents rhe variable //
)
//
"i"
axud "j"
aasigneal
the
Ean6 va1ue.
complex,with their functionbeingconfusedwith the built-in assignment statements. Access(readand write) of PIC16F684'sregisters and I/O Pinsis accomplished usingstandardassignment statementssuchasthe onesdemonstratedin cAssign.c.Theregistergbits,and pins are all declared in pic16f684.inc, which is loadedin by pic.h.cl-ight.cis a simpleapplicationthat simplyturns on D0 on the PICkit 1 starterkit and illustrateshow registerscan be written to 8 bits at a time,just as8-bit variables(of type char).Indivrdualbits are readfrom andwritten to in exactlythe sameway. #incLude - Sinple c Program lo /r clisht.c on a PIC16F584 in the PICkit 1
End cAsaigTl
The filst assignment statementis the initialization of the variablej. Thereis no differencebetweeninitializing a variableat its declarationand assigninga value to it in the ffustline of a program.You may find that initializinga variableat declarationis easierto read, makingits functioneasierto understandin the program.Thenext two statementsare basicassignments of a constantvalueand a variablevalue,respectively. Thesestatementsare commonto other programming languagesand their operationshouldbe obvious. The last assignment statementis probablysomething that you haveneverseenbeforein BASIC or other beginnerprogramminglanguages; the valueof i is giventhe valueofj, which itself is beingloadedwith a new value.Thisis one of the many capabilitiesbuilt into C that canbe usedto both simplify application programmingand obfuscatethe functionof the applicationcode.This,lultiple assignment statemen1which hasmultipledeslinalions [or theexpression. is reasonably clear,but asI will showin the next experiment, multiple assignment statementscanbecomequite
aA4 - LED Poaitive a-45 - r,ED Negative
Turn
on an LED
Connection Connection
myke predlko 0{ . 11. 10
CONFIG(II\TIO & WUTDIS UNPROTECT \ & UNPROTECT FCTiIDIS ) ,
PWRTEN BORDIS
& IICI,RDIS & IESODIS
&
nain( )
(
CMCoN0 = 7; ANSEIT = 0r TRISA{ = 0r TRISAs = Oi
// // //
Tlrr| A\rrL rtake
off conpalators off ADC RA4/RA5 Oueputs
aA4 = 1r n-4,5 = 0t
//
'\ErL
on LED
//
hoop
vr{hile(l l
//
== !),
End cliqht
Experiment9 - Expressiong potentialexistsin the capabilitiesof the C expression statemenlthal canmakeyour programmingeasierand more efficient.Unfortunately,this potentialcomesat a cost:it's easyto createexpressions that do not execute asyou would expect,and are very hard to debug.In this experiment,alongwith looking at differenttypes of expressions that canbe usedin your applications, I will presentsomeof the potentialpitfalls you may have to navigatearound. In the previousexperiment,I really skippedover what an exnressionis.Thisis unfortunatebecausea lot of
Section Turo
To demonstratethe operationof C expressions, I cameup with cExpression.c, which examinesdifferent
Introductory C Prognamming
33
formatsfor expressions and data.As you readthrough the descriptionof this program,I suggestthat you load and singlestepthroughcExpression.c so you canbetter seethe points that I am making. *incluale /* cE.Dression.c
-
Look at
Thia Program tlenronstrates Dif,f,er€nt E apr€aaions that
E {pressions a variety of can be createal
ilr
C.
nyk€ Drealko 04.09.23 Haralware Notea: ThiB Program has be€n wlit.ten to the MPtAa IDE Simu!.ato! ONLY,
naitt(
run
in
)
{ // //
n3" \i"
i = j * 1 1 ,
//
Siq)le
i = j * 0 x 0 B t
//
!4r1tip1y
i j
{r,{
*;
= 3t = i;
+ 0b00001011,
i
= j
i
= r0,
j
= 4e /
i
= (i
i
= j
+ Ai
// // ll // //
itl
r.,,.:l
l
-
4t
i
= (j
= i
j = r / 5
//
i = i
while
bg a Hex value
uulriDLy value
by a Binaly
Same AB previous Eoicad Oralet of
// I/
6,
/
//
E
c@s,lex Arithmetic E q)reEsion Involvingl Two Ogeratsion8 anal !'otced. Oraler of Operatlon6
L = j - s % 7 = L2 - s % 7 = L2 - s
/t // //
E qr!€aEion ErqrleEEion
Load. i with ASCII $8,, change 'watscb,, winalow aliaplay Eoflnag Eo ASCII to verify lo.retif.y. Ba6ic Division
5) %7,
5 %7,
the the
AriEbmetsic
//
// // // t / i = l i - 5 1 % 7 // = lL2 - 5' % 7
-
iB fa
but ao Operations
(5 % 7 = s)
* 2t
//
BrbeaLleil
asEighment:
t 6\ * 2
(1 == a)t
//
IJooDrorev€r
i r ) //
E'rd cE.pteaaion
t::
...i
The first two statementsshouldbe pretty straightforward.Inthe firststalement. theexpression is a constantvalue(3) that is storedin the variablei. Next,the
34
contentsof i are the expressionand they are savedin j. Theseare assignment statements,just like the onesin the previousexperiment. The next threestatementshavethe sameexpressions( x 11).Thedifferencebetweenthem is the numberingsystem(radix) usedto expressthe constant4. This is a reviewof the C DataTypesexperimentin which I discussed how usingbasesother than 10makes it harderto immediatelyseewhat is happeningwith the code. In the assignment statementsfollowing the three j x 11 statementqI am applyingthe basicarithmetic operations(addition[+], subtraction[- ], multiplication [*], and divisionUl, alongwith the modulusoperator [%]. The modulusof two numbersis the remainderof the divisionoperation.In the next experiments,I will look at someof the other operatorsavailablein expressions The next statementhasan expressionthat you haveprobablyneverseenbefore;I am addingthe contentsof the variablej to the ASCII characterzero (whichis specifiedin singlequotesas '0').The valueof this expression(and the valuestored in i) is 51 decimal,or if you changethe Watchwindow displayformat for i to ASCII, you will discoverthat it is'3'.This may be a surprisingresult,but if you were to reviewa tableof the ASCII codes,you will seethat the numericand alphabeticcharactersare defined together;so if you haveone character'svalue,you can jump to anothercharactersimplyby addingor subtractingthe differencebetweenthem.This property of ASCII codesis usedin a numberof placesin the book to algorithmicallychangevaluesinsteadof relyingon decisionstructures to changelhem. "i : the C 5) % 7;" statementhaswhat is known as a compkx. expressioz:that is,multiple operations are performed within the statement.Looking at the first statement,it shouldseemobviousthat five is addedto the valueofj and the sumis found usingrnodulus7. Right after this statement,I haverepeatedit with parenthesisaroundthe "j - 5" expressionremoved. When the full expressionis evaluated,you will seethe result(storedin i) is differentthan in the previous expression. The reasonfor this difference is due to the order of operationsof the operatorsusedin thesestatements. The multiplicationand divisionoperatorshavea higherorder of operations,or what you could refer to asexecution priority, than addition and subtraction instructionshave.Even thoughthe additionoperatoris encounteredbeforethe modulusoperator,the modulus operatorexecutesfirst becauseit hasa higher order of operations. To avoidtheseproblems,you shouldenclosehigherpriority operationsin parenthesis(indicatingthat their contentsmustbe evaluated beforethey are usedfor other operations)to ensure
l , A 3 P I C o l l C l JE x p e r i m e n t s f o n t h e E v i l
6enius
they executebeforeother operatorsexecute.Asyou look throughthe codein this book,you will seethat I am in the habit of alwaysusingparenthesisto ensure expressions are evaluatedin the order l want them to. The final statementbeforethe "while (1 =: 1):" statementmay look like a syntaxerror or somekind of comparison,but it is an exampleof what I calleda multiple assignment statementin the previousexperiment.Neither is true;the expressionsavesthe intermediatecalculationof i./6in the variablej before completingthe evaluationand storingthe resultin the variablei. This ability to embedassignments within expressions can help you simplily your programs and/ormake them completelyunreadable. When you first start creatingyour own C programs,I recommend
that you do not try to combinestatementsasI have done here.But whenyou gain someconfidencethen you might want to look for opportunitiesto take advantageof this capability.Especiallylook in situations wberethe intermediatevalueof a calculationis neededelsewherein your application. With the five basicarithmeticoDeratorsand the a b i l i t yt o c r e a t ec a l c u l a t i o n wsi l h m u l t i p l eo p e r a t o r s . you havethe ability to developexpressions for the vastmajority of applicationsthat you are goingto be w o r k i n gw i t h .B e f o r eg o i n go n .t r y l o w r i t eyo u r o w n applicationlike cExpression. Testout differentexpressionswith the five operatorslistedaboveand with constantdata in decimal,binary,hexadecimal, andASCII Iormals.
Experiment I 0-Bitr-r.rise Operators
.
As well asbeingable to perform mathematical operationson the contentsof variables,the C programming languagehasa numberof operatorsthat allow you to perform Booleanarithmeticon the bit contents of variables.Theseoperatorsallow you to easily processbit information,but they mustnot be confusedwith the logicaloperatorsdescribedin the next expenment. The four basicbitwiseoperatorsare asfollows: .
.
.
& -bitwise AND. When two valuesare ANDed together,eachbit in the result is loaded with the AND value of the correspondingbits in the two values(serif both the bits are set). I bitwise (inclusive)OR. When two valuesare ORed together,eachbit in the result is loaded with the OR value of the correspondingbits in the two values(setif eitherbit is set). ^ -bitwise XOR. When two valuesare exclusivelyORed together,eachbit in the result is loadedwith the XOR value of the corresponding bits in the rwo values(set if only one of the two parameterbits is set).
SectionTuro
- -bitwise negation.Thisoperatorwill return the negatedor complementaryvalue for each bit of the singleinput parameter(invert each bit). This operatormust neverbe confusedwith the ! logicaloperator,which will be shownto invert the logicalvalue,not the bitwise value.
Using thesefour operators,standardbitwise Booleanarithmeticoperationscanbe performedon differentvalues,asI showin cBitwise.c. After compiling cBitwise.c,Isuggestthat you work throughthe code(includingmodifyingvalues)in the MPLAB IDE simulatorasmuch aspossibleuntil you fully understandthe operationswork.When you are doing this, you shoulddisplaythe variables(i, j, and k) asbinary valuesin the Watchwindow. *incl"ude - Bitwise /* cBitswise.c
C operatols
This Prograln Denonstlates how bitwis€ arithrnetic oD€latioas wolk in c. Note:
Display
the
valiable
values
as
Boolean
\Bina!y".
nyke predko 04.10.02
char
i,
j,
ki
//
use
8 Bit. variablea
nain( )
t
Introductony C Pnognamming
35
//
hilialize
values
& it
//
AND Values
togethe!
rr = i I i;
//
OR valueB
k = i ^ it
//
xoR values
together
k = -i;
//
wLvetE the
aits
j
= a37i
k = i
k = ( i * 2 ) - j + (1 << 71,
together
ll
in
"j"
rtix BirLat! opelacors vrith
// Alitlu[€tic =- 1)t while(1 //
l
End cBitwise
The operationof bitwiseoperatorsis very straigh! forward.Going throughthe examplecBitwiseexperiment in the MPLAB IDE simulator,you shouldsee the Booleanarithmeticoperationsclearlywhenyou displaythe variablesasbinary in the order i, j, k. The Watchwindowwill displaythe two parametervalues directly over the result,allowingyou to comparethe inputsand outputsto the logic gatesdirectly.As shown in the laststatement,bitwiseoperatorscanbe combined with arithmeticoperatorswithout any special considerations. Although the bitwiseoperatorsare straightforward, you canrun into somedifficult-to-debugsituations whenyou write to registersin a PIC MCU (or any other hardwaredevice).Toillustratewhat I mean,considerthe laststatementof cBitwiseand haveit load a port directly.For this example,assumethat the hardwaredeviceattachedto this port savesthe leastsignificantfour bits of the PORTA, and bit 7 of PORIA is connectedto a deyiceclock.When the clockis pulsed high (or strobed),the hardwaredevicesavesthe four data bits.Thestatementcould be: p o R T A= ( i
* 2) - j
+ (1 << 7)r
//
wrire Dara
from j, which hasbit 7 set).This is a dangerousassumption asyou do not know how the expressionis evaluatedby the compilerand whetheror not the destinationis usedfor storingtemporaryvalues. Becausethe operatorsoutsidethe parenthesisexecute on the sameorder of operations,you can assumethey executefrom left to dght. In this case,PORTA is loadedwith the productof i * 2, and then hasthe contentsofj subtractedtuomit with the valueof 0x0D5 beingtemporarilystoredin PORIA. Finally,128 (1 << 7) is addedto the valuein PORIA to clearbit 7.In this case,you will haveinadvertentlystrobedthe four bits of data into the deviceconnectedto PORIA (becausewhenj wassubtractedfrom i * 2, bit 7 wasset and the final add clearedit). You haveprobably strobedin an unwantedvalueaswell.Thistype of problemis extremelyhard to find and debug;simulating the applicationwill not revealthe problem,and you may needan oscilloscope to seebit 7 changing duringthe instruction'soperation. The fix to this potentialproblemis to usean intermediatevaluefor all complexexpressions that are goingto be loadedinto a hardwareport.This changes l h es i n g l es t a l e m e ni nt t ot h el w o t h a t y o uc a ns e e below: k = (i * 2) - j + (1 << 7)' ,,
X::n"::";":i..
PORTA = k,
As a generalrule,neverwrite the resultof a complex expressiondirectlyto a hardwareregisterwithout first storingit in a file-register-based variable.If you follow this rule,you will guaranteethat the valuebeing storedin the registeris exactlywhat you want with no potentiallyproblematicintermediatevalues. It will probablybe surprisingto you,but the operators normallyreservedfor conditionallogic are part of just asthe adthmeticand bitthe numericexpressions, wiseoperatorsdiscussed in the previoustwo experimentsare.This givesyou someuniqueopportunities for cleverprogrammingaswell asan opportunityfor errorsthat are very difficult to find and debug.
::"1::"-"'" and knowingthat it endsup as0x055fi'om the simulation of the program,you are comfortableknowingthat bit 7 of PORIA is neverloadedwith a high value (i.e.,
50
l , e l P I C o 1 1 ( UE x p e n i m e n t s f o n t h e E v i l
6enius
H
Experiment 11-LogicalExpressions
vt F'
in
04.o9.27
i-l r ) }J"
r."8
i n t i = 5 , tnt j = 10, int ElpvaLuet
E.DreaBion
//
value
!"{
rnain ( )
(
The logic operatorsavailableto you in C are listedin Table 2-3 and return numeric true or false values.It is important to remember that logic operatorc are different from bitwise operators asthey return essentially binary values(Tiue or False),wherethe bitwiseoperator returnsthe logic operationfor eachbit.
Expvalue
= i
== jt
E.pvalue
= i
l= jt
r'IhaE is the value Falae? // Value f,or Tru€?
E:.9va].ue E Dvalue
= i = i
> jt < it
// //
E.DvaIue
= (i
!= j)
&& (i > j),
E:.pvalue
= (i
t= i)
ll
//
E .DVaIu€ = 1 & & l , E:.DVaIu€ = i & &
*r H
vallue f,or Falae? vallu.o for Tru€?
(i > i)t
Table 2-3 Logic Operatorg Lagic Operator Operalion
f,or
//
Tru€ Tru€
//
What abouts ORing?
// //
r'rvetE *i" r,oglc value *i. logic DoltbLe ravelt value
//
LooD Eoreve!
If if
a
// value for trrue AND FalB€? // valu€ for Tru6 OR Fala€?
Both one
valuea
F
!= 0?
F.r. E.Dvalu€
A = = B Return Tiue if the two valuesare equal.
= t
ll
E
A != B
RetumTlue if the two valuesare different.
A > B
ReturnTrue ifthe first value is greaterthan the second.
A > = B Return True if the first value is equalto or greaterthan the second.
while(].
== 1)t
0t
t d
gj
P
Endl er,ogic
A
RetumTrue ifthe fi$t value is lessthan the second.
)
A<=B
RetumTrue if the first value is equalto or lessthan the second,
By steppingthrougheachstatementof this program, you will make a few conclusions:the first being that Ti.ueis given a value of 1, and Falsea value of 0. You will alsoseethat the first six assignments work you your exacllyas might expectbasedon experience (Although the with other programminglanguages. idea that the result of a comparisoncan be used asa numeric may be somewhatnovel.) The last five statementsprobably are surprising,but they do emphasizethe point that logic operators are similarto standardoperators:Nonzerovaluesare treatedasTiue,and the zero valuesare treatedas False.From thesefive statements,you should seethat the samerulesthat are appliedto logicalvalues(zero and one) are also applied to standardnumeric values. This shouldbe kept in the back of your mind,because it allows for someclever programming tricks suchas:
A && B ReturnTiue if both valuesare true (not equalto zero). A !l B
ReturnTiue if either value is hue.
!A
Return the invertedlogic level ofthe value.
The experiment'sprogram(clogic.c) teststhese arithmetic operators for two different values.This program should be run in single stepsthrough the MPLAB IDE simulator with the Watch window set up and ExpValue displayed.As you step through each C statement,you will seethe resultof the logic expression savedin ExpValue. *incluilo - Quantify /* clogic.c Thia Plograrn looks €rg)r€aaiotr vaLuea D?ofluceal by thdr. Thia proglam ainulator. lEike
Is
tq
at enil
to
Logic lhe lh€
E:.greEaior
Valu€B
aliffe!€nt logic valuea lhal ar€
be ua€al wilh
juat
//
i
F 0x123{
*
(i
> {)r
ll
i,f, li > 4) ia lh€D 1 relulneal
Tru€,
th€
D!€alko
Section Tr.r.ro I n t n o d u c t o r y C P r o g r a m m i n g
37
FI X rd
r-9 {D {0
{n
t-,..
which is equivalent to: i r ( j > 4 ) i = 0x123{ t els€
The advantageof this type of programmingtrick is its apparentelegance. Although the singleline looks like it is much simplerthan the full iflelsesolution,you might find that it usesa greaternumberof programming statementsand file registersand that it takes longerto executedue to the needto includethe multiply routine.Additionally,the lack of gotosor diversionsto differentstatementscouldresultin a statementthat hasa constantexecutiontime,which can be a significantadvantagein someapplications. And althoughit may not necessarily be more efficient, you shouldnote that its operationis not intuitively obvious,and you and otherswill probablynot understandwhat is happeningin the statementby simply looking at it. Statementslike this are interesting curiositiesthat shouldbe avoidedunlessthereis a tangible reasonrequiringtheir use. The pitfall that you canrun into with C logic operators is with the eq&akto (==) statement.Thedouble equalssignis a good solutionto the problemof differentiatingbetweenthe assignment equalsand the comparisonequals,but it doesnot take into accountthe conditioningof peoplewho work with other languages like BASIC, in which a singleequalssignin an i/or a whilestatementrndicatesa comparison.It is very easy to forget yourselfand put in a singleequalssignwhen two are requiredfor a comparison. If a singleequalssignis usedin an expressionlike
I am not beingfacetiousby suggesting that you neverusethe equalslogicaloperator.If you are comfortableprogrammingin BASIC or other programming languages that havea singleequalssignasa compadsonoperator,you will havea greatdealof difficulty with the doubleequalssignin your logical expressrons. Throughoutthe book, I discusshow you canmake your programsmore efficientby Iookingat different waysof solvingthe applicationrequirements.It is a bit of a fine line to walk becausesomefeaturesof the C programminglanguageallow you to usefewer keystrokesto solvea problem,but often at the costof programreadability.(The exampleat the end of this sectionillustratesthis very well.)What you shouldbe lookingfor are optimizationsthat do improvethe readabilityof the code,improveits efficiency,and reducethe total applicationsize. A greatexampleof how this is done can be illustrated by looking at the first C programyou were given(cFlash.c)and looking at what its basicrequirement is (i.e.,to togglethe LED at RA4/RA5 on and off). In the originalcodeI gaveyou,I explicitlyturned on and off the LED, but by thinking of the problem from anotherperspective, for example,that you want the LED to be toggled,you might think in termsof basicBooleanalgebraandconsiderchangingcFlash.c to somethinglike the following: *incluale /* cFlash 2.e - Sinple oa a Prc16E684 This Plograln 2.c" .
is
an optimizeal
aA4 - LED Positive RJA5 - LED Negative
insteadof the requireddoubleequalssign:
the programwill behavethe sameasif i wasalways equalto 47.Tomakemattersworse,if you put a breakpoint to checkthe valueof i after the comparison,it will seemlike the valueis always47.What makesthe error so hard to debugis that it /oofr right.To avoid this problem,generallytwo approaches can be used. The first is to make sureconstantvaluesare placedto the left of the comparison.If a constantis to the left of a singleequalssign,the compilerwill return an error statingthat it cannotwrite to a constantvalue. The secondsolutionwill seemmore drastic,but it is effective100percentof the time.Simplydo not perform an equalscomparison.Instead,the resultof a not equalscomparisonshouldbe NOTted asshownbelow in the expressionthat is equivalentto i : = 47: ! (i
38
C Program
!o
Flaah
version
of
an LED
"cFlaEh
connection Connection
nyke predko 04.ta.a2
-CONEIG(IICIIO I'NPROTECT \ FCMDIS) t
irrt
i,
& WDTDIS & TINPROTECT
& PUIRTEN & MCI,RDIS & BORDIS & IESODIS
j t
nain( )
{ PORTA = O; CI4CONo = 7r ANSEI, = O'
TRrsa4 = 0r TRISAs = O'
// //
//
Turn of,f, Cdparators lPurn off ADC Make ItA4/RA5 Outputs
!= 47)
l , a 3 P I C @l ' l C UE x o e n i m e n t s f o n t h e E v i I
6enius
& &
1)
].oop
//
Forever
{ (i
for
= 0t
i j
BA4 - A,A{ ^ f, ) // elihw ) // End cFlash
< 25s; i++) // < 729, j++\ i Toggle
//
Sfinple
500ns Delay
LED St'ale
2
The change in ihe code was to change the two RA4 assignment statementsto one in which RA4 is toggled (XORing a digital value with 1 will always invert, or
toggle,its state).Thisallowedme to eliminateone of the 500ms delayloops,thuseliminatingan opportunity for error (i.e.,keyingin the seconddelayloop properly),which resultedin a better than 36 percent decreasein final applicationsize.Along with thesetangible improvements, the readabilityof the programhas beenimprovedbecausethe cornmentafter the XORing of RA4 statesclearlywhat the statementis doing and it can be directlyrelatedto the basicoperationof the program.
Ex per im ent l2- C o n d i ti o n a lE x e c u ti o n
Usingthe lf Statement the operationof the braces,I modifiedcAssign.cto createcstatement,casfollows: #incluale - A quick /* cgtat€ment.c stat€ments in c This work
Prosran in c.
further
qrperiment
er.amines
legarding
hovr statenents
m]'ke preflko 04.10.05
The basic form of the if statement in C rsi if
($er€ssion)
//
Test t'o Be€ if.ErrDression" is Not zero \E>!I)r€ssion" if
!5 0 \'else,, else // Optional statement which Statement if E:{pression is // Executes
int int nairl(
(i
(j
/
3)
/
3))
followins // Execute | / if. "i / 3" is no! // //
slatenent zero
Execute f,ollowing ataternent it "j / 3" iB not zero.
In both casesthe next statementis executedif the resultofj dividedby threeis not zero.The secondcase is not that much more difficult to follow,and it avoids any issueswith comparisons with constants. As the if statementis written above,you might think that only onestatementcan be executedconditionally. This is not true becauseof the useof braces( {and}) to collectmultiplestatementsinto one.To demonstrate
Section Tuto
)
Zero \i" (or assisned // The variabl.e the constant value 47 // Loaaled with) Blaces B€ Put in before a slatement? // ca { "i" i = ir assisned conlents // The variable / / ot \jt . i = j = 1, // \\i,, and '.j,' aasigneal the Bame ll vatlte. , / | E'rd. of State$e[t i
!=
variable unilialized Declaration variabLe Declareal with hitial (Initialization) value assigrhent
ll // //
{
and is similarto the operationof the if statementin other structuredlanguages, althougha few points shouldbe noted.The first is that the test expression doesnot haveto be only a simplecomparison;it can consistof complexterms,which may or may not have comparisonoperatorsin it.The two expressions in the if statementsbelow are equivalent (0
it j = 23t
= 47i
while(l //
)
== 1),
Enal cstatement
Using braceschangesthe basicform factor of the if statementto: if
(Expres8iorr)
| // ope'ri'rg statelrentr Statelr€ntr gtatementt
'Expressionleet if is Not zeio Blaee to colLect stat€lr€nts statenents that // Multiple // Errecute if, E>(I)lession // i.s Not Zero // //
Introductory C Programming
39
if, E:<pr€asion is zero else // Execute Statem€nls { // Opening Brace to Col1€ct E.ecule Stalemeatr Statements lhal // Uulliple ia zero Slat€lrent r // E.preEaion Slatement t
I
//
if
fi
This is the recornmended format for peoplejust startingout programmingin C.The bracescan be eliminatedif thereis only one statementfollowing the il for example:
. r"*
if
(a == b)
to help keep track of what the program is doing. For simple programg it is hard to seethe importance of this trick, but asyou work with more complexapplications,the needwill becomeobvious.You'll find it necessarywhen the compiler comesback with the messagethat thereis eithera missingor an extra closing brace.This is a goodhabit to get into andwill later saveyou time and grief debuggingsyntaxerrorsin your program. To demonstratethe operationof the if statements,I createdthe cllc applicationasfollows: *includle
of
Oreration _,t
9 3
w 5' l>et-i
i-g't f'{
-l
",={
.r*
But to avoidproblemsrememberingwhetheror not bracescanbe used,you shouldalwaysput them in and then stopusingthem whenyou are more comfortable programmingin C. In the basicform of the if statement,you might havenoticedthat I indentedthe statementsthat executeconditionally(i.e.,on the valueof the expression). This is a common programming technique to visually indicatewhich statement'sexecutionis dependanton the higher-leveldecisionstructure.I indentby four spacesfor eachlevel simplybecausethis is what the MicrosoftVisualStudioeditor uses.and I am simolv following its example. When you look at other people'scode,you may see that the openingbracesare not at the start of the next line,they couldbe placedat the end of the previous line asshownin the following: if
(E qEession)
Statem€ntt stat€tnentr gtalementt
;
// //
Thia program 1f gtatement.
'r.-t
9,*
operalio[
th€
^=21, nain( )
{ (44 == f,
//
"i"
n = n + 1r
//
Inc!€lle|rt
if
equaLs a cotrstant
{
Nn/
if
$iz
== 44
] €lse
t
n = n - 1i //
Decretnent if
Not EquaLs
.ExDressioa"
((j
if
{
j
|
Brace to Eail ) // closins if, E:.plession is else // Execute { Statsem€nlt Stat.ementE tshat // Uuttiple stal€menlr ia zero // if Er.pleaaion Stalementt
= (i 1 311 == 7l
= j + 1, // fi
(k = 22) |t = n + 1i eLse a - a - 1i if
zelo Execute
while(].
The compilerreally doesn'tcareaboutthe position of the bracesThey can appearanywhereafter the if statement.(The is alsotrue of the closingbraces.)I recommendthe placementshownherebecauseit is very obviousvisuallywhetheror not the bracesare presentor missing. You haveprobablynoticedthe "fi" commentplaced after the lastclosingbraceof eachif statement.The reasonfor this comment is to remind me of the purposeof the closingbrace;whenyou havea very complex and long program,the reasonfor the closingbrace canbe forgottenor confused.I mark all programstatementsthat producea bracewith their lettersreversed
,
//
Erit
--
// // // 1),
hcrem€'lt
Nn/
Note that stateneat,
there Ia a aingle ao no bracea requireal.
if
Nk'
equala
22
ctg
When you simulatethis application,you should noticethat I didn't put in the bracesfor the lastif previously. statement. As I indicated theyaren'l absolutelynecessary, but they are a goodideawhen you are startingout. There is a mistake in this program that should have becomeevidentwhenyou simulatedit.The final if statement,if (k : 22),alwaysexecutesasif k is equal to 22.This seemsstrangeuntil you canseeexactlywhat is goingon. Remember,the singleequalssign(=) a/waysbehavesasan assignment, and a doubleequals signis requiredfor a comparison.If you changethis
*r..;
40
of
i = 4 4 i j = 0t
int int
| // ti
g-{
lhe
myk€ pr€alko 04.10.18
Te6t- if is ll // \loE zeio !firLli.Dl€ that Ex€cut€ Slatetnenls if E
dlemonslrateE
\if"
l , e 3 P I C @l ' l C UE x o e n i m e n t s f o n t h e E v i l
Genius
singleequalssignto a doubleone,you will find that the programnow works properly. The problemof incorrectlykeyingin one equals signinsteadof two is very commonwith new C programmers. To avoidthe problemyou can reorderyour programso that you neverrequire an equalscompari son.For example,the lastfour linesof the application could be changedto the following: if.
lk
!=
221
n = n + lt
//
Increment
\n/
if
\k'
equalE
22
out how your codeis supposedto work and then do the reverse.
t".i
Another strategyis to alwaysput constantsfirst asin: LE 122 -= k) n - n + 1i €lse tr = n - 1t
// //
Increments
sn'
Declement
if
if Not
\kz
equals
22
,.1
ri; **J
Equals
This is marginallybetter but doesn'tprotectyou in caseslike "if (a : b)," wherethe comparisonsare both variables.In sucha case,forgettingto put in the second equalssigncausesthe valueof onevariableto be assignedthe valueof another.
I don't highlyrecommendthis methodbecauseit involvesnegativelogic.Thatis,you mustfirst figure
i.; ,t! '.,{i :",'
F,-;r
t
Experiment13-Nested ConditionalStatements
I
A logicalsuggestionwould be to placethe secondif statement(alongwith the statementsthat executeconditionallywith it) within a set of bracesafter the first if. Thiswould look like:
11; !'ir)
t*i iat
i f ( i > j )
(
i f ( k < n )
(
Statsement(a)
//
Ex6cut6al
if
"i
> j"
and
\k
Executetl
if
"i
> j"
anil \k
< a/
) Somepeopleare born troublemakers. When I was16,I had to go to a two-hour defensivedriving course becauseI had too many pointsfor speeding.Everyone in this coursewasgivena Driver'sEducationMqnual with the basicrulesof the road.Severalminutesinto the course,somebodyput up his hand and notedthat if a policeofficerwasdirectingtrafficin a mannercontrary to a set of traffic lights,then you must follow the policeman'sdirections,and if a farmer herdinganimals wasdirectingtraffic in a mannercontraryto traffic lights,then you shouldfollow the farrner'sdirections. He then askedthe question:"So,what do you do if there is botlr a police officer and a farmer that are giving contrarydirectionsto the streetlight?"I'm bringing up this little storybecausein the previouse>.periment, I presentedthe idea that the next statementafter the if statement(or the following elsestatement)would be executed.Andwhen I presentedthis conceptto a setof high-schoolstudentqI wasquickly askedthe question, what happensif you havean if statementfollowing anotherif or elsestatement?
Section Tuto
else
{ // ,
s!at6m€nt(a) // fL
>= n/
fx
, // fr Another solutionis to noticethat there are only two areasin the codeabovethat executeconditionalstatements,and they couldbe accommodated by two if statements: > j)
if
((i
//
stat€ment(a)
(
) elae
if
(i
&& (k < n)) ttrecut€al
if
"i
> j"
and
*k
< n,,
Executeal
j.f
"i
> j"
and
\k
>= n/
r."i" *...!.
f*r 1{ it,
> j)
t //
a1
Statse$ent(E)
I // ti
{,'.l
This methodisn't bad,but couldbecomevery long if statementsare wdtten for both the if and the else.And, dependingon how the compilergeneratedthe code, this methodcould be very inefficientin termsof code sizeand executiontime.
1 i
I n t r o d uc t o r y C P n o g r a m m i n g
41
&{
i_ld
s)
s) 6
The generallyacceptedmethodof combiningconditional executionstatementslike this is to recognize that the if statement and the conditionally executing statement(s)following it are all one statementand can be nestedunderneaththe originalif statementasin the following:
k = ot
Execul€al
if
*i
ExecuEeal
if
"i
> j"
enal *k
< n"
{
# ",".d !s{
c.' L;
EJ lri
StalelBent fi| //
(a)
> j"
andL \h
>= nz
l els€
This PlogrEnl wif!. .tunp b€tsw€ea aliffelent alue to itiffelent coatlitiona. The LED values
*.s"*
((4 == k) && (0 == n))
if
{ PORTA = 0b000000100r TRISA = 0b011101011t
Path
//
3
k = - 2 i
) (4 == k)
e13€ if
{
poRTA = 0b000000100t // TRISA = 0b011111001t
PaEb 4
k = - 2 ,
) (
{
LEDE
PORTA = 0b000000100r TRISA = 0b011011011t
j,
PoRTA TRISA |
ll
//
& &
//
0b000010000, 0t011001U1,
//
Path
5
Ei
| // fi k = k + 2r
//
N€xt
Tin6,
co to
\e1a€/
e rihw Enal cNoNest
OnceI had the programworking,I removedthe redundantbracesand looked for placeswherethe multiple if statementscould be combined into something simpler.I cameup with the following cNest.c: *incLuale - Jurltr Betsween IEDg /* cNest.c
Inain ( )
rrilh
ifs
\rif" NeEt lhe various Ithl.6 Program rrill anal get statenenta of ocNoNeBt.c" !o lry ia eaaier to f,ollow. Drogram that
t
42
5
t
rt
PORTA = 0, C!4CONo = 7r // r'rr! .ANSEL = 0r // Turn
Path
else
]
k,
//
)
a!e:
-CONFIG ( INTIO & VIDITDIS & PWRAEN & !,ICLRDIS I'NPROTECT \ & I'NPROTECT & BORDTS & IESODIS FCUDIS) t
i,
(0 == n)
if
LED Anoale Cathoale DO NA{ RA5 Dl RA5 RA4I D2 RA4 RA2 D3 RA2 RA{ D{ A.E5 RA2 D5 RJA2 RAs D5 RJA2 RA1 D7 A:A1 RA2
int
UJ
IJaEb 2
K != 0
//
t
|
-,i
Ilat }l L
) elae
ifa
lErhe D!6alko 04.11.15
d
k)
elae
iiJ
6""*
< L29t j++)l
PORTA = 0b0001000OO, // TRISA = 0b011001111, , // f,i
I shouldpoint out that this methodof nestingdoes not apply only to the if statement.It appliesalsoto all the conditionalexecutionstatementsin the C programminglanguage. As you work throughthe book, you will seemany examplesof nestedprogramming statementsof differenttypes.Actually you'veseenone already,the 500ms delaycodethat wasusedin the cFlash.cprogramconsistsof a for statementnestedas part of anotherfor statement. To demonstratehow nesting can simplify a program,I createdcNoNest.c.This programflashesdifferent LEDS on the PICkit 1 starterkit in a somewhat randomorder,but it is hard to follow and seeimmediately what is happening in the application:
r 1
! !
j
{
*incluale - aluJnlr B€tsw€e! LEDE with /* cNoNesl.c
&5F S.-{
= 0r
PORTA = 0b0000100OOi // TRISA = 0b011101011t
(
.ii"[
Foreve!
(0 == n)
if
slat€nenl(a) elae
w
Loop
valueE
{
) *-{
(j (0 --
if
{
//
//
tests
special
for (t = 0r i < 255t i++) // siry)te Delay rJoop for
a E ( r > t , i f , ( k < a )
//
== 1)
whl.1e(1
t
k & n ale
//
off conl)alators of,f, ,rDc
l , e 3 P I C @l l C l JE x o e r i m e n t s f o n t h e E v i I
6enius
a
The r,ED valuea
ar€!
eLse
LED Anoate Catboale DO RA{ RAs Dl RAs RA1I D2 RA4 RA2 D3 NA2 RA{ D{ NAs RA2 D5 AJA2 RAs D5 RA2 RA1 D? RA1 A:A2
if,
((4
== k)
&& (0 == o.l ) // Cdlbitr€ the ,/ Teat Coaalitions
PORTA = 0b0000001OO, ll TRISA = 0b0U101011,
Patjr 3
r1\
k = - 2 t
) elEe
{
rvk€ Dledlko 0{.11.15
if
F.(
(4 == k)
PORTA= 0b0000001OO, // TRISA = 0b011u1001t
Nr"
PaE}r 4
k = - 2 , , /t fr elae Lf (0 == n)
t
& P!{RTEN & !,ICIJRDIS & _CONFIC ( INTIO & lfIllDIS T'I{PROTECIII \ & IJNPROIECT & BORDIS & IESODIS & FCMDIS ) t
til
X rd
,
;J ;
PORTA= 0b000000100r // TRISA = 0b011011011,
Patsh 5
) elEe
inr nain(
{
j,
i,
k,
PORIA = 0b000010000r TRISA = 0b011001111t
nt
b.E>
5
)
I
{ PORTI = 0t CfiCONo = 7r // 'l''rt AIISEL = 0r // Tura
k = la L 2? //
while(l
k & n ale
-=
1)
//
SD€cial
Test
ve].ues
(1. = 0r (J = 0r
i j
Loop For€ver
< 255, < L29,
i11) jLLlt
//
Sirqlle
Delay
IrooD
(0 == k) (0 == n)
t PORTA TRISA -
Tine,
co
tso *e].se/
{'d
0b000010000r 0tr011101011,
//
Path
1
) elEe
t
PoRTA= 0b00010000O, /l TRrsA = 0b011001111t I ll fr
PaE}r 2
elihlr Enal cN€st
// //
)
t for f,or
N€xt
off CdEaratola off ADC )
k = O, //
g *
fr
ll
I
if if
Path
//
I admit that cNest.cisn't a hugeimprovementto cNoNest.cin tems of readability,but by reducingthe number of unneededbraces,I did manageto reduce the amountof spacethe main loop of the application takesandmadeit easierto look throughthe ent e application.This is an example of what you will seeif your taskis to supportan applicationthat hasbeenin usefor a long time and hasbeenmodifiedto reflect new requirementsand fixesto variousproblemsthat havebeenencountered.In thesetypesof applicationq it is often impossibleto understandexactlyhow the codeis working,and you end up makingsmallchanges that perpetuateits increasingcomplexity.
m ?-' I J ;t
tlt a
(tl f'r'
ExFerimentltl-The 5ulitch DecisionStatement
L
singlevariablemustbe tested.Multiple if and else statementscanbe combinedto meet the reouirements quite simply.Thecodebelowdemonstratesihis: (4 == L') ll
Go south
If
raalex et
'
'J
m
rr
{
&,
t Dir€ction
l
= 180,
' ela€
if
15 == L,
//
Go North
ll
co East
if
Intt€x
at
a 5 o ,",{
5
{ Dir€ctioD
Casesexistwheremultiple statementsare required becauseof multiple constantvaluesagainstwhich a
= 0t
) e].e€
if,
(7 == l,
if,
rDtlex
a!
7
t
5ectionTuuo I n t r o d u c t o r y C P n o g r a m m i n g
43
= 90t
Dilection
if
else
//
Go Iqeat
for
€Ise
€verylhinq
// //
t
n!
s
.t-,'
f,f) b.{ j't
I
= 270t
Directlon ll f!
If you were writing your application in BASIC, you statementslike the would probably use the seLect/case switch/casestatemenrsusedin cswitch.c listed below: *incLual€ - Detlonstrat€ /* cswlEch.c fhl,s Drogram alemonstratea awiEch atatdlent.
cE)eratLon
of
tsh€ op€ralion
ttsltilch" of
lbe
rq.ke prealho 0{.10.18
f 5
i n t i = { t int Di!€ction
= -1t
{t I
nain( )
{ switcb
(i)
t caBe 4. // Dir€clion bzaaki // c aBe 5t // Directioa bieaki case 7 . I / Dilection b!€aki default: // Direction ) // hcti\ta
rtr *-r ".{
{i!
!thil€(1
cio South lf = 180t r.eave switch if Go Norlh = 0t Glo Eaat = 90; co west = 2?0t
if
Ind€x
== 4
at
Even
; il
//
Slatem€ut the \Case/ Ncase Slatern€nt
the
Cour1tet
caae
7"gO / /
Goiug
aouth
Inalex
= {
caee
O .
Goirg
Norlb
Itral€t
= 3
Going
EaBt
Itrale*
= 2
Gol.ag Weat
IEdl€x
= 1
7 //
thlng
E1a€
ceee 9Or ll j - j + 1 , b!eaki tt€fault: //
== 1)t //
hcliws
E^d. crf
Obviously,you have to plan for situations where you can eliminate the break statementin your switch code,but whenyou do,you reallyhavea feelingof accomplishment-andthere'sa goodchanceyou've simplified the amount of application code required for the program.Wh€n you are startingout,you will probably use the switch/casestatementsfor situations like this one,where multiple if statementsexist, and all of them are comparing to a constantvalue and executing a break statementat the end of the case.
ai) ii{ ( a
r!1 ld54
}{{
Ls$ 44
!o
(
This application provides the samefunction of respondingto multiple possibleconditionsthat are listedin the multiple if statementsat the start of this experiment.By usingthe switchstatement,the codeis actually a lot simpler.The casestatement'sparameter combinedwith the switchstatement'sparameterforms the if statement:
"ir-' i-i
cas€Pafameler)
Di!€ctLoa // Clear (Dir€ctioD)
j = J + 1,
fo!
after nd{t
=-
The useof the casestatementis obviouslya lot easier to key and a lot lesslikely to havea syntaxerror like you had with the if statement. The "default:" conditionworks exactlythe sameas the elsestatementin the if statement;the statements after it executeonly if all parametersdon't match any of the casestatements. This is all there is to the switch/casestatements except for one point: the break statemetu.This statement causesexecution to jump out of the current switch statement and executethe statement following it. You can do someinterestingthingsif the break statement inside a switch block is not included. For example,if the switch block was being usedto record the direction of motion (keeping in the tradition of the wheel direction), it could increment the counter for each90 degreesrather than placing a hard value in the countervariable.The examplecodefor this implementation is: I = 0t awitch
stat€$eat Iaal€x aE 5
halex
Slaternentss sb!€ak" or \ // fL
] |
(SwitchPalameter
t
)
al
l , e 3 P I C @I ' l C UE x o e r i m e n t s f o n t h e E v i I
6enius
ir* i
E x per im entl5-fo n d i ti o n a l L o o p i n g
ili ,,?{
#ineLutle /* cFlaah !'lhile.c I.ED on a PIC16E584
ginE)le
to
Elash
an a-ii
|!hi€ Program is a noalif,ietl to uae ..whil€,' Loops iDsleaal of \fo!', loops RA4 - r,ED poailive ItA5 - IJED Negative
ti:: c Program
version
of
\tcFlash.c,,
:,- "
Connecti,on
i:
I'ke pretlko 0{.05.19
There are a coupleof rnethodsof implementingconditional loops.In this experimentI will look at the most common method: the bastcwhile loop. The while loop allowsyou to repeatedlyexecutea set of instructions while a test expressionis true.That is,the while loop canbe usedfor conditionallyrepeatingcode.But it can alsobe usedto implementinfinite loopsin your applications.Someprogrammingphilosophiesdo not use the basicwhile loop,but they alsodo not provideyou with the simplereadabilityof the basicwhile loop. The while loop is a programmingconstructthat testsan expressionbeforeallowingexecutionto take placewithin the loop.If the expressionis not zero,then executionwill take placewithin the while loop,and at the end of the loop,executionwill return to the expressiontest and the processwill repeat.If the expression evaluatesto zero,then executionwill skip pastthe loop andcontinueat the statementafter it. To showhow this works,the following statements canbe used:
while
(i
i
F nain( )
{
t\
PORTA = 0t CMCONo = 7t ANSEI = 0t TRISA4 = 0t TRISAs = 0t
ll // //
\E oft Corparatora Tuln of,f ADC !,take RA4./RAs OutDutg
//
Loop
l'i
it-,,'
while(1
== 1)
Foiever
!-:.
t i = 0, j = 0, whil€ ( (i
{ 1
(
a; < 2s5) ll
= t + 1t (i > 2s5)
//
(j
< 78))
Incronent
//
Ro11 Ov€!
//
ToggLe
ar!
S!fiaLL Counte! to
Larg€
i-J
Counler
J = j + 1, // fi ) // elihw
< {)
= i + 1; // elih!,r
& &
,
{ )
-CONFTG ( INTIO & WDTDIS & PWRTEN & MCLRDIS IJNPROTECT \ & T'NPRoIECT & BORDIS & IESODIS ECMDIS ) t
//
WhiL€
lJoop Coale
In thesestatements, the variablei is initializedto zero.Next,it is comparedto 4, and if it is lessthan 4 (i.e.,the expressionis true or returnsa nonzerovalue), the codeinsidethe while loop (incrementingthe variablei) is executed.Wheni is no longerlessthan 4, the while expressionbecomesfalse(and returnsa zero value),the codeinsidethe while loop is skippedover, and executioncontinuesat the statementafter the closingbraceof the while loop. To demonstratethe operationof the while statement in an application,I havemodifiedcFlash.cinto cFlashWhile.cin which the two for statement delays havebeenreplacedwith a singlewhile loop that incrementsthe two variablesi andj until they are both greaterthan 255and78,respectively:
5ection Tulo
R:A{ = RA4 ^ 1, | // eLihw , // wrd. cFlaah
LED
;-i
while
Although cFlashWhile.cis a direct copy of cFlash.c, I found if I usedthe sametestvaluesfor i andj (255 and 129,respectively), the delaywould increaseto 833 msecsrather than the standardvalueof 500ms By runningcFlashWhile.cin the MPLAB IDE simulator, I wasableto empiricallydeterminethe valuefor j that would resultin an approximately500ms delay. As you work throughthe code,you will discover that I usethe while statement while
(1 == 1)
a /ot.This is my loop-forevercode,and I useit either as the overallloop in an application(like this one) to
I n t n o d uc t o n y C P r o g r a m m i n g
45
l-,
the I/O and processingcode,or I placeit at encompass the end of the applicationto stopit from returningto the caller(and end up executingagainrepeatedly).The statementcouldbe simplifiedto: while
(1)
The PICC Lite compilercan detectstatementslike this wherethe test expressionis alwaystrue (or 1) and replacethe statementwith somethinglike:
| / / goto
insiale
Code Ex€cuteal IJooPt
vthile
loop
There is anotherform of the while loop.It is the do/while,which takesthe followingformat: alo t // Coale Ex€cutetl inside
) while
(orDreasion)
the alo/whil"e loop
t
This is a subtlemodificationof the original,whereduring the first time throughthe loop,the expressionis lo execute not lesledto be true;you areguaranteed the codeinsidethe loop at leastonce.The advantageof usingthis form of the while loop is that variablesor hardwareregistervaluesthat are testedin the while exoressiondo not haveto be initializedto force execution to work throughthe codeat leastonce.SomeC I implementationsh avethe do/untilstatement,whrch do not like becauseit forcesnegativelogic into your program(i.e.,loopinguntil a conditionis true is the logicalnegativeof loopingwhile a conditionis true). Two keywordsare alsousedin while loops:break and continue."Break" will force an exit of the while loop,and"continue"will force executionto retum to the while statementwherethe expressionis evaluated. I do not usethesestatementsbecausethey Personally, act asgotosin the program,changingexecutionwithstalements. out regardlo theslructuredProgramming And I do not recommendthat you usethem in your programs,asthey canbe difficult to debugand can leadan applicationto behaveunpredictably(especially if you are new to programming).
l5-The ForStatement Experiment PXekit*
L
The designof the for statementis actuallyquite ele"what are the gant andresultsfrom the question, requirementsof repeatingloops?"The statementformat ls: (Initializationi for Incr€nent ) Statemeat
I try to teachprogrammingasI wastaught,and that is to emphasizethe capabilitiesof the differentfunctions built into the languageand how to usethem approprF Somepeople,however,seemto atelyin applications. think they canusethe for statementin virtually any situationwhereconditionallyloopingcodeis required.I guessthe theorybehindusingthe for statementin different situationsis to reducethe numberof statement typesthat are in your programrninginventory.In this experimentand at the end to this section,I will show that the for statementis a wonderfullyflexiblestatement,but that it canmake codea lot more complexto understandand debus.
46
l.oop
'lesu
E {pressioni
Loop
and its operationis similarto the BASIC codefor a loop.Initializationis the processof initializingvariablesthat are (ideally)requiredfor the loopingoperation, but the processcan alsoincludeother assignment is an exPression. /oop testexpression statements.The similarto that usedin the while statementto test whetheror not the loop shouldrepeat.Finally,the /oop incrementstatemenlis normallyusedto incrementthe loop counterafter eachiterationof the loop. The for statemenlis typicallyusedwhenyou needa loop that repeatsa set numberof times.It might look like the following: (i = Or i < ua*Nlrrib€tt i++) for Executseal Repeatedllv // gtatenent slatementi nfor,, IJoop
l,e3 PICo llCUExperiments fon the Evil
Genius
by
and could be modeled as:
$rhi1e
(i
nvke prealko 04.11. 09
< Maxl{llmber)
{ Statementr i )
Executeal Repeateally Statenent \tfor,, Loop Equivalent to Ni++"
//
= i + 1r // elihw
//
by
CONFIG(INTIO & WDTDIS & PWRTEN & DTCIJRDIS& UNPROTECT \ & UIIPROEECT & BORDIS & IESODIS & ECMDIS) t
j..
int
In this for statement,a counteris initializedto zero and is incremented(usingthe "i+ +" statement,which is equivalentto i = i + 1) until it is equalto MaxNumber.This shouldbe quite easyto understandand usein your own applications. The useof the for statementbecomesmore complex whenyou considerthat multiple initializationand loop incrementassignment statementscanbe used (with eachseparatestatementseparatedby a comma). lf commasare not usedto separatethe assignment statements, the compilerwill becomeconfusedasto how to parse(convert)the statementscorrectly.The following for statementis completelyvalid: (i = 0, for Statetnentr
j //
= 47i i < MaJdilumberi i++, j = j Executefl Repeatedly Statement \forz Loop
lhrough
PICkit
This Program r,ri11 ro11 throuEh each PcB. rrEDs built inlo the Prckit The LED values
the
only
$for/'
PORTA = 0t ClilCONo = 7, ANSEL = 0r
// //
Tlvr'r off r'urn off
Conparators ADC
k = 0t
//
S!a!t
LED 0
for(rr)
//
r.oop Forewer
(i = 0r i < 255r i++) // for for (j = 0r j < !29t j++lt
- 2) by
I
k) && (0 == n)r (1 == k)u
n++)
for (rI = 0, (2 == { // Sinulate {if PORTA = 0b010000t TRrSA = 0b101011t | // tof for (n = 0, (3 == 'if { // sinulate PoRTA = 0b000100, TRISA = 0b101011, , // t.of f,o! (n = 0r (4 == { // simulate 'ig PORTA = 0b100000t TRISA = 0b011011t | // rof for (n = 0, (5 == trif { // simulate PORTA = 0b000100i TRISA = 0b011011t
k) && (0 == n)t (2 == k)/
n++)
k) && (0 == n)r (3 == k)/
n++)
k) && (0 == n)r 14 == k)"
n++)
k) a& (0 == n)r (s == k)/
n++)
+ 1)
% 8r
slatements.
5ection Truo
but
,
Delay
k) && (0:= (0 =- k)"
k = (k
to be 'cFor", explosive.
simple
f,or (n = 0r (0 == { // sirnuLate \if PORTA = 0b010000i TRISA = 0b00L111t j // '.of for (n = 0r (1 == t // simulate \if PORTA = 0b100000; TRISA = 0b001111t
for (n = 0r (6 == k) \if (6 { // sinulate PORTA = 0b000100, TRISA = 0b111001t j l/ rof for (n = 0r (7 == k) Nif (7 { // Simulate PORTA = 0b000010 t TRISA = 0b111001t J // rof
are:
The original nam€ was going that se€neal too potentially
at
{
r,ED Anoale Cathoale DO AA4 R.A5 D1 RA5 RA4 D2 RA4 NA2 D3 ai[2 RA4 D4 RA5 R]A2 D5 RA2 AA5 D6 RA2 RA1 D7 RA1 RA2 Using
nt
t
8 LEDE using
of
k,
nain( )
In this for statement,both i andj are initialized,and both variablesare changedin the loop incrementportion ol the for statement. To demonstratehow versatilethe for statementis,I havecreatedan applicationthat cycleseachof the PICkit 1 starterkit's eightLEDS.(It will be explained in more detail later in the book.) Ratherthan explaining how the for statementswork in the application,you shouldwork throughthem on your own (it's really not very hard-especiallywith the providedcomments). *include /* cPKr,ED 2.c - Ro1l oII].y \for?'
j.
//
// //
rr), n++)
&& (0 == n)t == k)/
n++)
&& (0 == n), == k)/
n++)
rncrement of o-7
IJoop
k within
Erl..l CPKI,ED 2
Introductory C Programming
range
For Eonsideration At the start of this section,I noted that C is notorious for its ability to allow programmersto createvery eff! programstatecient but very difficult-to-understand ments.In the lastexperiment,I showedhow the for statementis very versatileand how it canbe usedto replaceall the traditionallyusedconditionalexecution motivationfor writing complexstatestatements.The mentsis usuallyto minimizethe amountof keying requiredfor an application,althoughsometimesit can seemlike the author of the codeis simplytrying to demonstratehis or her mentalsuperiority. For example,in looking at an exampleapplication, you might run acrossa statementlike the following: * ?. Match = 0r (Malch = (i = (j = start) for (PORTC != (PoRTA ^= sequencelj++l))) && (i++ < 25)i r, // Sequence Match confirnation?
At fint glance,it is probablyimpossibleto understandwhat this statementis intendedto accomplish, and,to makemattersworse,the commentis no help at all asit doesnot seemto relateto anythingin the statement.You may feel like givingup and looking for anotherexample,but you can do this;you candecode statementslike this surprisinglyeasily. When I presentedthe for statement,I noted that it wasin the lollowing format: for
( Initial
izationr
lJoop TeEt
E:.pressioni
Lootr)
sta!emen!
stateand eachpart (whichconsistsof a C assignment ment or expression)of the for statementcanbe broken out into piecesand rewritteninto piecesthat make more sense.For example,the initializationassignment statementof the for statementis: i = ( i = s t a r t ) * 7 i
and takesadvantageof the ability of C to savean Becausej intermediatevaluein a complexexpression. is equalto Stafi and it is a factor in the initializationof the two following lines i, the authorhascompressed into one:
.
i = S t a l t * 7 t j = startt
Similarly,the comparisonexpressionof the for statementcanbe broken out andunderstoodby recogn2ingthat comparisonvaluesare arithmeticvalues (zerofor false,and not zero for true).To take
48
advantageof this point,lhe Matchv^riable (the first part of the comparison)is loadedwith the resultof the comparisonof PORIA (whichhasbeenXORed with a valuefrom the Szquencearray) to PORTC.When an arithmeticor binary operatoris placedbeforethe statement,the line is equalssignin an assignment translatedasthe destinationvalueoperatedon by the other parameter.I might write out the comparisonpart of the for statementasfollows: PORTA = PORTA ^ Sequencetilr
//
Same aB 'PoRTA
j = j + 1r // rnclemen! *r., "." ilT#"
" "
r{atch = 0t (PoREc == PoRTA) if Match = 1t
Both partsof the comparisonusethe unaryincrement (++) operatorto incrementthe variablesi andj d/€r the expressionhasfinishedexecuting.When the unaryincrementor decrementoperatoris put to the lelt of the variable,asin the following example ++J i
the variableis incrementedbeforethe statementexecutes.Similarly,if the unaryoperatoris on the right sideof the variable,the variableis incrementedafter the statementhasexecuted.I recommendthe useof the incrementand decrementunary operatorsin your coding,asthey are a lot easierto key than the completestatement j
= j
+ 1t
and they are generallyacceptedasthe shorthandversion of thesestatements, A null statementis usedfor the incrementpa of this statement.This is a bit unusual,but the unary proexpression incremenloperatorsin lhe comparison vide this function. Justasthe null statementis usedasthe for statement'sincrementstatement,a null statementis usedas the loopingstatementor statementsthat follow the for statement.If you look at how I havebroken out the you will seethat there is an comparisonexpression, assignment statementto PORIA, which could be movedto the loopingstatementareaof the for statement. If I wereto write equivalentcodeto the for stateit would look ment givenat the stafi of this discussion, like this: something i = S t a r t * 7 t j = start, tilatch = 0, ((0 == uatch) $hile
l , a 3 P I C o I I C t JE x o e n i m e n t s f o r
&& (i
the Evi]
< 25))
Genius
t
PORTA = PORTA ^ Sequenceli] t (PORTC == POREA) if Malch = 1r // s€quedce Malch Coafifinalion? j = j + 1, i = i + 1t ) // €1ihrt i = i + 1t j = J + 1,
You should be able to relate this code to the original,and I'm surethe commentmakesmore sensenow. What might not make senseis the incrementing of i andj after the while loop;thesestatementswereput in to make surethe valuesat the end of the equivalent matchthe valuesat the end of the orisinal for statement. In terms of readability and decodability,I am sure the seriesof statementsI havecomeuDwith are vastlv
superiorto the singlefor statement.In termsof efficiency,the number of instructions created for either solutionis not substantiallydifferenqnor is the execution speedof the two solutionsdramaticallydifferent. The major difference between the two statementsis the amountof keyingrequiredfor them;the sequence of statementsrequiresmany timesthe numberof the keystrokesof the short for statement. It should be no surprise that I recommendthat whenyou program,you avoidheavilycompressing statementsunlessa strongreasonexiststo do so. Although you may savea substantiallygreaternumber of keystrokegyou shouldaskyourselfhow much time you might later losedebuggingor decodingone compressedcomplexstatement.
h{ L C
n
9--, TU
TJ 4
Section Tr.uo I n t r o d u c t o r y C P n o g r a m m i n g
49
Section
Three
S i m p l eP I C @ M C UH p p l i c a t i o n g
Prc16F684 14-pin ZlF socket (3MlTextool 2L4-333900-0602J reconmended) 0. 01 p,F capacito! length of 283-foot 30-gauqe sol j.d core
Before goingon,I would like to walk througha modificationto your PICkitrM1 starterkit. This minimizes the chancefor damagingeither the PIC microcontroller you are programmingto put into anothercircuit or the PICkit 1 starterkit you are usingto programthe PIC MCU Although the PICkit 1 starter kit is an excellenttool, the machinedreceptaclesocket that is built into the PCB is not designedfor many repeatedplug/unplugcycles.Looking at manufacturer'sdatasheets, military-gradedual inJine chip package(DIP) socketsare qualifiedfor 48 cycles. The specifiednumberof plug/unplugryclesfor industrialgradesocketsis 50 times(althoughthey are not tested to seeif they meet this specification). As you work throughthis book and your own experiments, you will easilyexceedthe maximumnumberof plug/unplug cyclesfor a military-gradesocket,and chancesare at leastone or more pin receptacles in the socketwill wearout and stop makingreliablecontact.Youwill find alsothat pluggingand unpluggingpartsin the machinedreceptacleis difficult and that it's easyto bendthe pins,havethem fall ofl or get stuckin the PICkit 1 starterkit's sockets.You canavoid these problemsby adding a zero insertionforce (ZIF) socketto the PICkit 1 starterkit. Followthe stepsoutlinedhere.To add the ZIF socketyou will needthe following: 1 PICkit 1 starterkir with snap-offPCB still attached 1 14-pinZIF socket(3M/fbxtool 214-3339-000602Jrecommended)
51
or
1 0.01pF capacitor 1 3-foot length 28- or 30-gaugesolid core wire Weldbondglue Solder The toolsyou requireare asfollows: Solderingiron DMM with audiblecontinuity tester Needle-nosepliers Clippers Wire strippers A ZIF socketis similarto the machinedreceptacle socketalreadyon the PICkit 1 starterkit. The differenceis that the pin receptacles can be openedor closedby movingthe lever on the socket.The open positionis shownin Figure3-1,and the pin receptaclesare closedwhen the leveris pusheddown.This socketwill be addedto the open 14-pinDIP socket areaon the prototypingsnap-offPCB on the right sideof the PICkit 1 starterkit (seeFigure3-2),and eachpin will be wired to the correspondingpin of the machinedreceptaclesocketalreadyon the PICkit 1 starterkit. Expectthat this taskwill take an hour.
Figure 31 14-pin3M/TextoolZIF socket
Fiqure 3-a 14-pinZIF socketaddedto the prototypingareaof the PlCkit I storterkit
The stepsfor addingthe ZIF socketare asfollows: Solderin the ZIF socketwith its lever up (i.e., pin receptaclesopen).This will ensureproper operation.If you solderthe ZIF socketin with the lever down,you will find that the receptacleswill not open properly.You may find that you haveto prop up the PCB with ZIF socket to make surethe lever staysup during soldering. If, after soldering,you find that somepins stick or don't open easily,move the ZIF socket'slever up and remelt the pin's solderto seeif that relievesthe stress. 2. Using point-to-point wiring,add the 14 connections betweenthe machinedreceptaclesocket and the ZIF socket(seeFigure 3-3).Pin 1 of the PCB socketshouldgo to Pin 1 ol the ZIF
1.
52
Figure 3-3 Point-to-pointwiring usedto connect ZIF pins to PICldt I starterkit programmingsocket ptns
socket,pin 2 of the PCB socketshouldgo to pin 2 of the ZIF socket,andso on.When I have donethis,I try to keepmy strippedpin lengths to r/:z inch (1 mm).There are two rows of holes besidethe 14-pinsocketholesin the prototyping snap-offPCB;to theseholesyou canattach one side of the wires rather than soldering them to the pins of the ZIF socket.When you are addingthe wires,it is a good idea to leave the ZIF lever up to make sure that, rt the ZIF socketpinsremelt,therewon't be problems later with any of the receptacles. 3 . l e s t y o u rw i r i n gu s i n gt h em u l t i m e t ecro n l i n u ity testerfunction.Each pin of the machined receptaclesocketshouldbe testedagainstthe correspondingpin on the ZIF socket,aswell as againstits adjacentpins to make sure no shorting exists. 4. W h e ny o ua r ec o m f o r l a b lteh a ty o u ru i r i n gi ' correct,solderthe 0.01p,Fin the two holes abovethe 14holesusedby the ZIF socket.I solderedthe 0.01 pF capacitoron the backside of the PCB becausethe ZIF socketcoveredthe holeson the topside.When solderingin the capacitor,make sure the leadsare asshort as possible,that it lies againstthe PCB,and that it doesnot extendbeyondthe rubber feet on the b o t t o mo I l h e P ] C k i t I s l a r l e rk i t . 5 . T h e f i n a ls t e pi s t o g J u ed o l rn t h ew i r i n gu s i n g the Weldbondglue.If you put on a reasonably thin bead,the glue shouldset to a hard,clear consistencyin 6 to 12 hours.To make sure the wires don't extendbeyond the rubber feet on the bottom of the PICkit 1 starter kit, you may
l , e 3 P I C o l ' l C UE x p e r i m e n t s f o r
the Evil
Genius
want to hold down the wires with a weight or tie them down while the glue hardens.I use Weldbondbecauseit can be Dulledoff later without damagingthe PCB.
1 starterkit that will standan indefinitenumberof plug/unplugcycles. And, it is still connectedto the other functionsof the PICkit 1 starterkit, which allows you to experimentwith the LEDS,buttons,and potentiometerintedacesbuilt into the PICkit 1 starterkit.
Onceyou'vecompletedthe six stepsand the glue hashardened,you havea ZlF-socket-equipped PICkit
h* * ;ii:
" ; l;t fi ''5
ExFeriment17-Basi c Delags
inh i'rt.
iEnd = 235r jRnA. = 23st
// //
.-- 1
OutBifle l,oop value Inaiale Loop value
I!
nain( )
{
The cFlash.cprogrampresentedin the introductionto this book includeda simpletwo "for" statementdelay. For the application,I wanteda delayof a half-second (500ms) so the LED would flashon and off with a period of one second.Findingthe end valuesof the for statementswasdoneempirically;I usedthe simulator, asI will showin this programto time the delayand then adjustedthe valuesuntil the delaywasapproximately500ms.In this experiment,I wantedto go back to the cFlash.capplicationand seeif therewassome way in which I couldquantifythe delayso I coulduse it in other applications. To test the application,I modifiedcFlash.cslightly asyou canseein the sourcecodebelow: *incluale - Try /* cDlay.c
to
fluantify
Delay
VaLues
Ihia Program iB a rnodificalion of \cFlash.c,. u36al to qua.Dtify the value of th€ enat of the tlelay valiabl€a anal the time dl€1ay on the FlaBhitrg D0 I,ED. ThiB Drog!€m is !o be usetl with botb th€ prc16P684 ainulator andt the prckit x pcB with iEEtalLefl. RiA4 - I.ED Poaitive aA5 - I,ED Negative
Connecliolr Connectsion
0{ .05. 19
( INTIO & WD4IDIS & PICRTEN & UCITRDIS & _coNFIe I'NPROIIECT \ & I'NPROTECT & BORDIS & IESODIS & FCMDIS) t
anit
PORTA = 0t C M C O N o= 7 r ANSEIJ = 0r TRISA4 = 0; TRISA5 = 0t whiL€(1
(
// // //
tura off Comparalora turn off ADC Make IIA4/RA5 Outputss Jj!
== 1)
//
loop
Foreve!
//
BreakpoinE
,l 1
$oPo, i j
NOP()t aa4 = aA{ ^ 1r // €lihw ) // Entl cDLay
< iEnal; < jEndr
Eele
i++) // j++) t
//
Breakpoint
//
Toggle
Delay
roop
Eere
LED
il;
]
|-r:*
The first changeto cFlash.cfor this experimentwas to add two variables,iEnd andjEnd, that I could changeeasilyto testthe operationof the application. The secondchangewasto placetwo statementsyou haveneverseenbefore(NOP0) beforeand after the delaycode.The reasonfor the first changeshould be apparent:Thevariablesallow the loop valuesto be changedeasily without affecting the program statements. The secondmodificationaddstwo instructions that don't do anything,and I could usethem for breakpointswithout affectingthe operationof the applicationor breakingan instructionthat is usedmultiple timesin the application. The pointsmaderegardingthe NOPO;statements are probablyconfusingandmight not make a lot of senseat this time.First,the NOPO;statementsare replacedwith "nop" or no-operationassemblylanguageinstructions, which I will discussin more detail later in the book.And statedpreviously,the PICC LiterMcompilerNOPO;statementcanbe usedasa
5ectionThree S i m p I e P I C @l l C U A p p l i c a t i o n s
53
{*
breakpointwithout affectingthe operationof the C program.Second,you will find that the PICC Lite compilerhasa very efficientbuilt-in optimizer,which looks for opportunitiesto ffeate executablecodethat optirnizerwill is assmalland efficientaspossible.This try to reusecodethat performsthe samefunctionin diflerent partsof the program.Whatthe optimizer the considersto be the samefunctionis not necessarily samething you or I would considerthe samefunction. Therefore,you will find situationswhereexecution will jump aroundto differentlocationsin the applicaBy addingthe NOP0: tionswithoutapparentreason. you are putting an instructionexplicitly statements, beforethe start and after the end of the two delaytbr statements. To measurethe time of the delay,I enabledthe MPLAB@IDE simulatorandthen addedthe Stopwatchfunction (seeFigure3-4)to the project.The Stopwatchfunciion will count the numberof instructionsthat executeafter the start of the applicationor after beingreset. To measurethe delayfor differentvaluesof iEnd andjEnd,I put a breakpointat eachof the two NOP0; I did this by movingthe cursorto the line statements. wherethe NOP0;statementwasfound,right-clicking, and selecting"Set Breakpoint."I then resetand ran the program,and whenit stoppedat the first NOPO; statement,I clickedon the stopwatch'szerobutton to resetthe stopwatch,then clickedon the run button again,andwaitedfor the next breakpointto stopexecution. I wasexpectingthat the iEnd andjEnd valuescould be reversed.Thisis to saythat the delayof iEnd equal to 50 andjEnd equalto 100would be the sameasiEnd equalto 100andjEnd equalto 50.Thisturned out not to be the case;the delayvariedby severalpercent whenthe iEnd and jEnd valueswerereversed.Totry
Stopwdtch
and comeup with a simple,repeatableformula that couldbe usedfor the application,I tried makingboth valuesthe sameandcameup with the followingrough formula: Delay(seconds)
= 1.8(10-5) x iEnd
This formula is reasonablyaccuratefor the rangeof 50 ms to 2 seconds. Thinking aboutthe optimizerand thinking about the code,I realizedthat the optimizerdidn't do an obviousoptimizationand that is why I replacedthe two for statementswith the following statements: i j
= iEndtt = jEndt
Without anythinghappeningin the insidefor loop, the two loopsare not doing anythingother than exiting with i andj beingchanged.In this case,the for loop codeis still includedin the application,but you will find caseswherethe ultimateoptimizationthat I listed previouslywill be producedby the compilerand its optimizer. Delaysare criticaloperationsin microcontroller(or any real-time)programming,and I will be showingyou a numberof methodsto implementdelaysin your Although you might want to get your applications. delaysexact(in termsof time or instructioncycles), rememberthat this is often closeto impossibleand usuallynot required.As I discussdifferent applications,I will point out whetheror not the delay's absoluteaccuracyis criticalor if an approximation (usuallywithin 10percent)is acceptablefor the aDplication.
Totalsimddted
cycresf---1iDE67l-**iffii66' r -lI!.'| Inskuction l-
I
@l
q...l I a.n.nEr I r nA-n. rimeftsecsl l-----'iro-i6571-m Tiho
Requency IMHz) Processor
fllooo6''
It ClearSinulstionTirne0n Eeset
Fiqure 3-q
54
MPLAB IDE Stopwatchfunction
l , e l P I C @l ' l C l JE x p e r i m e n t s f o r
the EviI
Genius
t l t
ExperimentlB-Sequencing PlCkit1 StarterKit LEDs Table3-1 Plckit1StarterKit LEDUisplasTBISHand PoFTF Values
As you havegainedinsightinto PICC Lite compiler PIC microcontroller programming and the PICkit 1 starterkit, you haveprobablystartedaskingyourself how did I know to turn on the LED marked"D0" to make the PIC16F684's RA4 and RA5 pins outputs, and then output a 1 (or high voltage)and a 0, respectively. The processthat I went through is quite simple and only requiredlooking at the schematics for the PICkit 1 starterkit. It did not requireany probingor trial and error. When you look at the LED circuitryin the PICkit 1 starter kit's schematic(fowdin the PICkit I Flash StarterKit UserbGuide),yor seethat eachof the eight LEDs is wired aspart of a pair,like I showin Figure35.To turn on one LED, currentmustflow in one direction. and to turn on the other-currentmustflow in the oppositedirection.When I startedthis experiment,I hadhopedthat I couldmake activemore thanjust the two I/O pins connectedto the LED output.But whenI followedthe variousconnections, I discoveredthat if more than two I/O pins were activeat any time,there wasa good chancethat a secondLED would be inadvertentlylit. With this knowledge,Icameup with Table3-1, which lists the TRISA and PORIA register values neededto turn on eachLED on the PICkit 1 starter
LED
TBI5B
POETE
DO
B' 11001111.
B ' 0 0 0 1 0 0 00 ,
D1
B'11001111'
B'00100000,
D2
B'11101011'
B ' 0 0 0 1 0 0 00 '
B'1110L01"L'
B'00000L00'
D7
*s4
B' 11011011'
B'00100000,
B'11011011'
B'00000100,
B'11111001'
B'00000100'
B'111110 01'
B ' 0 0 0 00 0 1 0 '
t!t
! i
, ii
kit. To test this knowledge,Icameup with the following program, which turns on eachLED in sequence. The program usesthe samedelay that we usedfor the originalcFlash(flashingD0 LED) programto show clearlyif eachLED lit and if they lit in the correct order.Note that in the program,the informationfrom Table3-1 is part of the documentation. #idcLutl€ - RoIL /* cPKtED.c
Through
Prckit
8 LEDg
This Prograll will ro11 through each LEDg t'uilc inlo PCBChe PICkit The LED valuea
of, the
! ; I
e"f
are:
:- -
LED Anoal€ Cathotle DO RA4 RA5 D1 RA5 R]44 D2 RA4 RA2 D3 RA2 RAd D4 RiAs RA2 D5 RJA2 RA5 D5 RA2 RA1 D7 RJA1 RJA2
**'ti f 1 1r.
nyke 9retlko 04.09.10
! :
COIII'IG(ITVIIO & VIDITDIS & PICRTEN & UCIJR.DIS & I'NPROTIICT \ & IJNPROTECT & BORDIS & IESODIS & FCUDIS) t
PIC MCU l/O Pin
int
i,
j,
fe
k;
nain( )
(
P I CM C U l/O Pin Fisure3-5
*{ . !
LED wiring
PORTA = 0t CUCONo = ?r // t\rn ANSEIT = 0t // Tuln
off cdnlraratsors off A.DC
k = Ot //
IED 0
Start
a!
5ectionThree S i m p l e P I C @l l C l JA p p l i c a t i o n s
55
while(1
=-
1)
//
loop
Eolev€r
{
{J
r-(
P.{ v
Ft
o g
s, r.L{
z
f , o r ( i = 0 r i < 255r t++) // f o r ( j = 0 r j < L29i i++),
Si{E)le
(k) | / / seLect switch caBe 0: PORIA = 0b010000t TRISA = 0b001111t bleakt caa€ 1: PORTA = 0b100000t ERISA = 0b001111t breakt cese 2: PoRTA = 0b010000, TRISA = 0b101011, breaki cas€ 33 PORTI - 0b000100t TRISA = 0b101011t breakt gAB€ 4: PORIA = 0b100000t fRIsA = 0b011011t br€akt caEe 5l PORTA = 0b000100t rRISA = 0b011011t b!€akt caae 5: PORTA = 0b000100t TRISA = 0b111001, bleekt
r,ED tso Display
$..
k = (k
+ 1)
% 8i
6 'r.l
Loop
PoRTA - 0b000010, TRISA = 0b111001, b!6aki ) // hctiw8
h L.
wblch
Delay
//
) }
//
//
Incr€ment o-7
k wilhin
range
of
elihw End cPIGED
Looking at the program,its functionshouldbe fairly easyto understand. The largeswitchblock of codepassesexecutionto the seriesofTRISA and PORTA register wdtes that are specific to the LED to be written. I could have wdtten to individual bits rather than the entirepod, but I felt that the entfue port write waseasierto follow and understand. I would considerthis applicationto be quite large, clumsy,and not particularly well written. The use of four register writes per LED took a long time to key in (evenwith cuttingandpasting),and there wasa very goodchanceof makinga data entry mistake,or typo. As you work through the experimentsin this book, (particularlythe onesin Section4), think abouthow you could improve the way a piogram is written. For example,in this preyious example I believe I could reduce the total number of lines to lessthan a quarter and eliminatethe repeateddata valuesusedto tum on and then turn off eachLED. This program could be consideredan initial version of a Cylon Eye from BattlestarGalactica,which is also called a "Knight Rider Eye" from the TV show.After trying out the program presentedin this experiment, you might want to seeif you canmake the LEDs reversedirection after reachingone extreme.To do this you will requirean additionalvariable,this one storingthe directionof the LEDs and changingits valueeachtime the on LED is either D0 or D7. Along with the direction variable,you will have to make sure that theTRISA and PORTA bits are returnedto their originalstate(i.e.,loadedwith zerosfor output and in input mode) before tuming on the next LED in the seouence.
m II
Experiment l9-Binarg NumberOutputUsingPlEkitI StarterKit LEDE
t* ()
s
.l-l t . H
s
P{
X
In the previousexperiment,I demonshatedhow each LED on the PICkit 1 starter kit could be turned on in seouence. I notedthat onlv one LED couldbe turned
l;'rl 55
on at any time,meaningthat the PICkit 1 starterkit cannotsimultaneouslydisplaymore than one bit of data at a time. In this experiment, I will show how you can display an incrementing eight-bit counter on the eightbits of the PICkit 1 starterkit. The methodusedto displaydata on all eight bits simultaneouslyis the samemethodthat I will demonstratefor multidigit LEDS and dot arrayLEDs.To give the appearancethat all the LEDs are active at the sametime, we will rotate through eachLED in sequenceand, if the bit the LED is representingis set, then the LED is turned on for a set period of time. If the bit is not set.then the LED is left off for the same
l , e 3 P I C @l ' l C l JE x o e r i m e n t s f o r
the Evil
Genius
PORTA = O' elae // DiEplay the PORTA = 0b100000t TRISA = 0b001111,
amountof time.Thisensuresthat the brightnessof eachLED will be constantregardlessof the number turned on, and that constant timing for the application is provided.Thismethodis alsothe basisfor controlling multiple rnotorsand servos(asin a robot) and shouldnot be consideredapplicableonly to the devicesshownin this book. The rule o[ thumblhat I usewhensequencing LEDs is that eachone shouldbe turned on 50 times per second.For this application,IwantedeachLED to be on 100timesa second,which meansthat eachLED is turned on over a 0.01second(10 ms) period.For eachLED to be activein the 10 ms time period,it shouldbe turned on for 1.25ms (10 ms dividedby eight).Tocreatethis delay,I useda singlefor loop with the delayvaluefound empirically. The programI cameup with incrementsa counter onceeveryhalf a second,and the currentcounter valueis displayedon the eightLEDS of the PICkit 1 starterkit: *inclual€ - use /* cLEDDlEp.c counter Using IED at
\ePKLED.C,, 100x Der
LE'D Time
on Delay
f'J,
f,or (i = 0r i < Df,ayr i++)t ( (value & (1 << d)) == 0) if PORTA = 0t elae // Diaplay th6 va1u6 PORTA = 0b100000, TRISA = 0b011011t
\.L; i I
(i = 0, i < Dlayr i++)t for if, ( (value & (1 << 5)) == 0) PORTA = 0t elae // Diaplay the value PORTA = 0b000100, TRISA = 0b011011t
$=3" 6"{
(i = 0, i < D1ay, i++)t for ( (vaLu€ 5. (1 << 5)) =- 0) if PORTA = 0t €15e // Display the vaLue PORTA = 0b000100, TRISA = 0b111001;
as a base, cycl€ lhrough each secondl (1250 uB b€tlraen IJEDa).
//
tu
fo! (i = 0r i < DLay, i++)t if, ( (value & (1 << 3)) == 0) POREA = 0t else the value // Display PoRTA = 0b000100t TRISA = 0b101011t
nyke p!€tlko 04.09.12
in! i, jt in! Value = 0t ints Dlay = 67,
b!,1
(i = 0r I < Dlayr L++)t for ( (Value & (1 << 2)) == 0) if PORrA = 0t elae the valu€ / / Diar.lay PORTA = 0b010000t TRISA = 0b101011t
D0-D7 a6 an incrementing
& WMDIS & PIIIRTEN & IICIJRDIS -CONFIG ( IIIIIIO I'NPROTECT \ & I'NPROTECT & BORDIS & IESODIS FCMDIS) '
value
r-5 e.€'! *:S
for (i - 0i i < DLayr i++); i.f ( (valu€ & (1 << 7)) == 0) POBIA = 0t else the Va1ue // Display POREA = 0b000010t TRISA = 0b111001,
& &
j = j (i if
VariabLe
+ l, // >= 50)
Incremenl
lhe
Counter
d*.{
B.{
every
1/r g
{
tiS
value = value + 1t // Increments Digplay j = O, // Reaet the counter
main( )
{
frt' tn
Count€r
| // f.r PORTA = O' CMCONo - 7, // Tuln off cd|I)aratols ANSEIJ = 0r // I'urn off ADC J = o, whil€(l
//
R€set == 1)
tlre //
Dis!)lay
counte!
IJoop Eorever
{ NOPOT for (i = 0r i < Dlay,
t++)r
//
siry)Le Delay looD
( (va1ue & (1 << 0)) == 0) PORTA = 0t eLa€ // DispLay the Value PoRTA = 0b010000t TRISA - 0b001111, if
NOP O T (i = 0, fo! ( (valu€ if
i < DLayi i++); & (1 << 1)) == 0,
l }
/ / //
eLiYLw En.I CPKIJED
I chosethe 10 rnsdisplaytime becauseit allowssimple calculationsfor countinga setnumberof loopsfor largerdelays.I take advantageof this for inqementing the Valuevariable,whichis displayedon the LEDs Two pointsshouldbe notedregardingthe codeI usedto determinewhetheror not a specificLED is turned on in this experiment.The first is the useof shifting the bit ANDed with "Value" to seeif the bit in "Value" is set.Rather than putting in the decimal, binary or hexadecimalequivalentof the bit, I choseto shift one up by the bit number.By doing this,we can seeexactlywhat bit is beingANDed with "Value" ratherthan havingto do a mentalcalculation.You may
5ectionThree S i m p l e P I C @l l C U A p p l i c a t i o n s
5t
i?t
feel more comfortable using an equivalent value. Secondly, I choseto OR the value in PORIA with zero if the bit is not setto make surethat eitherpath takesup the sameamount of time. This can be extremely important in timed applications,and although it makesthe codea bit more complex,it ensuresthat your timing is asconsistentaspossible,regardlessof the path taken.
This program will be the basisfor displaying binary data in future experiments.I must point out that it is actually programmed in a very inefficient manner.In Section4, I will provide you with features of the C programming languageand programming techniquesthat will make this application more efficient both in terms of soaceusedand executiontime.
ExFeriment 20-Basic ButtonInFuts on RA3 is low,and then RA5 (DO'scathode)is pulled low.When the logiclevel input on RA3 is high,RA5 is driven high.The program,cButton.c,is quite simple: f!r...
:4 t
#incluale - Stnltl€ C Progra$ /* cButston.c rJED wh€n Buttotr La Prea8€al
x
Thl.6 Program
ia
a moalification
to
Turn
on a!
.cFlash"
of
&-* a:A3 - Button Con!€ctsLon a:A4 - IJED PoaitsLve Conn€cEio! a:A5 - IJED Negative CotrnecEion
g-*.*
f :
r:! :iY1 I
The simplestform of userinput you canput into a PIC MCU application is a button. This is usually accomplishedby a pulled-uppin with a momentaryon button that pulls the pin to ground(seeFigure3-6).The PICkit 1 starterkit hasa very similarswitchcircuit on RA3;it canbe usedfor eithercontrollingthe resetof the PIC MCU (whichwill be presentedlater),or it can be usedas an input with which you can experiment.In this experimentaswell asthe next one I will demonstratehow this switchcanbe usedasan input device.
nyke preflko 04.05.24
-CONFIG(IN:IIO T'NPRCTIECT \ ACMDIS ) t
& WDTDIS & I'IIPROTECT
& PIIIRTEN & BORDIS
& !{CIJRDIS & IESODIS
nain( )
{
The software for this experiment consistsof simply readingthe switchand then determiningwhetheror not the D0 LED on the PICkit 1 starterkit shouldbe turned on.When the button is pressed,the logic level
PORTA = 0n3F, // Atl Bits are Hish CMCONo = 7t // $En off. Cdll)arators ANSEL = 0, // Turn off A.DC TRISA4 = 0r // Uake RA{/RAs Outputa TRISAs = O' whiLe(1
(
P I CM C U
if,
== 1)
tooD
//
(0 == Rll,3)
//
Eorev€r
s€t velu€s ata!e[rent
usiag
*if"
{ RA5
)
.i'{
€lse
{ RA5 = lt
l // fr //
I )
b.t n!
//
elihw Endl cButEon
cButton.cis written asif the authorwasfamiliar with C, but had only recentlystartedworking with the PICC Lite compiler.In traditionalC programming,
Figure 3-5
Pulled-upswitch
58
l , a 3 P I C @I ' l C l JE x o e r i m e n t s f o n t h e E v i l
d\
Genius
whereno bit inputsare used,the button read and LED .
oulpul woulo plooaDly tooK |lKe Inls: if
(0 == (PoRra & (1 << 3rl
{ PORTA = PORTA & (0x0FF
ll
Ia
^ (1 << 5 ) ) r
on -tt--oz RA3 Hi.gh
Lon, Malt6 RAs IJow
//
'
( IIITIO & WDTDIS & PWRTEN -CO![FIG I'NPROTECT \ & I'NPROTECT & BORDIS FCI{DIS) t inr
else
{
PoRTA = PoRTA I (1 << 5) // , ll f.r
Hish,
Make RA5 Hish
*incluile 2.c - SirtrDlifieal C Prograll /* cBuwon an IED wb€n Butlon is PleEs€al Program
ia
a nodlif,ication
i,
:u
& IICIJRDIS & IESODIS
. '
;+
Jt
nain ( )
*1
(
!3
but the author,seeingthe definedpins in the include files,probablyrealizedthat the pins couldbe read and written directlyratherthan havingindividualbits ANDed and ORed asI do above.What the author probablydid not realizeis that an input pin valuecan be passeddirectlyto an output pin asI do in the followingcButton2.c:
This
mvke Dlealko
to
Tuln
on
of, scButton"
POBTA = 0x3Er // A11 BitE are High C!4CONo = 7, // \rt'l off Cdnpaialora aNSEIT = 0r // nrra off ADC TRrgA{ - 0, // uake 8A4/!tA5 outputa TRISAs - 0, whiLe(l
== 1)
//
a:l ir1
IJooD Eorever
{ RA5 = AA3; // Si.nE)Ier: // €lihw 2 ) // End cButlon
Pass Value
through
to
RA5
)
This is a fairly sirnpleoptimizationof cButton,but it illustrateshow the pin variabletype of the PICC Lite compilercanbe usedto greatlysimplifythe source codeof an application.
t--i
r,i\
n-L3 - Bulton Connection RiA.4 - LED Poaitive Conneclion RA5 - IJED Negalive Conaeclion
r*{ ':., r: ai.
Experiment2l-Debountring Button lnputs
r-1
raI
If you have some experiencewith digital electronic circuitqyou'll know that handlingbutton input is a surprisingly challengingtask with a bit of sciencebehind it, whichyou will haveto understandbeforeyou can processbutton inputsfrom the application. successfully The mostcriticalaspectof understandingbutton operation is to debouncethe incomingsignals.Knowing the cunent button state and how you want the application to work is integral.In this experiment,I will demonstratea simpleprogramto changethe stateof the D0 LED eachtime the RA3 button on the PICkit 1 starter
kit is pressed.I will demonstratealsohow the MPLAB IDE simulatorcanbe usedto verify the operationof an applicationbeforea PIC MCU is bumed with an application. Each time a switch (or button) state changes,the contactsliterally bounceagainsteachother asshownin picturedin Figure3-7.Thishappens the oscilloscope both when the contactsare madeandwhen they are broken.To interpret,or debounce,thechangein switch state,the line is typicallypolled until it staysin the samestatefor 20 ms The basiccodefor polling a switch input line and exiting when the line has changed state for 20 ms is asfollows: i = 0 , I / waIE 20 ms fo! !,rhi1e (i < Twentt|ms ) t
Butlon
SectionThree S i m p l e P I C @l l C l JA p p J . i c a t i o n s
tp
59
l. tt
t
:
(0 == a.a3 )
if
//
Butlor
Down/Slarl
ov€!
t = 0t
i
) else
//
qp/IncredFnt
Buttson
counl
{
sl
| ,
i = i + l t // El eLi}lw /l
NOP()t i = 0, // Wait 20 rns for (i < llwenlyns) rdhile (1 == RA3) // Bulton if else // Bulton i = i + 1t RA5 = RA5 ^ Ii
Figure 3-7
Debounce
l
LJ
) (0 == RA3)
if
"
//
Button
Dowa/Stsalt
over
{ = 0t
i
) €ls€
Butston
//
UDllacrement
CouDt
{
b&4
= i
i
+ 1t
, // f.r //
)
elihw
Using this codesnippet,the following cDebounce.c applicationwasdeveloped: *incluile /* cDebounc€. c - Debounc€
Butlon
Iry>ut
oa na3
ThL6 Program polla lb€ bullon at RA3 anal cha.dgeB tlt€ atate of Rias aft€r lhe DreEa haa beeD alebounceal. use a 20 ns al€bounce perioal.
r6{ f,'$
RA3 - Butston CorbectLon RA4 - IJED Poaitiv€ ConaectLon RA5 - IJED Negativ€ Connectsi.on rryke Dretlko 04.11.07
i!
qi€
-CONFIG ( INTIO & 1iID!DIS I'NPROIIECT \ & I'IIPROFECT FCMDIS) ' iDt
,;di
$"{
dr
int
Tw€ntf'ms
-
1150,
//
Declar€ a Coaataat for 20 mE Delay
naia ( )
t POR!a = 0x3Fi // All Bits ere High Cl'lCONo = ?t // 'I'ttta ol.t Colll)alators AI{SEL = 0r // Turn of,f, ADC TRISA{ = 0t // Make RA{/RAs Outputs TRISAs = 0t whil€(1
,&
& &
it
consl
w
& PWRTEN & IICLRDIS & BORDIS & IESODIS
{ while
== 1)
//
IJoop Forever
/ / ttlaiE 20 I[s (i < Twent!,ms)
for
Bulton
UI)
// //
Butslon ltDlslarts
Down/Incr€drent
ll
'loggLe
Dolrn
Rlas to
over
Count
Tuln
r,ED
elihw End cDebounce
In the cDebounce.capplication, I first wait for the RA3 line to be high for 20 ms and then I wait for RA4 to be low for 20 ms before toggling the D0 LED output state.In the applicationcode,for the first debounceloop (debouncingbutton goinghigh),I addedall the bracesfor conditionalcode.But for the seconddebounceloop (debouncingbutton goinglow), I eliminatedthe extrabracesbecauseonly one statement appearsafter eachconditional execution statement, and thesestatementstake up a relatively large amountof space.For the restof the book, I will be usingbracesonly whenmore than one statementexecutesconditionally. The NOP0; statementmay seemout of placein this apptcation. When I wrote this application, I found that I could not placea breakpointat the i : 0; statement following the first debounceloop,so I put in the nop instruction,which gaveme a placeto setthe simulator breakpoint.Thisis a goodtrick to rememberwhenyou are developing your own application. You might think that the first debounceloop (debouncing the button input going high) is redundant or not neededbecausewe just want to executewhen the button is pressed,but you must rememberthat the The debounce PIC MCU is operatingat MHz speeds. and LED toggleoperationexecutesvery quickly,and, without the button up debounceloop,you'll discover that the LED togglesat roughly 50 times per second rather than once,eachtime the button on the PICkit 1 starterkit is pressed. Before I burnedthis codeinto a PIC MCU on the PICkit 1 starterkit MCU,I simulatedit usingthe MPLAB IDE simulator. If you were to enable the simulator and start executingthe code,you would discover that it would get stuckin the f st debounceloop becausethe defaultvalueof RA3 is 0 (or a low logic level).Tochangethe stateof RA3 in the simulator (and add a digital signalinput),you can usethe
{
60
oN/oFF
l,e3 PICo l"lClE J xoeriments fon the EviI
6enius
A number of different options exist for defining stimulus.In this experimentI simplyworked with predefined pin stimulus,but you can also specify asynchronouspin statesusing the Pin Stimulus tab.To changeor set specificpin states,click on a button on the window.When you specify the predefined pin stimulus for eachrow,you will haveto specifythe followrng:
ft*[1@
. Figure 3-B
Stimuluswindow
MPLAB IDE Stimuluswindow shownin Figure3-8. The importantpart of the stimuluswindow is the area the at the bottom,whichlooks like a spreadsheet; changinginput pin valuesare specifiedalongwith the time (numberof cycles)the changetakesplace. To set up the stimulus window, you will go through the following steps: 1. 2. 3. 4.
5.
6.
Click on the Debuggerpull-down,and click on "StimulusController." In the MPLAB IDE Stimuluswindow.click on the File Stimulustab. Next. to start a stimulusfile. click on 'Add" in the Input File Box, and selecta file name. Make surethe stimulusfile nameis highlighted and click on "Edit" in the Input File box to bring up the spreadsheetJikeinput area. Click on'Add Row" and then selectthe desiied options(discussedin the following paragraphs)to build an input waveformio the applicationcode.In Figure 3-8,the stimuluslist puts the input line high,glitchesit down,and then holds the line low.
. .
. .
cq! &3 @
s 5J
&"' ;t
Tiigger On-either after executingfor so many instructioncyclesor when executionhits a specific address.For most pin stimulusapplications,you will lvant to trigger on a set number of instructioncycles.Thespecificaddressfunction is usefulfor applyinga test value to an internal register. TiiggerValue-the number of cyclesor addresses. Pin/Register-the I/O pin or hardwareregister to be written to. More than one pin or register can be referencedin a singlestimulusfile. Value-the 1 or 0 for a pin or a hex value for a register. Comments-gives you a chanceto note what is happening.
In previousversionsof MPLAB IDE, stimulusfiles wereproducedby a text file that wasloadedinto the simulator.The cuffent Windows version makes it easier to implementsimplestimulusinputslike this one, but I feel that for more complex operationg the Windows version is a lot more work and more difficult to implement correctly.If you have a complex stimulus for the MPLAB IDE simulator,I suggestthat you write it out fi$t and then enterthe datacarefully rather than on the fly, asI did for this application.
Savethe stimulusfile and then define and save the project'sstimulusfile (click "SaveSetup"in the File Stimulusbox of the Stimuluswindow).
{&
ry $
il.} A,r
iN : t' +tr
rh
t ,
N
s
{"J {U
*"$ nr
v' ._*
Experiment aa-_MELFIOperation I-ooking back at the first book I wrote about the PIC microcontroller,I wasamazedat the amountof spaceI devotedto the topic of resetand the -MCLR pin, which is usedto control whetheror not the PIC MCU is to execute. The PIC MCU I wrote aboutin that book,the PIC16F84,requireda separateresetcircuit that,ideally, held the PIC MCU resetuntil the power supplyramped up to the operationvoltage,held off clock start until
5ectionThree S i m p I e P I C @l l C U A p p l i c a t i o n s
61
,rl
fd ${ \v >.-l
*-{ f l re'{ I I t
{'"f
ry +)
s! s "*l
any initial fluctuations had passed,monitored the power supply,and reset the microconholler if it fell below a specificvalue, aswell as allowed the user to control the operation of the PIC MCU. Although some shortcuts existed,they could be irnplemented only if you understood the application and PIC16F84operation well and if you understood what the tradeoffs of the selectedmethodwere.One of the big changes sincethen is the sophisticationof the reset circuitry mostof theseissues built into PIC microcontrollers; are no longera concemwhendesigningPIC MCU applications A completeresetsolution for the PIC16F84is shown in Figure 3-9 and takes advantageof a chip like the PanasonicMN18311 reset supeffisor chip.This chip will not allow the microcontroller to executeuntil the input voltage has had a chanceto stabilize,and if the power supply voltage drops below a specificpoint (known asbrownout, the PIC16F84will reset.Not only does a modern PIC MCU have the voltage-monitoring hardware built into its reset circuitry, but it is also able to work over a much larger voltage range (from 2.0volts to 5.5volts comparedto 4.0volts to 5.5 volts for the PIC15F84),so brownoutsare muchlessof a concern. The PIC16F684hasthe built-in resetfeatures includingthe brownoutdetectionand built-in start-up delaythat wererequhedto be addedto PIC16F84 Along with thesefeatures,the new chip applications. includes a number of bits in the STATUS and PCON registers(listedin Table3-2)that canbe polled to help determinethe causeof a PIC16F684reset.For most applicationgthesebits canbe ignored,but in some casesit is importantto understandwhy an application hasstarted executing. For this experiment,Iwould like to demonstrate how the reset pin (also known as-MCLR) can be used to resetthe PIC16F684while poweris active.And by polling the _POD bit of PCON the programwill indicatewhetherresetwascausedby power on or by making the _MCLR (RA3) pin on the PIC MCU active. Normally,I disable the -MCLR function of the RA3 pin and rely on the internal hardware to properly reset the PIC MCU. For this cReset.cexperiment, I enabled _MCLR and usedthe button on the PICkit 1 starter programis kit to causea resetof the PIC16F684.The basedon cPKLED and when the program first powers Vcc
& t a.{ tr: i?t
Signalto Microprccessor
Fisure3-9 MCU reset
62
up and -POR is low, I set the program to run so the LEDs will light in incrementalorder.On subsequent power ups,if the CPKLED bit is set,then I run the LEDs in decrementalorder. *incluale - RoIl /t cRese!.c
Prckits
Tlrrough
S rrEDE
each roll through ThiE Plogrem will intso the Prckits PcBrJEDE buiLl Th€ LED values
of
the
I
at6:
IJED Anodle cathoale DO RA4 RA5 D1 AA5 RAII D2 A;A4 !lA2 D3 AJA2 R,A4 D{ RAs N,A2 D5 AA2 RA5 D6 BA2 RA1 D7 RA1 RAz rq'ke prealko 04.09.10
( INTIO & TiIITIDIS & PWRTEN & MCI.REN & -COIIFIG I'NPROTECT \ & UNPROTECT & BORDIS & IESODIS & FCMDIS) t of \IICIJRDIS' // llotse \!{CLREN/ insteatl
int int
i. j, kt Polarityt
naia( )
{ PORT.a, = 0, CUCONo = 7t ANSEL = 0t
// //
Turn Turn
k = 0t
//
Stsalt
at
//
Check UD
PCON Resister
if
(0 == POR)
(
= 0t Polality poF. = 7, // rntlicat€
off off
ConrDaratora lU)C LED 0 for
Star!
Prc ltcu Powerefl UP once
) 6La€ PoLallty while(1
(
// Reset = Lt ll == 1)
//
Go Backwardls Loop
Folevet
(i = 0, i < 255t i++) // for f o r ( j = 0 t J < 1 , 2 9i j + + ) ,
siry)le
s w l E c h ( k ) ( // select caa€ 0: PORTA = 0 b 0 1 0 0 0 0 , TRISA = 0b001111, b!eaki
rJED tso DisDlaY
PORTA = TRISA = breaki case 2 r PORTA = TRISA = breaki
l , e 3 P I C @M C U E x o e r i m e n t s f o r
lihich
0b100000t 0b001111t 0b010000, 0b101011,
the Evil
Genius
D€l'av I,ooD
cage 3! PORTA = 0b000100t TRISA = 0b101011t bleakt
Table 3-2 for IndicatingBeasans for Bits FlesDonsible FlEset
PORTA = TRrSA = breakt case 5: PORTA = TRIaA = breaki cas€ 5: PoRTA = TRISA = breakt
Bit Name
0b100000t 0b011011t
0b000100t 0b011011t
0b000100t 0bU1001,
(0 == Po!.arity) k = ( k + r l % a i / /
elBe k = l ] E - L r % a r / /
)
//
racrement of 0-7
k within
Decr€nent
k within
Enfl cReael
0
Function
_TO
STATUS,4 Normally Set,Resetafter aWatchdog Timer Reset
_PD
STATUS,3 Normally Set,Resetafter Executinga SleepInsffuction
r )
F*
ULPWUE PCON,s
Set to Enable Ultra Low-PowerwakeUp
SBODEN PCO\4
SoftwareBrownout Detect Enable
PoRTA = 0b000010t TRISA = 0b111001t bleak, ] // hctiws if
negislef BiT
l.'J
th r!.t L !
POR
PCO\1
Reseton PowerUp-after PowerOn SetBit
BOD
PCON,O
Unknown Value on Power Up PowerOn Set Bit
e3
after
t "1
For virtually all applications that you create,you can safely disable the _MCLR pin and use it as an input-only pin. The only circumstancewhere I would expectyou to enablethe -MCLR pin is whenyou are debuggingan application and expecting the application to fail and hang up periodically, requiring a lowresetvalue.
r ir1 !|"J
*{ ct I
23- E n d i n g F p p l i c a ti o n s E x F er im ent
DFf
throughD2) in sequenceand then end.I enabledthe -MCLR pin so the applicationcouldbe restarted rather than requhingyou to downloadit againto start the executionprocessagain. *incluale - I,ighl /* cEud.c lghis lhen
Before goingoff to rnorecomplexapplicationEI thoughtit would be usefulto discusshow your PICC Lite compilerapplicationexecutesin the PIC MCU. In particular, the manner in which the hex code is loaded andexecutedmay be confusingand,therefore,worth discussing.You are probably familiar with running programsin your PC: when a program ends,control doesn'treturn to the operatingsystem.Obviously,this is not true for the PIC MCU, which doesnot havean operating system;so you might expect that when the programcompletes, the PIC MCU just stops.This experimentwaswritten to test this expectation. The cEnd.c application waswritten for the PICkit 1 starter kit. It will turn on the first three LEDs (D0
SectionThree
Proglarl Enfl,
3 LEDg anal Return
will
Lighl
D0 to
D2 Ltr Seguenc€
anal
rDJake pretlko 04.09.12
i, J, iEnal = 235i
t5r
f t
-CONFIG ( INTIO & WIiIDIS & PI{RTE!{ & IICI,REN & IJNPROTECT \ & T'IIPROIECII| & BORDIS & IESODIS & ECUDIS) t
int int
tsr,,
//
:, Seconal D€lay
nain( )
t PORTA = 0, O(xlICONo- 7r // '!J.tin of.f conparalorE aNSEL = 0; // Turlr of,f, A.DC PORTA = 0b010000t
//
D0
S i m p l e P I C @l l C U A p p l i c a t i o n s
63
TRISA = 0b001111; f o r ( i = 0 r i < i E n i l t
silrp1€ Delay for D0
f o r ( j = 0 r j < i E n a l i PoRTA = 0b100000r // TRISA = 0b001111t f o r ( i = 0 r i < i E n a l t
j++)t D1 sirE)le D€lay fo! D1
f o r ( j = 0 r j < i E n d t
j++)t
PORTA = 0b010000, // TRISA = 0b1010U, for(i=0ri
i++ )
f o r ( j = 0 r j < i E n a t t
j++)t
PORTA = 0b000000r
//
Retula stale
//
Delay sinple f.oi D2
PORTA to
Initial
TRISA = 0b11u11t // // l
U , f-t
*r ; i,! \t, '".d 'P.
ill
l
t
=- L), // lrorrral Enal whtle(]. SIJEEPO, // Allernative Endl //
Enal cEntl
When you run the programasit is presentedhere, you will discoverthat insteadofjust stoppingat the end (D2 turns on and then off), D0 lights again and the programseemsto run again.I suggestthat you now run it on the MPLAB IDE simulator,put a breakpoint at the first statement(PORIA : 0;) and at the last statement(TRISA : TRISA | 0b011111111), and start the programexecuting(with the stopwatchdisplayed).Theftst time the programexecutes, it will stopat "PORTA : 0;" indicatingthat it hasexecuted in 100instructions.Click on "Run" againand the program will executefor a few momentq finally stopping at the "TRISA : TRISA I 0b011111111;" statement with 3,006,075 executedinstructionson the stopwatch. Now,click on "Run" a third time.You might expect that the simulatedPIC MCU neverstopsexecutingor that it immediatelystopsand resetsthe simulatedPIC MCU. Actually,neitherhappensiexecution returnsto the first breakpoint(PORIA : 0;) and the stopwatch displays3,006,175 instructions. From theseresultsyou canconcludethat programstartsagainafter 100 instruction cycles.What is happening is most easily illustratedwhenyou are familiar with assemblylanguage,but the short explanationis that whenthe PIC MCU reachesthe end of programmemory,insteadof stopping,the programcounterresetsitself and starts executingfrom the start again. To preventthis from happening,Inorrnallyendmy programswith a statementlike the following that puts the PIC MCU into a hard loop that executioncannot escapefrom: whtL€(]. == 1),
h-
Although you will seethat I have noted this with a comment(or "commentedit out") in the previouspro-
64
gram,to testthe operationof this statement,deletethe two slashesto the left, rebuild,and retry the program. You will find that it will stop after D2 hasbeenturned off andwon't start until you press"SW1" (the reset button) on the PICkit 1 starterkit.Along with the while foreverloop,you canalsousethe SLEEP0; PIC MCU instruction,which is set off asa commentafter the while statement.Thisinstructionputs the PIC MCU into a low power state,and then allowsit to be restartedby pressingthe resetbutton on the PICkit 1 starterkit. In mostmicrocontrollerapplications, the programis continuallylooping,so the needfor the while statementor sleepinstructionis not required. But in applicationswherea singleoperationis being carriedout (like the examplesin this book),you will needthe while statementor sleepinstructionto prevent the programfrom executingrepeatedly.
For Consideration So far in thisbook,I havereliedupon the PICkit 1 starter kit exclusivelyfor putting in the circuitry but you canbuild thesecircuitson a breadboardvery easily if you have a limited number of PICkit 1 starter kits available(suchasin a classroom). Another casein which you might want to build a PIC MCU circuit on a breadboardis when you require different circuitry than is availableon the PICkit 1 starter kit. In the following paragraphs,I will quickly introduce you to putting a PIC MCU on a breadboardandsomeissuesthat you should be aware of when building your own circuits. The basicparts required for wiring a PIC MCU on a breadboardincludethe following: 1 Smallbreadboard 1 Breadboardwiring kit 2 AA or AAA batteriesand clip with breadboard wires 1 0.01mF capacitor(any type) 1 Powerswitch(E-Switch'sEG1903is recommended) LEDs Capacitorsof variousvalues Optional parts that you will want include the following: Pushbuttonswith breadboardwires Potentiometersof variousvalues
l , E 3 P I C @I I C U E x p e n i m e n t s f o r
the Evil
6enius
Smallplasticpartsbox The toolsthal you will rcquire includethe followlng: Smallflat screwdriver pliers Needle-nose Wire clippers Wire strippersor knife This probablyseemslike a modestlist of partsand shouldnot costyou muchmore than $20.00,and with them you cancreatea wide variety of differentPIC MCU applicationsoutsideof the breadboard.What of the two "radio may surpdseyou is the usefulness batteries"that togetherprovide about3 volts (for alkalinebatteries).The PlC16F684(and most other new PIC MCUs) will work with voltageinputsranging from 2.0to 5.5volts.Many modernperipheraldevices alsowork at thesevoltagelevels,so rather than using somethinglike a 9-voltbatteryand a voltageregulator to get 5 volts,you cansimplily your circuit by powering with two radio batteries.A completekit is shownin Figure3-10and canbe purchasedfrom a varietyof sources(includingRadio Shackand Digi-Key). The kit consistsof a breadboard,a breadboard wiring kit, someLEDs, resistorsor dilferent values (100Ohms,220 Ohms,330Ohms,470Ohms,1k,and 10k are goodvaluesto start with), capacitors(0.01pE, 10 pF,and47 pF will be useful),a momentaryon push button,an SPSTswitch,and a two-cellAA or AAA batterypack.As you createmore complexapplications,you will probablywant to expandthis kit. It would be a goodideato get a smalltool kit aswell.
Pin throughhole (PTH) chips(like the PIC16F684 and breadboard microcontroller),resistors,capacitors, wiring work without any modificationsto the brcadboard and only a few to someof the components. Although it will take a bit of work. For a power switch, the E-SwitchEG1903SPDT (availablefrom DigiKey) will work with a breadboardwithout modification. Unfortunately,I havenot found a momentaryon switchor batterypack that will work with a breadboard without modilication;I solderwiresonto standard partsasshownin Figure3-11to get this capability. Onceyou havethe parts,you canwire togetherthe cFlash.ccircuit (Figure3.12)in just a lew minutes,and the resultingcircuit shouldlook somethinglike Figure 3-13.Although the circuit seemsquite simple,there are threethingsto be awareol The first is to wire both sidesof the breadboardwith power (Vdd/Vcc) and ground(Vss/Gnd)on the commonbarson both sides of the breadboard(seeFigure3-13).This will n.rake your wiring simplerwhenyou havemultiple devices
Figure 3-ll AAA batteryclip and momentarypush buttonmodified with breudboardwiressoklereclt
#
2x 'AA' Baitery
-: -f I
Figure 3-110 Breadboard with basic parts neetled to run the PIC|6F84
.L
VSS
Figure3-le
Breadboard
5ection Three S i m p I e P I C @l l C U A p p l i c a t i o n s
circuit
6s
o! E P
2x'AA' -: or'AAA': Battery: Pack
t LED Can Ptc
Figure 3-lq Figure 313 Breadboard wiring to demonstratethe cFl.ash.coperation
on the breadboard and you won't have to crossover chips wheri you are connectingpower and $ound. Secondly,make sure tJrata switch is located on the positive terminal of the battery pack before power s passedto the common bars on the breadboard,and don't just place the switch on the Vdd pin of the PIC MCU chip @in 1). ff power and ground are available on other pins of the PIC MCU, you will discoverthat it will run, even if no connection to the Vdd and Vss pins exists.The clamping diodes on the UO pins of the PIC midocontroller will allow current to passtlrough them asshown in Figure 3-14,and frequently this will
Parasiticpower
be enoughto run the application.This is often called parasiticpower ard.problems with it can be avoidedif you control power at the source,rather than at the PIC MCUchip. It's important to remember to remove gently the PIC MCU chip after programming and insert it before reprogramming.The easiestway I have found to remove chips is to stde a small flat-blade screwdriver under the chip and twist; it will pop up from the breadboard. Before inserting the PIC MCU chip, make sure all the pins are aligned before pushing the chip onto the breadboard.You can even roll the chip on a table top to bend the pins inward. Bent pins can be straightened using a pair of plie$, but by taking a bit of care, you'll never have to.
c o .rl {J
(I, ${
o €
.r{
v,
g
o
U
t{
o
F.
56
l , e 3 P I C @l ' l C UE x p e r i m e n t s f o r
the EviI
6enius
Four
Section
f LanguageFeatures type at the start of the file name for two reasons.The first is so I can use the folder name to differentiate betweensimilarprograms-thosecodedin C or assembler. The secondreasonis that the extensionis not displayedin the folder window of Microsoft Windows,and I want to make sureI know at a glancewhat language theprogramis writtenir.. The main part of the file name (Function, in the previous convention line) is simply what the program does.Personally, I would like this to be arbitrarilylong so I could createfile nameslike "SingleButton Debounce,"but the 64-character limit imposedby the MPLAB@IDE simulatormakesthis difficult. So I stick to a single surnmarizingword. If I am going to produce multiple versionsof the application,I keeptrack of them by a versioncodeseparatedfrom the rest of the file nameby a blank.
In this section,I will presentmany of the advanced features of C that will help you more efficiently program your applications.Thesefeatures allow you to more quickly create applications that are smaller,run faster,and handle data in different formats.Before I go on to the more advancedfeaturesof C.I would first like to addressthe topic of makingyour applications more readable. Readability of a computer program is a function of five different parameters: e
Appropriate file name
.
Header information
. .
Intelligent comments Adherenceto formatting conventions
.
Conventionalstatementusage
Remember to keep eachapplication in its own separatefolder.Multiple applicationsin the samefolder (or evenon your PC's desktop)are difficult to sort through to find specific applications.By keeping every applicationin its own folder,you will easethe workload requiredto find a specificapplication,help you managethe applications,and identify which ones are neededandwhich aren't. Every programshouldhavea headerblock with the following information:
This list of parametersshould not be surprising,but I am amazedat how few peoplethink to usethem when they are under a deadline.Actually, theserules often fall by the waysidein normal programming,causing a lot of grief whenit's time to go back and try to fix somethingor evento usethe codein anotherapplicauon. The filenamethat I haveusedfor the codepresentedin this book and the folder in which it is stored followsthe convention: nl"anguag€extl\rnctioaI
ftselalionl
.languageext,rr
"Languageext"is "c" or "asm,"dependingon the languagethe applicationis codedin. I put the language
. . . . .
Summaryof programoperation Detailed descriptionof what the program does Hardware information Author's name Date last updated(ideally with comments explainingwhat wasdone)
The purpose of most of this information is to allow you or somebodyelseto scanthroughand seeif this is the applicationrequired.You might be looking throughpreviouslywdtten applicationsfor samples that use specific hardware,or for a particular application that requires a fix.
67
Intelligent comrnentsexplain the purpose of a block of code.How the codeworks shouldbe selfexplanatory. The following is an example of what not to wdte: I
= i
+ 1r
//
Incteneut
Couat€r
i
This comment is not helpful asyou would assume that the readerknowsC well enoughto understand what the codeis doing.Insteadthe commentshould explainwhy the codestatementis there.A better comment for the statementmight be:
i = i + 1'
,A
0)
t{ Fi
{J
d \y [&l
ry
b d
"::::1":::'"::"*
In university,Ihad a professorthat took marks away for every comment in an application.His logic was that the code should be written in sucha way that it is self-commenting.I can seehis line of thinling, although it is probably the other extreme of voluminous,redundant commenting.I would suggestthat you follow the rule that commentsshould only add information. When you've been taught to program and when I have presenteddifferent statementtypeq they are formatted in very traditional ways.You may be unaware that C and mostother highJevellanguagesare very loose with their formatting, and an if statement like this one:
bt
i f ( A > B ) i = i + 1 ,
6 *4 t \
j
is just asvalid to the compiler asthe traditionally formattedstatementlike this one:
! i f
f.t't
o
( A > B ) i = i + 1t
eLse j = J + 1 ,
\J
r,t
+ 1,
(J is the endingof thestateIn C, the semicolon ment. Until the semicolonis reached,the statementis parsedasif it were all on the sameline, or formatted traditionally. You might think that a different statement format will make the application more efficient, but it will only make it frustrating for others to read and debus.
'r{
When I am formatting code,the rules that I use are as follows: . . .
.
Each statementis on its own line. Nestedconditionalexecutionis indentedby four spaces. If statements are longerthan lhe page(or screen)width, find a natural break and start them on the next line, indentedfour spaces from the start of the previousline. Commentsall start on the samecolumns.
Simple,clear code that is written in a consistentformat that is easierto read-even if it is formatted differently than you are usedto-than code that doesnot follow a single format and usesdifferent conventions for indentations and variable names.For example,the numberof indentationspacesI suggestis basedon whatVisual C11usesand I havebecomeusedto.You may find that two or eight spacesfor eachindentation makesmore senseto you. I do have one warning regarding indentations.Try to resistthe urge to rely on tab characterswhen moving code or commentsto a specificcolumn;use spacecharactersinstead.Different editors and web browsers interpret tab charactersdifferently, and by using tabsin your code,you will find that your neatly organizedprogram will becomevirtually unreadablein other tools. The final comment is similar to the previous one.As shown,C is a remarkably flexible language,and there are a lot of different waysof doing things My recommendation is this: Do not try to be creative in how you codeyour applications.Instead be asconventional as you can.Thespacesavingsandspeedimprovements(if any) madeby creatively organLing the code of your application will be offset by the increaseddifficulty reading and understandinghow the code works.I put the caveat"if any" in parenthesisbecausethe optimizer in the PICC Literu compiler is very sophisticatedand very good at identifying situationswhere repeatedcode is integrated into a subroutine or even reorganizingthe code to avoid redundant blocks of code. To summarizethis introduction, I quote the credo of the poor coder:"If it was difficult to write, it should be difficult to read." And the corollary is also true: If you work at making your code easyto read, you will find that it is much easierto wfite. The added benefit will be that your teachers,supervisors,and coworkers will appreciateyour efforts over those programmerswho do not try to make their codeeasierto read.
r l
(_,
$ 68
l , a 3 P I C @l l C U E x p e r i m e n t s f o r
the Evil
Genius
pl
Experiment 2t-.1-Functions and 5ubroutines
t.?
Functions are very similar to subroutinesexcept they retum a singlevalue.The declarationstatement for a function is very similar to the subroutine,but differencesbetweenthe two relateto the declaration statement'sability to return datato the caller: (ty9e var1, zunctslonNam€
type t //
If you were to Google@ the C programminglanguage for a definition,you would discoverthat it is "procedurally based."Thismeansthat the languageis designed to implement subroutineseasily so that prograrnming taskscan be brokendown into smallerpiecesfor easier programmingand reducedopportunitiesfor errors. Subroutinesin C will allow you to simplifyyour program, but I am more excited about C's ability to create functiors ,which offer much greater utility to your applications Just so the terms are straight, I usethe word rnvoke synonymouslywith cal/ when I am referring to subroutinesand functions. Subroutinesin C are declaredin the followins format: SubroulifleName
( t].D€
Var1,
...
{ // |
gubroulin€ //
)
stat€drentB her€
EnA subroutineName
and musteitherbe declaredbeforethe subroutineor a prototypehasto be placedbeforethe subroutineis used.This prototlpe consistsof the subroutinedeclaration statementwith a semicolonafter the input parameters.Prototy?es are often placed in include files (endingin .h) that are loadedat the start of the C sourcecode.For the previousexample,the prototypeis asfollows: Subloutsin€Ndne
(ty9€
Var1,
...
)t
Personally,I put subroutinesand functions above the mainline to avoid the need for protot)?es. The only time I useprototypesis if I havepreviouslycompiled the subroutine or function and I'm linking them with the mainline.In thesecases, I will load them all in a .h include file. One important reasonto place subroutines and functions before the mainline is to avoid the bother of maintaining the prototypes if the functions themselveschange.If you changethe input or output parametersof a function and do not changethe prototype.you will get an error message.
11 q
;., tt)
...)
r-ts Funclion
statelreats
return ,
dn
ReturnvaLue
tud.
//
h€r€ i
h3
subroutia€s
To invoke a function, a statementin the following format canbe used: 1=
FunctiotiNam€ ( inlrutParanat€r,
...)t
I trl
Or a subroutineinvocationcanbe used: e"a gubloutineName
( inputPalam€ler
,
.. .)t
/-!
If a functionis invokedasa subroutine,then the return value is ignored upon return. To demonstratethe operation of a function in a program,I createdcFactoral.c, which calculatesthe factoralsof the first eightintegers: #inclual€ - Calculale cEactoral.c /* Inlegera Thia 10.
Plogram
Calculatses
lh6
Factorala
Factorals
of
fldr
1 to
nr *"{
p,
{n 1.,
int tnt
Faclval,u€i
int
Facloral(
f,or
//
F
Ft
j.nE Nt|rib€r)
(Faclvalu€ Faclvalu€
!€tur|r ,
$d {*
rrl|ke D:.eflko 04.09.15
(
$r.
r{
= 1r N\jlib€r > 1t N\rntber-- ) * lludberi = lactvaLu€
.+
EactvaLu€i
,r. H
ElLd Factoral
TE
nain( )
{
SectionFour C L a n g ua g e F e a t u n e s
t3
69
for
(i
j
,
-
1r i
<= Ir
= FactoraL
i++)
//
Return the Factoral of 1 t o 8
(i) t
while(1 =- 1), E^d. cEactoral //
The programmultipliesthe integerby eachdecrementingvaluesuntil it reachesone.Thisis not the traditional way of calculatingfactorals.In C, this function is normallyshownasan exampleof a recursivefunction. I will not be discussing recursivefunctionsin this book for two reasons:(1) It is beyondthe scopeof this
book. and (2) the PIC16F684microcontrollercannot suppot it easily. When you simulatecFactoral.c, I suggestyou display the Watchwindowfor the four variablesusedin the program:i, j, FactValue,and Number.When you run the program,you will noticethat eachof the four vadables,exceptfor Number,is displayedat all times. Unlessexecutionis within the Factoralfunction.the "Out of Scope."The variableNumber hasthe message, reasonsfor this messagewill be explainedin the next exDerlment.
E x per im ent25- 6 l o b a l a n d L o c a lVa ri a b l e s nl'ke pr€dko 04.09.16
( int
i.nU Plinecheck
value)
t j
fo'. li i++) if
j)r
In C, you havethe ability to redefinevariablenames, so long asthey are declaredwithin functionsand subroutinesand not outsidethe main statement.This feature is known as/ocal variablesand allowsyou to reuse commonvariablenames(suchasi, j, k, and n) without fear that the contentsof a variablewill be changedor corruptedby other functionsand subroutinesin the application.To demonstratethis capability,I created the programcPrime.c,which hasthe function PrimeCheckthat usesthe samevariablesasthe mainline uses.Whenyou run the applicationandtry to monitor the valuesfor the counterand flags(i andj, respectivelyin eachfunction),you will discoverthat MPLAB IDE hastrouble monitoringthe correctvalue for the variablesand may evenstop single-stepping correctly! #include - Find cPrine.c /r Integers
Che Primea
in
the
first
200
This Prograr works through each of th€ prime rumbera frorn 1to 200 anal indicates which ones are prine h,t att€lpting bo divide every integer fron 2 to ( (Nurlb€r / 2) + 1).
= 1;
)
{ int
i,
for
the
MPLAB
(0 == (va1ue % i))
= 0;
jt
(i
= 1r i <= 2OOi i++)
j = Primecheck(i) i
//
rf
DiviEible
//
value iE NOT Prime
//
Retuln the Prime Fl.ag
//
T6at Every
//
i:::::"'= l+nrar
is
)
(1 == 1)r whil6 E ral cPrirne //
//
t if
i
P].ime
Loop For€ver
The problemsare causedby the confusionthe MPLAB IDE simulatorhasregardingwhichi or j it shouldbe displaying.This doesn'tmeanthe program isn't working properly,but that MPLAB IDE cannot properlydisplaythe valuesof i andj. In this programthe i andj local variablesthat are specificto eachfunctionare uniqueto one anotheras well asto any variablesthat are declaredoutsideall the functionsof the program.Thevariablesthat are
l , a 3 P I C @l l C l J E x o e r i m e n t s f o r
under
/
jt
70
run
< ( (vatue
main( )
is
to
(i
ead. Plinecheck
//
Thia program rDE simulator On1Y.
alegigrteal
= 2,
j letuln
aaBume lhe value ia prime 2) + 1)) && (0 != //
the Evi I
6enius
declaredoutsideall the functionsare known asglobal within any function. variablesandthey canbe accessed When debuggingfunctions,you will probablywant to changethe variablesthat are local to the functioninto globalsso that you can debugthem usingthe full featuresof the MPLAB IDE simulator.From a programa bad ming qualityperspective, this is not necessarily idea;by testingand debuggingindividualfunctions beforeintegratingthem into an application,you to ensurethat they are correctbeforethey are usedand simplifyyour applicationdebug. The big questionyou are probablyaskingyourself from this experimentis "When shouldI uselocalversusglobalvariables?"When I programin C for the PC, I try to make all my variableslocal;but I useglobal across variablesonlv for the valuesthat are accessed
the applicationand/orthat would becomecumbersomeif their parametersneedto be passedto other functions.I do not follow this rule when I am programming the PIC@microcontroller,becausethe PICi6F684processorarchitecturedoesnot allow for parameterstringsof unlimitedlengthto be implementedefficiently.Ideally,you shouldkeepyour input and output parametersto 16bits.Additionally,there couldbe situationswheremultiple variableswith the samenameare declaredbut only very rarely accessed, and thereforetheremay neverbe any dangerof them appearingmultiple Iimesit nestedsubroutines(snbroutinesandfunctionsthat otherscall or are calledby other subroutinesor functions).For thesereasons,I tend to declareall the variablesasglobals,exceptfor counters(i,j, and so on) and temporaryvalues.
Experiment26-Defines and Macros
In Section2,whenI introducedyou to variabledeclarations,I alsonotedthat constantnumericvaluescould be declaredaswell.Theconstantvaluesthat wererepresentedby the labelswould be substitutedin anytime the label wasencountered. In this way,commonlyused values could be stored asan easy-to-rememconstant readability of the prostring that should help the ber gram.I did not focuson the constantvaluedeclaration. I try to avoidusingit in my programming,becauseI believethat its declarationcanbe easilyconfusedwith variabledeclarationsand becauseit doesnot encompassall the differenttypesof data that are usedin programming. To declareconstantvaluesof all types,I usethe #definedirectivebuilt into the C programminglanguage.The format for the #definedirectiveis as follows: *define
labeJ. t (Argumert,
...
)I
Strinsl
with the label encountered, the .slrilrgthat is associated is insertedinto the program.A subtlebut very important differenceexistsbetweenthe two, asI will showin this experiment. The stringreturnedby the definelabel doesnot haveto be numericonly;it canbe alphabeticcharactersor evenC programlanguagestatementslike if or for. Thesesubstitutionsare allowedbecausethe define substitutionstake placein the compiler'spreprocessor. That is,the stringsare substitutedinto the program sourcecodebeforecompilationstarts. Further enhancingthe usabilityof the #definedirective is the ability to specifyparameterstrings(the argumentsin the previousdirectivedescription).These parameterstringsare substitutedin the #definestring, allowingyou to customizethe stringfor a particularsituation.Theadditionof parameterstringsallowsthe #delineto behaveasa macroand allowsyou to easily enhancethe operationof your application. Macros are seclionsof code that are commonly used,but deemedinappropriateastheir own subroutinesor functions.In this expedment'sdemonstration application,cDefine.c,I showhow #definesare usedto definea constantvalueaswell as,with smallpiecesof code,to providesimplefunctionsthat may be required multiple timesin an application.It isn't unusualto refer to constantvalues,declaredby usingthe #define directiveand codestringsthat are addedto the applical\on asmacros.
When a label that has been declared as a constant is encountered, the numeric value associatedwith the label is returned.When a label declared in a #define is
5ection Four C L an g u a g e F e a t u r e s
7L
#incLuale - Denonstrate cDefia€ /* fo! Equales anal Maclos The C "Defin€' equaling values Th€ae proglall.
the
Defin€
Dir€ctive
direclive can be useal fo! aa weLI as Droviding basic
caDabiLiti€s
are
ilemonBtrated
Halalware Nolea: PIC15F684 running al 4 M$z ln ReBet iE li6al ali!€cE1y to vcc PrograEniag Haralware
in
both maclo thig
Sinulato! via PuLluD/
Myke Pletlko 04.09.26
tors;wh€nthesecharactersare encountered,the preprocessormovesthe next line to the end of the current one.This allows for multiple-line macros or for situations like this, where you could cram the macro string all onto one line.But by usingthe line continuance character,the line canbe readmore easily.Secondly, the macro has a question mark (?) and a colon (:) characterinsertedinto it, neitherof which seemto make any sense. The questionmark and colon are part of an altemative conditionalexecutionstatement.which hasthe following forrn: Conalltq)reBBion FaIB€E apr6ssion
F4
rl
{q3
| / Deelneg constantva].ue *t[€fine ldgbByt€
*alefine
Lowtsyte(value)
va].ue
/
vaLue
% 0x0100
uDDercase (charact€r) *alefine \ ( (Chafactse! >E ra') && (Chalacler Clraract€r Charact€!
0x0100
<= '2,))
?\
qL!
nain(
)
iat lilurbell , N\nber2 t char Char1, Cha!2, Cha!3t Nunb€r1
= 0x0123t
//
Iilr,mber2 = ConBtantvaluot
.r{
Chart
ft!
//
= '1"
//
(Nlrnber2 ) r
//
t I I
Nllriberl
= IJowBt't.e (Nurber2
),
//
rtr f.i nl )
N a!
Get Bigh Byle of, Nunb€r2 eel Lolr EyEe of Number2
cha!1
= UlrDercase ( Charl. ) ,
//
ISBE "qpD€rcaaen
char2
= UrpDetlcas€ (Cha!2 ) ,
//
llac!o only value be Changetl
Chal3
= UDDelCade (Cha!3 ) i
$hi1e
(1 == ].)t
i\*
. *,{
Stantlaral rnitlalize LnLEiaLi,ze witsh Define Characte! hirializ€
Cbar2 = 'b', Char3 = '7" lituIl|ber1 = HighByte
//
lf
( CoaalE:rDles s ion ) i = TrueE qrressioni €Ise i = FalseE
Personally, I do not like usingthis alternativeform of the if statementexceptin macros,asits operationis not alwaysobvious(e.g.,the colon canbe easilymissed or misreadasa semicolon),it doesnot allow rnultiple conditionallyexecutingstatements, it is not logically nestedwith other statementqand it often endsup running over a singleline,which makesits operationeven more cryptic. It is,however,an efficient way of adding a conditionaloperationto a macro,just asI havedone in this experiment.
{ ,it
tso
Before ending,I shouldnote that the #definedirective canbe usedfor renamingI/O pins in PIC MCU applications. Ratherthan accessing an I/O pin asthe genericlabel,you can assigna label to it usingthe #define directive. For example,if you had an LED wired to RC2, you could declare it using the following statement: *al€f,ine
//
:
When "CondExpression"is evaluatedif it is true (not zero,which is what "true" means),then "TiueEx"FalseExpression" pression"is evaluated;else is evaluated.Thisstatementis usefulfor situationswhereyou want to seta variableto a specificvalue,asin the code:
0x1234
(valu€)
*tlefine
? Tru€E:qrr€BEion
FiniEhetl, Loop Fo!6ve!
Enal cDefiDe
The strangeformat of the Uppercase macro will requiresomeexplanation.The two backslashes at the end of the first two linesare line continuanceindica-
LED RC2
Now, when the PICC Lite compiler encountersit, it replaceseveryinstanceof"LED" with "RCZ."This is a usefultrick for makingyour applicationseasierto read andwrite.
&'&4 4.6 trt
72
l , e 3 P I C @l l C l J E x p e r i n e n t s f o n t h e E v i l
Genius
rfl
Experiment ?7-Variable Flrrags
X
€
Array addressingis a common feature of most programming languagesand provides you with a mechanism to allow you arbitrary variable data within your application.Array addressing could alsobe called indexedaddressing,and it utilizes an arithmetic value to specifya certainvariableelementin an arrayvariable.Arrays allow you to handle more data than could be handled normally in an application and to write applications that would be very difficult without this capability. Using arraysin your program is actually quite easy. In Figure4-1,I showhow I visualizean array-as a seriesof memory elementsthat are given a single variablename.Eachelementis accessed by specifyingan indexvalue.The indexcanbe a constant,a variable,or an arithmetic expression.For example,eachof the threestatementsbelowwill load the variablei with the contentsof the fourth elementofArravVariable: i
-
i
= Arrawariabl€ljl
Arlayvariable
[3] ,
// //
r
E.presEion
int
= t' = 3
-
Arratryarlablel(l
177. L2L, LOi,
Tenp
= gortArlay
SortsAffaylil
= SoltArrayli
+ 1l
sav€ !h€ eurrent Valu€ // store Next value ia Current // Ilul Ortgl.aal currents value in Next //
[i]. + 1lt
= Te pt
Thesethree statements,which require an extra Temp variable, are a fast and efficient way of swapping the contentsof two variables,not just arrayvariable elements.
fll?J,[!*z: s a @rs "Bubble" Testind ArrayElement Values
Declared As: inl
VariabfeNane[4];
Figure q-l
Array
Figure U-2
\ArrowsShow Exchange of Sort
Bubblesort
SectionFour C L a n g ua ge F e a t u n e s
tt\ lv l.t
l-" tn
x
tg {
IT
LOLI i
A commonprogramusedto demonstratethe operation of arraysis the bubblesort (seeFtgure4-2).In this simpleprogram,eachelementof an arrayis read and comparedto the onenext to it (this is the bubble).If one elementis greaterthan the next,then the two are swappedusingthis simplethree-statement sequence:
sortelrayli
Intlex is a Constanl rnd€x is a
i = arrawariabl€ Ij * 1r, ,, rtiJ"'**ff jt
Array elementsin C start at an index of zerq not one asyou might expect.You couldcreateyour programswith one extra element and start your index at one,but this would not follow conventionalC programrning and would make it difficult for others to read your program. I should point out that many other languages(including various flavors of BASIC) all have their fust array element aszero,so this is a convention that is transferable to other languages. To define an array variable, the variable with its sametype is specifiedalongwith the numberof elements of the array.Along with this, the initial valuesof the array can be optionally specifiedby placing them within bracesasI show in the samplearray variable declarationstatementshownhere:
73
sr-i F.
p,
tr
F
{D
F
h1 H
p,
m
The mostbasicbubblesort programthat I cancome up with is asfollows: #incLudle - siry)Ie cbsoft.c /* This values.
Proglarr
ia
C Plogram
a aimple
Bubblo
'Bubbl€
So!t.
of
ffi
Ii
to
run
in
the
)
== 1)t
//
Firriahotlloop
d{il )
{ * r?a
a
* f-* .
3,
4,
ll
o, 2, 4,
6,
A,
//
9,
L2,
//
L5r,
//
o're Row Tvo Ront 'I}rte.e Row Eolr]. Row
i = 3r Proaluct
i = {t = MuLArray IiI
tilt
i, - 4t Product
i = 3i = MulArlay
til
tilt
i = oi Proaluct
i = 2i = MuLAl.lay ti]
tilt
i = li Proaluct
i = 2i = MuLArray IiI
til;
whir.e(1 == 1)t
whiL€(1
{ :
zer o
(
(t = 0r i < siz€of ( So:.tvalues ) t i++) for - (i + 1))t (J = 0r i < (sizeof(Sorlvalues) fo! j++) (sortvaluestjl > Sortvaluea [j + 1]) { if TdE) = sortvalues tj I . = Sorlvaluealj + 1lt Sortvaluealjl + 1l = ledlpt sorlvaluealj , // f5-
'at
//
rnaia ( )
t
F-{
0,
o, 1, 2,
20
iltt i, j, TenD, char Sorlvalu€E [20] ={33. 5{, 42, l2O, 37, 5, 99, 105,8.2r, 1OO,33, 4r, 77, 41, 69, t3,86, 51, 901t
&'"{
0,
o , 4 , a , !2,
Earflware Not€E: ThiE Progiam haa b€en written IIPLAB IDE Sillulalor ONIJY.
nair(
0, 0,
Rolt
Sort
l[yke gretlko 0{.08.03
P1
inl i, j, Produclt ints I'lutArray [ 5 ] I51 = t0,
//
Edil
cbsoll
So far I havediscussed single-dimensional arrays (arrayswith one index),but you can alsoimplement multidimensional arrays in C by simply adding a second setof squarebracketsasI do in the following exampleprogram.Note that when I cameup with the initial values,I kept the valuestogetheraccordingto the row in which they appear. *inc].ual€ l* clIulArlay. c - UultiDle
Dimen6ionaL Array
This Program alemoaEtslates how e two alimenaional array coulal be inpldEntsetl !'luttiplication. sinptify
to
myke pretlko 0{.09.0? Haralware Notes: ThLa Program haa been wrilten to the llPLAl IDE Simulato! ONLY.
{1} &,{"t
74
run
in
l
//
Ertd. cMulAffay
If you are looking at the cMulArray program,you might think that it is a clever way to avoid having to use a complex multiplication routine. Unfortunately, when the compiler is calculating the address,the row index (or the first dimension) is multiplied by five and then addedto the columnindex (or the seconddimension) to calculatethe indexelementto be accessed. Another way of putting this is that all arraysare actually singledimensional,and the multidimensional array format is simply provided as a way to avoid requiringthe programmerto calculatethe address. Before using a multidimensional anay, think about how necessaryit is to your application.Two- and threedimensionalarrayscan use a lot of spacethat could be usedfor other functions.For the cMulArray program, the MulArray variable takesup 50 bytes (five rows timesfive columnstimestwo bytesfor eachintegerelement). If we were to extend it to three dimensiongthe total memory requirementswould become250bytes, which is much more than is availableto the application. From an academicperspective, the bubblesort algorithm is probablythe leastefficientalgorithmfor sorting data.Other sortingmethodsare much more efficient, but they require resourcesthat are generally not availablein the PIC MCU processorarchitecture, and implementing them can be quite difficult. In any case,for mostPIC MCU applications, the bubblesort is good enough;in fact for the rest of this chapter,I will look at different ways of implementing it using different C languagefeatures.
l , a 3 P I C @l l C l JE x p e n i m e n t s f o n t h e E v i I
Genius
Experiment 28-Structures and Unions and personalinformation.Thestructuredeclared below is an exampleof somethingthat couldbe used bv a storeto keeDtrack of its customers: Cualodnellnfo struct { char Nalne [ 6{ ] t char Aalalless [ 128] t int sonePh[101t int
When processingdata or handlingmultiple datatypes, simplearraysare often not the answerto the problem. What is neededis someway of combiningmultiple piecesof disparatedatain the samevariable.Therewill alsobe caseswheresinglepiecesof data may be dividedin differentwaysfor differentdatagroups.The solutionto this problemis actuallyquite elegant.In the C languageyou candefineyour own variabletypes with specificparameters; you evenhavethe ability to representdata in more than one way. Tt1estruct lqngu(tgestatementts used,to define a variableof arbitrarytype that cancontainmultiple piecesof data.Theformat of the statementis:
// // //
BusPh t10l ,
//
char ernail [32 ] t CDate !astSalet
//
int
//
LastsameAmtt
Custon€r Nane Aalalres s Ilortre Phone Nunbe! nork Phone Nudber Date of, Last saL€ Anounts of, Last sal.e
When usingthe structstatement,the StructureNameand StructureVariable parametersare optional (althoughboth cannotbe missingat the sametime). StructureNameis usedasthe type for other variables:
With this information,a storecan find out who its bestcustomersare,who the mostrecentcustomersare, or the storecanquery other parameters. Oncethe storehasfound the parameterinformationit wants,it hasall the other personalinformationimmediately availablein the structure.In Customerlnfo,note that I usethe previouslydefinedstructCDate asa type of one of the variablesin the struct;you can imbed structs into other structs.Thisis an effectiveway to make your applicationeasierto read andwork with. In the previousexample,you might be thinking that the structurecould easilybe built for a singlecustomer, but how would it work for multiple customers?Like numberscan be built into arrays,so can structures.For example,if a storehad 2,000customers, an arrayof Customerlnfowith 2,000elementscould be defined usingthe statement:
Structsurertc'e
cuslomerlnfo
SlructureName st'ruct ctype valiab1e1Na$et ctyp€ valiable2Namet
I
(
siructurevariaure;
Variablet
Structuresare initializedin declarationstatements in the sameway arraysare initialized,with valuesbeing appliedto the appropriatevariablewithin the structure in the sameorder asthe structureis declared: StructureTEe Variable VariabLe2Namevalue.. .)t
[2000] t
In the followingprogram,I havedefineda 20-element anay of a structurein which a valueand the initial arraypositionare storedand then sortedusingthe samebubblesort methodthat wasusedin the previous experiment:
{Variabl€1Naneva1ue,
Finally,variableswithin a structureare accessed by connectingthem to the structurenamewith a period as in the followingstatement: SturctureName.variablelNane
CustonerDatabaae
= 47t
As I saidat the start of the experiment,structures allow multiple piecesof data to be includedtogether.A typicalapplicationcouldbe in a databaselistingnames
#incluale cBtrctsort.c /t Bubble Sort
-
Structure
This Program is a sinple 20 Values uBing a'I array
Baseal C Ploglam
"Bubble of
so!t' Struceures
of
nyke preilko 0{ .08.03 Eartlware NoteB: This Program has been wlitten the MPr,ar rDE simuLator oNLY.
Section Four C L a n g u a g e F e a t u r e s
to
run
in
unsigneal i. jt ={33, 5{, 42, L2O, 37, 5, char hitvalueal2o] 99, 105,8,21, 100,33, 41.,77, AL, 69, L3, 46. 51' 90)t strucb Datagtruct { unsigneal ltritPos, char valuei Te$)t ) SorlAl.layt2ol,
//
Datastruct
T€lnpt
Sorts Position
//
Initial
//
20 El€ment Structure Asray TenDorery Value aa strjucture
//
nain ( )
t t l
for (i = 0t i < 6izeof (hitvalues), = i; soltArray I i ] . rnitPos = Inilvalues .value SorlAffaylil til iof ll ,
L'J , t"{
lJ rrq
(i - 0t i < aizeof for !!€ru) = SortAllay Ii I t wbiLe(1 \
{ J
$
{
//
== 1)t
( Inl.tvaluea)
//
FiniEh€dloop
lowHigh
atruct
L5 Bi.t- value Bit valu€a
I/
8
aa two
Lt Hi
char char
unl.on
(
//
{
lonlligh int it ) tr,
variabl€ as 8 Bit valuea
16 Bil
2x
or
bt
Normally, when you are reading and writing the full 16 bits,you would definethe integern asfollows:
t
(1 = 0r i < aiz€of (Initvalues), i++) for - (i + 1))t for (i = 0r i < (sizeof(rui|alues) j++) (sorlArrayljl.value + > soltArlaytj if 1l .value) { Terfr = SortArlay [j I t = sortarraylj + 1lt sortAlrayljl + 1l = l'€tw|i SortAlfaylj ll fi l
b"ri
'r'"c
i++)
the samememorylocation.For example,if you had a 16-bitvariable(ctypeint) and wantedto accesseach byte individuallyasseparatebltes or togetherasa 16bit integer, you could define a structure breaking up and a union as:
r i++)
Fo!€ver
n.i
= 123{5,
s al'e !6
ll
Bit
value
iu
'n"
To accessthe individual bytes of n, you could use the followingstatements: Bylevariabl€ Bytevariable
= n.b.Ht = n.b.Lt
which seemvery cumbersome, but they are equivalent and often much more efficiently implemented than thesestatements:
ErLd. cstlclsort
In cstrctsort,note that I treat the entirestructure like a simplevariableand copy it in the samemanner as I would with a simple variable.This feature helps to keep the complexity of an application to a minimum. Therewill be timesthat you will want to sharedata in a structure (or accessit asif it were a different variable).This is done usrngthe union stqtemenl.The union statementhasthe samesyntaxasthe structstatement andproducesa new datatype.But insteadof each valuewithin the union beingunique,eachis locatedat
Bylevariabl€
= n.i
/
255i
//
By!€variabl€
= n.i
4 256:'
//
Return the High Blrt€ of "n" Return the Low B1.t€ of "n" aa uodulo 255
Structuresand unions are not programming tools thal you will usea greatdealto programmicrocontrollersin C; they are usuallyrequiredfor large-system programming.Despite the apparent lack of applicability, they are useful tools and keeping them in the back more oI yourmindcouldmakeyour programming efficientor easierto read and follow.
29-Pointers and Lists Experiment Two programming conceptsseemto strike terror in the heartsof computersciencestudents:working with pointers and working with lists.The conceptsthemselvesare not terribly difficult to understand,but implementing them in a prograrn and debuggingthe program can be difficult and frustrating; so difficult and frustrating, in fact, that many people question their understandingof the concepts.Philosophically,using
F
t {
nt b*4 t.4 l - I
76
l,e3 PICo llCu Exoeriments fon the Evil
Genius
pointersin programsis curently out of favor.For example,JavaandMsual Basicare designedto hide the operationof datapointers.But in C, understanding the basicsof pointersis criticalto understandinghow to manipulatecharacterstrings.Lists are generally considered a "mainframe"compulerprogramming conceptfor handlinglargeamountsof data,but they do havesomeusefulpropertiesthat you may want to considerin microcontrollerapplications. If you wereto guessthal a pointer is a variablethat pointsto the locationof a data object (vadable,struct, or union),you would be correct.Like other variables, pointersare typed,with the asterisk/splat character(+) usedin the declarationafter the type to indicatethat the variableis a pointer to a specifictype of data.For example,a pointer to an integerwould be declaredas: intr
IntegerPoint€!i
DecLar€ Pointer
//
an Integ€r
The ampersand(&) characteris usedto indicatethe addressof a variable.Tostorethe addressof a variable in IntegerPointer, the followingstatementwould be used: = &it
IntegerPointe!
//
IntegerPointer points to =variable <\#3{>.i<\*34>
The valuein the variableindicatedby the pointer canbe accessed by placingan asterisk/splat in front of the variablein a statement.In both of the following statements, the contentsof the integeri (whichis pointedto by IntegerPointerusingthe previousstatement) are incremented. i = i + 1, *IntegerPoj,nter
= *Int,egetpointer
+ 1t
When pointersare usedwith structures,the values withinthe slruclures areaccessed by usingan arrow madeup of a dashand a greaterthan sign ( ->. ) insteadof the simpledot,or period,of a structvariable.Creatinga structvariablewith a pointer to it and assigninga valuewithin the structureusingthe pointer would be accomplished usingthe followingstatements: struct in! int
PixelPoint
{
//
Pixel
information
xt yt
) PointvaLue; Pi.xelPointr
DtrPixel
ptrPixelt
= &Pointvaluer
//
//
Pointer to inf,orma!iod Point to Structure
Pir{€l structure
the pixeL Vari.abl"e
DtlllPixel->x
= xPositiont
AaBigtL a VaLue to lhe "X" coordlinate
//
Pointersand pointersto strucluresare often usedas parametersto functions.By passinga pointer rather than a value,the originalvaluecanbe changedand much lessdata canbe transferred,resultingin faster programexecutionand smallervariablememory requirements. This is really everythingthereis to know about pointers-in conceptthey are quite simpleand easyto understand.Debuggingprogramsusingpointersis generallydifficult becausefew simulatorsand emulators providepointer informationin any kind of meaningful context(suchaswhich variablethey are pointingto). To effectivelydebuga programthat has pointersin it, two thingsare required:a goodunderstandingof how variablesare stored(and where,most likely,they are in the variablememory)and some imaginationin trying to understandhow the code works.In the next experiment,I will showhow pointersare usedwith charactersand strings,but for now you know all the basicsand probablymore than you will needfor the foreseeable future. Lisl.rconsistof structureswith pointers,which point to the structurebuilt into them.They allow each instanceof the structdata type to point to another instanceand to form a linearchainof structs.Thetwo lypesof listsmoslcommonlyusedin programming (seeFigure4-3) are singlylinked listsand doubly linked lists.The advantageof the doubly linked list is that it allowsmovementin eitherdirectioneasily,while the singlylinked list allowsmovementin only one direction.The end of the listsare usuallymarkedwith a null (value0) or -1. Other waysexistfor organizing structures. For this expedment,I wantedto sort the sameselection of numbersasusedin the previoustwo experiments.Here we will usea singlylinked list.The code itself,which follows,is not muchmore complexthan the codeof the previousexperiments, but I experienceda numberof challengesdebuggingand confirming the application'soperationthat would make this experimentunreasonablydifficult for an inexperiencedprogrammer. *incluale cpstrctsort.c /* BubbLe Sor!
-
Structure
This Program is a simple pointerB 20 values using S!ructurea rryke predko 04.08.03 tlalabrare Notes: This Proglaft has
been
5ection Four C L a n g ua g e F e a t u r e s
Baaed C Progran
"Bubble to
writtelr
go!t"
a Irink€al
to
run
of tist
of
in
7'l
Curren!
l:lrffi Doublv
,
--l T--.
while(l
l-.-__-l ,
ListPointers
th€
Lists
MPITAS IDE Sinulator
ONLY.
it unsigrlefl char hitvalues I20l ={33. 54. 42, r2O' 37' 5, 41, 69, 13, 45, 99, 105, 8, 21, 4OO, 33, 4L,71, 51, 90) t atruct sErucl char
(
Datastruct Dataslruct*
N€xtDr
//
hitElementt
//
ehar vaLuet ) SortA!ray[20],
Slartr
//
gointe! to the Next Element Initial Elenent
20 Ele';nerft Structure Afray/S!art
Previousi
//
C1ftte':t,
//
Enalinqr
//
Pleviou€ Pointer vaLue Pointe! Current value Poinler to the LaEt Elemenl
main ( )
t Start.Ner{ED
// fr
Enaling = Currentt , / / eralrw
iiii""ffi Figure q-3
= current->NextsDt
= &SortArraytolr//
Point start IJist < sizeof (Initvalues) r .NextD = &SortAlrayti+1] = ii . hitELem€nt .value = hitvalueE [il
(i = 0r i for SoltAllayIi1 soltA].lay [i] soltArlaytil // '.of J SortArray t 19I . N€xtD = (structs Endling = SortArlay[19],NextDt
to of
//
//
== 1);
Move Bach
//
the
FiniBhealEooP
Pointer
Forever
EtLd. cpEtrctsott
Although buildingthe singlylinked list is quite simple and can be found in the first for loop,sortingthe list by movingpointersis not exactlyobvious.In order to sort the list,I usedthe Previouspointer asan anchor to the list and then movedthe pointersasshownin Figure4-4.When I developedthe code,I madea diagramsimilarto Figure4-4 to make surethat I understoodhow the pointersweremovingthe two list elementsasin the bubblesort swap.Despitemaking this diagram,it wasstill a challengeto get the program to work properly.I endedup makinga spreadsheet with everyelementand eachpointer and kept track of how they changedandwherethey endedup pointing. Overall,writing and debuggingthis applicationtook me aboutfour hours,whereasthe other sort applications presentedtook Iessthan an hour. The puryoseof this experimentis to demonstrate how pointerscan be easilycreatedand point to different piecesof data.Lists are generallybestsuitedfor largeapplicationswith many data elementsthat might be reordered.inserted.or deletedat random.At first glancelistsmay not seemto be appropdatefor microcontrollerapplications, but there are caseswherethey are useful,suchasallowingeasyeditingof a robot programsequence. I suggestyou considerthe list concept whenyou havea situationwhereadding,removing, andmovingdata elementsis required.
the the
i++) t
(
P.evaous
t
Datastruct*)
-1,
Previous
]tr'hiIe (start.NextD = &sEatEt Previous
!= Endins) t of, to lhe Start // Poinl the Liat = Start.NextDr Current // Point lo the First ElernenE (current.->NextD lrhile != Enaling) - >NextD- >value ) { (Current->value > culrent if = Culrent->llextDt Previoua->NextD = Culrent->NextD->NextDt Currenl->NexlD Pr€viou6- >NextD- >NextsD = Cutrent, = Previoua->NextD; Previous Nothing Changeal, Goto lilext // ) 61ae { = Currenti Previous
78
Ial
Previous Current Previous P€vious.>NonD> NenO =
Figure Q-Q
P I C @l l C l JE x p e r i m e n t s f o r
List sort
the Evil
Genius
ExFeriment 30-fharacter 5trings char*
Ne$rName1, Ne$rl{ame1
NewNane2
t
= lilyNalnei
- &M]'Nametol;" NerdNane2
Although working with structsand unionscanbe difficult,working with pointersand characterstringsreferencedby pointersis quite easyif you follow the basic conventionsoutlinedhere.Unlike other languages (suchasBASIC), C doesnot nativelyhandlestringsof data.Although it canhandleindividualASCII characters,which are treatedlike eighfbit numbers,each ASCII characteris storedin an arrayelementto create a characterstdng.Toeasethe workload causedby copyingeachcharactereachtime it is used,the starting addressof arrayscontainingASCII characterstringsis normallyusedto referencethe entire string.These methodologiescombineto make working with character stringsin C more complexthan in other languages you may haveusedwhenlearningprogramming.The sameattributesandmethodologiesmake character stringsmuchmore efficientwhenyou are comfortable working with them. When a numberofASCII charactersare combined in a string,they normallyend with a null (zero)character to form what is known asan'ASCIIZ strins."The p l a c e m e no lf t h en u l lc h a r a c t eart t h ee n do [ t h es t r i n g is automaticwhenit is enclosedin doublequoteslike this: char
Mtalame t121
= nq'ke
predlkotr r
//
Def.i')e
a
;;-;;.--*' To declareenoughspacefor the stringand the null characterat the end,you will haveto count the number of expectedcharactersof the stringand add one to it. When a stringvariableis referenced,it is referenced by the vadablenameandit is a pointer to the first characterin the variablearray.
== ilflilil:l
Eachindividualcharacterin a stringis accessed as an arrayelement.IndividualASCII characterscan eitherbe representedasdecimal,binary,or hex numbersor the actualcharactersin singlequotes.In the following codesnippet,the third characterof MyName is comparedagainstupper case'K'.
// //
(NevNar$elt2l == rK' ) if Stalements executeal if Equal to Uppelcase elae .K, Sla!€llrents ex€cuted if Not l4)pelcase
rK,
Along with decimalrepresentations ofASCII charactersand the actualASCII charactersin singlequotes, a numberof specialcharacters(precededby a backslash[\]) are alsoavailablein C.Thesecan be placed eitherin singlequotesasa singlecharacteror aspart of a stringlistedin Table4-3 and found in the "For Consideration"pafi of this section. Dependingon the circumstanceq ASCII stringscan be locatedin eitherprogrammemoryof variablememory.To allow the compilerto differentiatewhich is which,the "constkeyword" shouldbe put beforethe charin the pointer declaration: const
cha!+
ConstPointeri
The constkeywordwill make the pointer 16 bits long (insteadof the standardeightbits,which can accessonly variablememory).The extrabits are used to indicatethe locationof the pointer data aswell as the locationwithin the specifiedmemory.My rule of thumb regardingthe useof the constkeywordis to let the compilerindicatewhenit is needed;mostof the time it is not required. To demonstratehow stringsof charactersare implementedand manipulatedasarraysof singlecharacters, I havemodifiedthe sort programto sort an aray of pointersto strings.I createdthe stdngCompareand stringcopyfunctions,which perform byte-by-byte operationson the bytesin the strings,becauseC does not havethis built-in ability.
5ection Four C L a n g u a g e F e a t u r e s
79
#include cslrIlsolt.c /*
sifiD1e
Bubble
C Program
(i = 0r i < 10, t++) fo! for (j = 0r j < (10 - (t + 1))r j++) gortvaluea (atringcdE a!€ ( (char*) lf [j], (cha!r) + 1l) > 0) { soltvaluestj SortVaIu€B [jl ) t stringcoDy(TenD, + 1l)t atrinqcolDr(SorlvaLuea [J L Sor|alu€stj ( Sorlvalu€e !!eq>) t sEringcopy [J + 1]' // EL I
Solt
"Eubble Sortd of ThiB Proglam is a simple 10 Fou! chalecter Stsringa b!'moving them functions iD the solt arlay. fhe atring w€re wrilten bY Myk6 Pr€alko. nvhe pretlko 0{.08.05
!'hi1e
Earatware Not€B: Tlris Program hag b€en !h€ I.IPITAB IDE Simulator
u! St l-{
"r{ H
?n
jt unsigled i, sorlvalu€a char* char T€alI) [5] t cha! nameo [5] cha! name]. [5] char nam€2 [5] char name3 [5] cha! nam€{ [5] char names [5] char nrme6[5] char nam€? [5] cha! nameg [5] cha! nameg [5] int
F.{
| writlen ONIY.
to
run
E c = = = = = = = =
Etllngcorq)a:.e
( char*
{
slringl,
//
chat*
gt!lng2)
cd|tr)are two Strl.aga
i n t j = 0 ,
(i = 0r ('\0' l= Sttiusl.lil ) && i++) - strins2til, j - stsltnsltil // j < 0 ff, S!!ing]. // j = 0 if stringl. // ) > 0 if strins2
for
4J t! ru p"{
ru "Li F \
return ,
//
Striag].t0! for (i stlingltil ,
ll
Return
1,
he
< string2 = string2 > st':.ing2
t SorlveLuea [0] Sortvaluea [1] Sortvalues [2] sortvaluea [3I Sortvalu€s [{I sortvalu€s [5] sortvalueB [5] so!tsva1u6a [7] gollvalueB [8] sortvaluea [9]
= = = = = = = = = =
nam€ot na.nelt aame2, narne3, n€$€4t nane5 t nam€5t nam€7t nam€8t nam€gt
Errd. cEtlmgort
*incLudla cstrDsolt.c /*
sil[I,le
c Program
Bubble
So!t" llhis Proglem la a ai!E)1€ "Bubble with novlng 10 Four Cha:.actse! Stringa atrings.
lilotea: llartlwar€ Progran has b€en l|rl'!t€n fliis o$[Y. "n" ** IDE Sirmrlator
stringl
Byte
to
*,
char* charr cha! cha! cha! cha! cha! cha! char char char char
SoltvaLuea TettE)i narreo t5j = nenel [5] = n€me2 [5] = neme3 [5] = neltr€{ [5] = = nene5[5] . name6[5] Dame? [5] = '1ame8 I5l 5 name9 [5] =
[10] t "mtk6"t ntoDin' 'lolin' trcalarri njune" n lf'tlntr ' ulrar1rn' "ryra"' trsara'r "kira"
P*
&€4 80
Fo!€ver
sorl of
!vk6 Dr€alko 04.08.0{
= String2 [0] r // Cor4, E}l.e t.ilsl .\0, - 1lt i++) != Stringlli = sErins2 [i],
E!.d. stringco9y
FinisheauJoop
In the programyou'll seethat I first initialized arraysfor eachnameand then passedthe addressof eachnameto the SortValuesvariable.In standardC, you could initialize a pointer variableto a seriesof double quotedASCIIZ strings,but this is not possible in the PICC Lite compiler.I suspectthat the reason why it's not possibleis due to the memory organization of the PIC MCU; the initial valuesare storedin programmemory,which is completelyseparatefrom the variablememory.Before a variablepointer can be assignedto a value,the value must be storedin a variable. After writing cstrmsort,I noticedthat I could improve the performanceof the sort routine by simply movingthe pointersto the stringsin the sort instead This programis of copyingthe stringsthemselves. listedhere:
ConrDare ReEull
cha!* strl.ng2) stsfing1, into I / coDy stltng2
nain ( )
#
(0 == j),
E'l'd atlingcotDpale
EEringcoDy(clEr* I
iI
Cry
//
j;
//
in
[10] t trnvketr, trtonLn' trLofi" trcaren' trjulent n].r.ann' n$aryn' ilr\ylent trsalan' nkiren'
//
( 1 == 1) t
1 , 2 3 P I C @l l C U E x p e r i m e n t s f o n t h e E v i l
6enius
run
in
lnl |
(ctla!*
alringcorq)are
Stringl, char* // contr'ale two
String2) slllngs
for
i n t j = 0 , for (i = 0, ('\0, !- srrinslttl j - slrinsltll - strins2lilt // i < 0 if // j = 0 tf //j>Oi-ES r€lurn
!!aid(
t++1
strinsl < Sl!1ngl2 = String2 strinsl t r i n g 2 > String2
R€tsutn CdlDare Result
Eird. slringcon[)are
//
I
//
Jr
) && (0 == i ) ;
unaigneal
i,
Sorwalues Solwaluea Soltvaluea Soltvaluea goltvaLua3 goltvalueE gortvalueE Soltvaluea Soltvalues Sortvalu€a
jt [0] [1] [2] [3] [{l [5] [6] [7] [8] [9]
= = = = = = = = = =
= 0r i < 10r i++) (i = 0r i < (10 - (t + 1))r i++) (Btringcompa!€ ( (chalr) if Sortvalues (char*) Soltvalu€s tj + 1l) > 0) T€d|D = Sortvaluea [j I. = Sortvalueslj Sortvaluealjl + 1]t gorlvalues [j + 11 = TerD; | // fi
whiL€(1
ll
!
== 1)t
//
Finiah€alt
tJ 1, (
nam€o t nalne].t name2 t nane3t nalle4t narlesi aam65i nar€? t aameSt aame9i
. . . . .
m lt:
{*
ooD Eorev€r
t-J "
ErLd cstrpsort
The updatedversionof this sort is recommended and demonstratesthe important functions of pointers that you shouldbe comfortablewith in order to program in C.To recap,thesefunctions include the followrng:
)
t
(t for
Declaringpointers Assigningpointersto the start of variable stnngs Accessing(readingand writing) pointer values Defining ASCIIZ strings AccessingspecificcharactersinASCIIZ strings as array elements
d\
r*d
r t i
t-l
r*" 9,, ! i F
Experiment 31-LibrargFundions
tsd
t"/ with strcmp and strcopy,respectively,and added the string.hheaderto get the following: *inclutl€ #iaclutl€ - SirE)le cstrf,Sorl.c /*
q F"t
C Program
Bubble
sort ! d
nBubbl€ Sortn of Ihis Program ia a siq)Le 10 Four Chal.acle! SlringE blr noving them in lhe soll array. CdE)arison anal litovemeDts ar€ provial€al by l"ibrary Funclions.
In the previous experiment, I showedyou how to compare and copy eachbyte in an ASCIIZ variable array. Klowing how to create thesefunctions in C is important,but it is not alwaysnecessary for mostapplications.As part of the C languagespecification,you can take advantageof a collection of functions that will take someof the load off you when you are programming.Thesefunctions (along with the PICC Lite compiler C languagestatement definition) are included in the "For Consideration"part of this sectionand are part of the "C run-time" library that is linked with your application at run time. For example,I replaced the stringcompare and the stringcopy functions in the previous experiment's code
X
llyk€ prealko 04.08.05 Harflware Noles ! ThiE Progr€m has been th€ MPLAB IDE ginulato!
j, u.Eaig!€d i, char* SortvaLu€s char TerDIr[5] t char nameo [51 char nam€1[5] = char name2 [5] = chat nam€3 [5I E char nam€4 [5I char nan€5 t5l = = char !€.ne5l5l
Fr.
wrilt€n to ONLY.
run
in
[10 ] t "!oni" nlorinr ncaran'june"t nltrnntr "nar't'".
SectionFour C L a n g ua g e F e a t u r e s
dI
- '4yran t = rrsaratr t = "kira",
narLet [51 nameS [5] name9 [5]
cha! cllar char
For Eonsideration
nain ( )
(
Sortvaluea sortvalueE sorwalu€a sortsvaluea sortsvalu€a Sorlvaluea soltvalu€s So:atvelu€s Sortvalu€a Sortvaluea
[0] I1l [2 ] [3] [{l [5] [6] [7] [8] [9]
= = = = = = = = = =
nameot 'rameli name2t naltre3t nalle4 t namest name5t !a!re7 t lr€lneSt aame9t
for (i = 0r i < 10r I++) for (j = 0t j < (10 - (i + 1))t j++) (sllclE)( (char* ) Sorlvalues ljl, if (chai*) Sorlvalues tj + 1l) > 0) ( Sortsvaluea [j I ), strcDy(T€dlp, strcDy(Sortvalu€a tj + 1] ), [j L Sortvaluea strcpy ( sortvalu€a t j + 11, Teqr) t ll fi | !thile(1 |
l, .,-t P EIJ
t+
at l.Lt
ls
"*t r,J 3*t
//
== 1),
//
Fini
ahefltJoop
Foreve!
EE.d. cal:.fsofl
The resulting program takes up just about asmuch spaceasthe previous one and runs in roughly the same amount of time, which meansthat my routines are similar in efficiency to the provided library routines.The big difference is that the first program was shorter and required lesseffort to debug.(I assumethat the strcmp and strcpy functions work properly and this assumption is extendedto all the built-in functions of the runtime library.)For the mostpart, I would recommend that the run{ime library functions are usedin your C programswhereverpossible. One caveatexiststo the previous statementand that is the linker brings in only the library functions that are calledby the application.Ifa functionis not called,then the function is not linked into the final application hex file. I'm pointing this out becausein you canvery quickly smalldevices,likethe PIC16F684, use up all of your available spacewith libraries and applicationcode.It is importantto rememberto balancethe number of built-in and user-written functions so you don't useup the programmemoryavailableto your application.
f l
H
For modern systemgC is the programming languageof choicebecauseit is availablefor a wide rangeof systems and processors(including the PIC microcontroller). This ubiquity requires anyone who is planning on developingan application for processingsystemsto have at least a passingknowledge of the language.The following information is specific to the HT-Soft PICC (including the PICC Lite) compiler: Application mainline/entry point is the main function: nain( ) // ADpltcaEton {
Coile
|
// ll
!
Codle
N)plication
E'rd ApDllcatiorr
Functions are defined in a similar forrnat to the main function: Frnctlon( R€turn_Ttz9e Parameter. . J) stsalt. { // nrdctioa .
// leEuln
|
TtT)e Paramet€r
//
zunction
T]ZI)e
Coal€
valuei
EnA l\tnction
The function can be placed before or after the mdn function(not inside),but if it is placedafterward,there must be a function prototype, like this one,before main: Retu!n_T!'D€ l,lractl.on( Paramete!..1),
llyl)e
Peraneter
[,
lPt pe
PIC MCU configurationregisterfusevaluescanbe specifiedusing the "_CONFIG(x)" define (found in the pic.h include file). The specifiedvaluesare ANDed together to form a complete configuation register value. I recommend that a value for eachbit be specified to ensureproper operation of the microcontroller. Table 4-1 lists the PIC16F684'sconfiguration fuse bits, the HT-Soft defined constant'soption values,the AND valueq aswell asthe Microchip defined assemblylanguageconstantsI havenoted alsorecommendedvalueswhen I felt it wasimDortant.
e&{ 82
[,
l , e 3 P I C @I I C U E x p e r i m e n t s f o r
the Evil
Genius
Data declarationsare very consistent,starting with the constant declaration: coaat inr tJabel = value, ., vanaDtesoeclaredInstdea Iuncfion(rncludlngthe main vaiable) are known as local variables,are accessibleonly within that function,and may be different upon entry into the function. Variables declared outside of all functions are termed,global, as they can be read and updated anywherein the application.
where the last characteris an ASCII null (0x{00). Array dimensionsmustbe specifiedin the variable declaration statement.Multidimensional arrays are defined with eachdimension separatelyidentified in squarebrackets([ and]): int rb'eeDspac€ [Din1l tDn!21t pointers are declaredwith the asterisk (*) character after the variable type: char*
tlzp€
rra.t€l
o rt
o o 5
u f-r.
glrinq'
p-
t= valu€l,
Valueis an optional initialization constant.The different types are listed in Table 4-2,with the data value rangesare in parenthesis. Single dimensional arraysare declared using the form:
qt
o
Finding the addressof the pointer in memory is accompliJred using the ampersand(&) character:
rj 9' cF
EtsringAda!= &strins,
,J.
ll'I)e Labeltsizet
[= { hitialization
o
values..}lt
5
Strings are defined assingle dimensionalASCIIZ uuTays: char
striDgl
17 I
= "I'his
is
a gtridg"t
Table 4-1 PIE'l6F58qConfiguratlonFuse Values Connguration Bit
PICEUte CompllerValue
Microchlp Value
Ualue-Functlon
Bit 11-FCME\ Fail-Safe clock Monitor Enable FCMEN (Default), FCDIS (Recommend)
_FCMEN_oN -FCMEN_oFF
0X03FFF,0X037FF
Bit 1o-IESO,Intemal Extemal switchover
_IEso_oN
0X03FFF,0r03BFF
Bit 9|8-BODEN, Blownout DerectEnable 0x03DFF,0x03CFF
IESoEN (Default),IESoDIS
(Recommend)
_IEso_oFF
BOREN (Default),BOREN_XSLP, SBOREN,BORDIS
_BOD-ON _BOD_NSLEEB _BoD_sBoDE\_BoD_oFF
0X03FFF,0X03EFF.
Bit 7-CPD, Data Memory Protect
UNPROTECI (Defaulr/Rec), CPD
_CPD_OFF,_CPD_ON
0X03FFF,0X03F?F
Bit 6- _CP, Program Memory Protect
UNPROTECT (Default), PROTECI
_CP_OFF,_CP_ON
0X03FFR0{3FBF
Bit 5-MCLRE, Extemal _MCLR Pin Enable
MCLREN (Default), MCLRDIS
_MCLRE_O\
0X03FFR0X03FDF
Bit 4-_PWRTE, Power Up Timer Enable
PWRTDIS (Default), PWRTEN (Recommend)
,PWRTE_OFF, _PWRTE-ON
0x03FFR0rt3FEF
Bit 3-WDTE,Watchdog Timer Enable
WDTEN (Default), WDTDIS (Recorffnend)
_WDT_O\
0X03FFF,0x03FF7
RCCLK (Default), RCIO, INTCLK, INTIO (Recommend), EC, HS, XT, Lp
_EXTRC, _EXTRCIO, _INTOSq _INTOSCIq _EC_OSC,_HS_OSq _XT_OSq _LP_OSC
Bit 2:0-FOSC, Oscillator Selection
_MCLRE_OFF
_WDT_OFF
S e c t i o nF o u r C L a n g u a g e F e a t u n e s
0X03FFF.0I{3FFE. 0X03FFD,0X03FFC, 0X03FFB,0X03FFA, 0x03FF9,0x03FF8
83
Table4-3 C BackElash Eharacterg
Table4-2 PICELlte EomDilerBata TgFeg Tcpe
Btt Size Comments
bit
1
BooleanValue
8
lnteger (-128to ASCII Character/Signed
char
unsignedchar 8 short
16
unsignedshort 16
rn)
Eharacter
nSC Value
FunEtion
\0
00x00
Null Character
0x007
Alert/Bell
0x008
Backspace
0x009
HorizontalTab
0x00A
New Line (Line Feed)
0x00B
Vertical Tab
0x00C
Form Feed(New Page)
0x00D
Cariage Retum
0x05C
ASCII BackslashCharacter
0x03F
ASCII QuestionMark
0x027
SingleQuote
0x022
Double Quote
\b
unsigned Integer (0 to 255) 6'7) SignedInteger ( - 32,768to 32.'7 UnsignedInteger (0 to 65,536)
int
16
SignedInteger (-32,768 to 32J67);sameas short
unsignedint
16
as UnsignedInteger (0 to 65,535);same unsignedshort
long
to SignedInteger ( 2,147,483,648 2,147483,647)
unsignedlong
UnsignedInteger (0 to 4294,96'l,295)
float
assume3 digitsof Real (0 to 1/-6.81(1033); accuracy/defaultfloating point mode
double
assume 6 digitsof Real(0 to l/-6.81(10'3): usingPICL -D32 compiaccuracy/specilied lation option
\f
\?
Mathematical operatorsinclude the ternary operator and thoseshownin Table4-4 andTable4-5. The ternary operator is the form: TestE
Calculatingthe addressof a specificelementin a string is accomplishedusing the ampersand(&) characterand a stringarrayelement: Strinssterts
= &Striagtnl,
The variable'stype canbe overridden,or cast,by placing the new tlpe in front of the variable in brackets: ( long)
'r{ fta
tl q,
StrtngAaLl!
= 0rr0123450000t
The C assignmentstatementis in the following format: variable
= E:lplesEioat
variablevalues,or Expressionscanbe constants, mathematicalstatementsin the format:
(J
'd
o r l
or Constantscanbe decimal,binary,hexadecimal, ASCII charactersenclosedin single quotes.Table 4-3 liststhe specialbackslashcharactersthat canbe placed in single quotes so they lvill be evaluatedassingle Note that a singlebackslashcharacteris characters. interpr€tedasa line continuance.
$4 w f:.t
and executesin the following manner: ifTestExp is not zero,then Expl is evaluated.IfTestExp is equalto zero,then Exp2 is evaluated. The binary operatorslisted in Table 4-4 can be simplified to the modified equalsstatementif the destination variable is one of the parametersof the expression. Table4-6 liststhe resultingcompoundassignment statements C decisionstructuresincludethe ifstatement, if
(E qr!€sBion)
{ // Ex€cut€ ) ela€ ( // Ex€cut€
[(..1
if
&q)reEaion
ia
no!
if
E qtlession
ia
zelo
( "f,als€"
(E .preEsion)
t // ,
E:tecute whil€ eLlhv ll
E)q)toaaion
i€
aot
zero
("true')
and the for statement, fo!
( initialization,
LooD
E:.DresBioni
{ Execute
!"hile
ltt€
E:rpleasion
is
not
)
84
)
the while statement, while
[(..1 variable I Constant topelator variable I colEtsant I[)..1]
: E
? E:gt1
l , e 3 P I C @I ' l C UE x p e n i m e n t s f o n t h e E v i l
6enius
Increment zero
)
Table4-4 E Binarg0peratorg
Table 4-5 C lJnarg Operatol-s
Dpepto, Pnonry Flltctio?
Operator Function
*
r )
Highest Multiplication
2'sComplement negation
Division
"/"
!
Logicalnegation(Return zero if valueis not zero and retum not zero ifvalue is equalto zero)
{
Addition
<
Bitwisenegation
S
Subtraction
11
Incrementvariablea_f?rexpressionevaluarionif on the vadable'sright-handside;incrementvariable
fs ;
Modulus
+
Shift Left
belbluexpression evah",i."ii"" irt" r".i"ilr" rlr,
Shift Right
handside)
I€ss-thancomparison(Return not zero if true,zeroif false)
Decrementva ablearel expressionevaluationif on the variable'sright-handside;decrementvaiiable beloreexpressiirevaluationifon the variable'sleft-
Less-thanor equalscomparison(Return not zero if true,zero iffalse)
Lowest
) while
f}J 1 {S t{
creater-than (Returnnotzero comparison if true,zero if false) (Rerurnnolzeroi[ Fquafs-to comparison true,zeroif false)
Table 4-6 E Eompound Fssignment Statement Bperators
r|
Operatot
Function
NoFequals-to (Retumnotzero comparison
O S-{ **
&:
BitwiseAND
if true,zero iffalse)
:
BitwiseOR
BitwiseAND
^
BitwiseXOR
+:
Add to Destination
BitwiseOR
Subtractftom destination
LogicalAND
Multiply destination
LogicalOR
l= '/.=
Divide destination Divide destinationand return modulus
Intheforstatement,multipleinitializationandloop>> incrementstatementsare separatedby commas. Puttingin multiple initializationsand incrementstatements can make your applications difficult to follow To executeconditionally accordingto a value,the whenyou are first programmingin C.To avoidthis switchstatementis used: extra complexity,I recorrmend that you stick to just havinga singleinitialization and loopincremenlwhen "**:lj:T:i::1""' ' you first usethe for statement. trE:q)ression"== nvaluetr " *fi:::*;i For loopinguntil a conditionis true.the doiwhile statementis used: ,, ,r";i3'i!i""' sratsementss are rru€ ato t // Executs€until
m
ru
itwiseXOR &&
#
$*,
-
(Return ,'iT:il:|?1"::;Hii:,:i3iarison
&
LJ
l the E qrression iE zero (',fal6e")
Finally, the goto Label statement is used tojump to
a specificaddress:
(E:{Dression),
To jump out of a currentlyexecutingloop.a break statementis used.Thecontinuestatementskipsover remainingcodein a loop andjumpsdirectlyto the loop condition(for usewith while,for, and do/while loops).
soco r'abeLt Labet:
5 e c t i o nF o u r C L a n g u a ge F e a t u n e s
85
&J.
To return a value from a function, the return statement is used: retuln
Stat€m€ati
Directives are executedat compilation time and usedto modify th€ sourcecode for the application and
Table 4-7 E Directives Functian
Directlve
Null directive;do nothing. #assertCondition
Force an ellor if condition is false.
tasm
Indicate the start of inJine assembly.
#endasm
Indicate end of inline assembly.
#defineLabel (Optional Define a label that will be replaced with the specified text when it is Paramete$) Text encountered.If optionalparameters are specified,instancesof them h the text will be replacedby the parameteN specifiedwhen the label is invoked.
o
"'.{
#undefLabel
Delete the definedlabel.
#line Number ListFile
Specifythe line numberand file name Ior listing.
#include
Load the specified file found in the INCLUDE folder path.
*include"File"
Load the specified file by fi$t looking in the cudent folder and then in the INCLUDE folder path.
#error Text
Forcea compilereror (stopcompilation) and output text for error information.
#warningText
Forcea compilerwarningand output text for waming information.
#if Condition
If the condition is true, passfollowing code to next #else,#elif,or #endii
#ifdef Label
Ifthe label hasbeendefined,then pass followingcodeto next #else,#elif,or #endii
JJ
|6 g 0,
t
CI
o
If the label hasnot beendefined,then passfollowing code to next #else,#elil or #endii
#ifndef Label
This directive is an else/if, and the con" dition is testedonly ifthe previousif directive is not true.
#elif Condition
#else
Invert passfollowingcodestatus.
#endif
End a +tif,#ifdeI, #ifndef, #elif, or #else condition.
#pragmaString ke).tords
Passthe specifiedstring to the compiler (seeThble44).
t'l
are listed in Table 4-7.Each directive is given its own continuesonto the next line by line and,if necessary, useof the backslash(\) character. The PICC Lite compiler pragma options are used by the compiler to changeits operation and are listed in Table 4-8.Note that for the code presentedin this book, these options are not requfued. In the PICC Lite compiler manual, you can find additional information, including error and warning descriptiong information on including assemblylanguageprogramming in C applications,and file format referenceinformation that is not critical to performing the experimentsin this book but may be useful to you. I have not included the list of PICC Lite compiler options in this section becauseyou should be able to successfullyrun the PICC Lite compiler under MPLAB IDE without having to changeany of the operating parameter$ In Thble 4-9, I have provided a cursory list of the library functions that are available in the PICC Lite compiler. I have arrangedthe functions by alphabetical order within the include file rather than by overall alphabeticalorder, asthis should make it easierto find specificand related functions.Unless otherwise specified. assumethat the label is for a function. For more information, you should consult with the PICC Lite compler User'sGulde (available for download at www.ht-soft.com),the .h files in the PICC Lite compiler INCLUDE folder,and standardtextson the C programming language.
Table 4-8 FlvailablePIEELite EompllerPragmaEirectives Pragma OireEtive
Function
interrupllevel 1
Allow interupt functions to be called by main line code.
Jis
characterhanEnableJIS (Japanese) dling in strings,
Nojis
Disable JIS character handling in strings(defaultcondition).
p ntf_check(printf) const Use printf formattingconventionsfor string checking. psect text = newpsecrname Change the object file psect name. regusedRegisters
Specify registers that are used in interruPt handler'
l.l
c
tr* 86
l , E l P I C @l l C U E x p e n i m e n t s f o r
the Evil
Genius
qr o
Table 4-9 PIECLite CompilerLibraruFunctionsand Macrog Library Functlon
Description
conio.h Bitkbhit(void);
Skeleton of keyboard hit function
ctype.h int isalnum(charc)
Macro testing if c is alphanumeric
pic.h
rl
o
int isalpha(charc)
Macro testing if c is alphabetic
int isascii(char c)
Macro testing for seven-bit value
int iscntrl(char c)
Macro testing for ASCII control character
int isdigit(char c)
Macro testing for ASCII decimal digit
itrt islower(char c)
Macro testing for ASCII a through z
int ispdnt(char c)
Macro testing for p nting character
int isgraph(char c)
Macro testing for nonblank printing character
inr iennn.r/.h,r.\
Macro testilg for nonalphanumeric character
int isspace(charc)
Macro testing for space,tab, or newline
int isupper(char c)
Macro testing for ASCII A thrcugh Z
int isxdigit(char c)
Macro testidg for ASCII hex digit
int toupper(int c)
Macro to convertASCII characterto uppercasb
Ft g, ct
int tolo{er(int c)
Macro to conveit ASCII character to lowercase
P.
int toascii(intc)
Macro to ensure parameter is valid ASCIImath.h
double acos(double f):
Retum the arc-cosinein radians of the input value
doubleasin(doublef);
Retum the arc-sine in radians of the input value
double atan(double f);
Retum the arc-tangent in mdians of the input value
doubleatan2(doublef doublex)i
Retum the arc-tangent in radians of the input value
doubleceil(doublef);
Retum smallestwhole number not lessthan f
doublecos(doublea);
Retum the cosine of the radiatr argument
double cosh(double f);
Retum hyperbolic cosine for argument
double eval-poly(double x, const double* d, iDt tr);
Evaluate the polynomial with coefficients stored in array d at point x
double exp(double f);
Retum the value of er
double fabs(double f);
Retum the absolute value of f
doublefloor(double0;
Retum largest whole trumber not lessthan f
double ftexp(double f, int* p);
Brea.l(real number into integer and fraction
double ldexp(double I int x);
Integer is added to real and result retumed
double log(double f);
Retum natural logarithm of f
double log1o(double l);
Retum base 10 logadthm of f
doublemodf(doublef, double* iptr);
Split f into integer and ftaction parts with same value as f
doublepow(doublef, doublep);
l(etum t'
double sin(double f);
Retum sine of the mdia! argument
doublesinh(doublef);
Retum hyperbolic sine for argument
doublesqrt(doublef);
Retum the squarercot ofthe argument
doubletan(doublef);
Retum tan of the radian argument
double tatrh(double f);
Retum hyperbolic tangent for argument
di(void);
Disable intedupts
o p
a F, p-
o
o Ft
eeprom_write(unsigned char addr, unsigned char value); Store the specified byte at the specified addressin the PIC MCU's data memory
stdio.h
ei(void);
Enable interrupts
unsigned char eeprom_read(unsignedchar addr);
Return the byte at the specified addrcssin the PIC MCU'S data memory
unsigned char pdntf(const char* f, . . . );
Standard C print routile; before using sdtout must be defined for application
unsigned char sprintf(char* buf, const char* f, . . . );
Convert C pdntf fomat parametels to stdng at buf
unsignedxtoi(constchar* s);
ConvertASCII hexadecimalstring to integer
S e c t i o nF o u r C L a n g u a g e F e a t u r e s
87
Tabfe 4-9 (continued.) Librara Function
Description
stdlib.h int abs(intj);
Retum the absolutevalue (positive)of the input
doubleatof(constchar* s);
ConvertASCII string to doublevariabletype
int atoi(constchar+s);
ConvertASCII string to integervariabletype
long atol(constchar* s);
aonvert ASCII string to long variabletype
div_t div(int num,int divisor);
Divide and return quotient and remainder
ldiv t ldiv (long num,long d);
Divide and return quotient and remainder
int rand(void);
Retum random number fto/JJ0 to 32,767
void srand(unsigned int seed);
Initialize random numbergenerator
string.h constvoid* memchr(constvoid* block,int val,size_tn); Searchstringfor specificbyte
\J ,"* JY{
time.h
k dt ,.{I l .J
int memcmp(constvoid* sl,const void* s2,size_tn);
Comparetwo blocksof memory
void* memcpy(void*d, void* s,size t n);
Copy n bytesof data betweenpointers
void* memmove(void*s1,constvoid* s2,size_tn);
Copy n bytesunder all circumstances
void* memset(void*s,int c, size_tn);
Fill block ofmemory with specifiedcharacter
char+strcat(char+sl,const char* s2);
Concatenates2 at the end of s1
char* strchr(constchar* s,int c);
Searchstringfor first occuffenceof c
chaf strichr(constchar* s,int c);
Searchstringfor first occufienceof c in upper-or lowercase
int strcmp(constchar* sl, constchar* s2);
Comparetwo strings
int stricmp(constchar* sl, constchar* s2);
Comparetwo stringswithout regardto upper-or lowetcase
char* strcpy(char*sl,const char* s2);
Copy s2into buffer (characteraray) pointedto by sl
char* strcspn(const char* s1,constchar* s2)t
Find numberofcharactelsfrom the start of s1to the part ofthe string that matchess2
size_tstrlen(constchar* s); (char* s1,constchar*s2,size-t n);
Find the lengthof the ASCII stringchar*strncat Concatenaten charactersfrom s2onto the end of s1
int strncmp(constchar* s1,constchar* s2,size_tn);
Comparetwo stdngsfor up to n characters
int strnicmp(constchar* s1,constchar* s2,size tn);
Comparetwo st ngsfor up to n chamcterswithout regardto upper-or lowelcase
char* strncpy(char*sl,const char* s2,size_tn);
Copy n charactersfrom s2 to s1
constchar+strbrk(constchar+sl,const char* s2);
Return a pointer to the lirst instanceofs2 in sl
constchar* strrchr(char+s,int c);
Searchfor characterstartingat the end of the string,rather than ftom the front
size_tstmpn(constchar'r'sl,constchar s2);
Retum the lengthof s1,startingftom the start that containscharacters rrom sz
constchar* strstr(constchar* s1,constchar* s2);
Find the first occurrenceof s2in s1
constchar* stristr(constchar* s1,constchar* s2);
Find the first occurrenceofs2 in sl without regardto upper-or lowercase
char* strtok(char*sl,const char+s2);
Break s1into a seriesof tokens,separatedby s2
char* asctime(struct tm* t);
Convertthe variableofthe tm struct type into an ASCIIZ string
char* ctime(time_t*t);
Converttime in secondsto ASCII string
structtm* gmtime(time_t+ t);
Break down time into type tm
structtm* localtime(time_t*t);
Break down time into type tm
time_t time(time_t*t);
Skeletonoftime read function
{l} T '
t l
t{ 0 88
l , E 3 P I C o l ' l C UE x o e r i m e n t s f o r
the Evil
6enius
Section
Five
Plfl SFEBqMicroctrntrol ler Built-inFunctions
Ptc16F584 tlt31? adjustable age legulator in package Io-LED balg.aph
voltTO-220 dispLay
REd LED Creen
LED
100C)!esistor 330!) res istor 4?0O 10-pin
DMM NeedIe-nose
plie!s 10k breadboald mountable potentj.ometer
Breadboard Wiling
ki.t
Jeweler's
les istor
1 lk bleadboard potentj.omete!
sclewdriver
mountable
2 0.01 pF capacitols 1 Breadboard-mountable Jrur swrEcn (!--5vr1!cIl 8G1903 recomnended)
A big question askedby software developersis whether or not to rewrite an application.The reasons for doing a rewrite are usually good and noble; the author may havefigured out or leamed waysthe application could be mademore efficient, new hardware may be availablethat makesthe task easier,or there may be too many potential errors in the software that only a complete rewrite of the codewill prevent problems in the future. Pcrsonally,I am of the opinion that applicationsshould never be rewritten unlessa tangible reasonexists The question,"what will happen if the changesare not implemented?" hasto be asked,and unlessthe answerincludessomethingabout cost savings (e.g.,the application could be usedin a cheaper nricrocontroller), then the rewrite should not be attempted.This may seemlike an off-topic way to introduce a sectionabout the builfilr featuresof the PIC16F684,but it is surpdsingly relevant becausemany of the builfin featuresof the PIC@MCU introduced in this sectionreplacesoftware functions that you may have written to imDlementdifferent function*
1 9-vol.t
batte.y
1 g-volt
battery
1 Three-cell cl ip
pack
AA battely
3 AA battelies I
Two-cell AA o! AAA battely pack
2 AA o!
AAA batteries
The builfin featues of the PIC MCU can make your applicationa /ot smaller,easierto write,and easier to debug.For example,in Section 3, I introduced an application that displayedan incrementing binary value on the eight LEDS of the PICkitrM 1 starter kit. It did so by sequencingtbrough eachof the LEDs simultaneouslyto give the impressionthat they were all on continuously,when in fact no more than one
89
LED was on at any given time. I feel that the code was fairly clumsy and unnecessarilylong.The length made it very difficult to follow valuesfrom top to bottom, and assuch errors had a good chanceto make their way into the different statementsof eachgroup of statementswritten to optionally tum on an LED.
U,.
, j
r ! l
f
0.4
'.l
&E r t taEr
D0-D7
of
aE a!
"CPKLED.C" aa a bas€, cycl€ each lhrough Using LED6). LED at 100r( p€r Eecondl (1250 ua betw€er lrhLch ia rewrilten i6 th€ geconil v€rsion fhiB lo leAuce the amounl of Arrays take aalvanleg€ b!| th€ aDplicatsiolr. space lequireal
to of
tni'k€ Drealko 0,r.09.12
& IID|TDIS & PI{RTEN & IICIJRDIS COIAIE(IN'IIO IINPROIECT \ & IJNPROTECT & BORDIS & IESODIS FCMDIS ) ,
& &
qrl
k{ qs r€ f l H
= 0, in! value int Dlay = 65i // LED Tine on DelaY variable cofls! char PoRTAvalue [8] = {0b010000, 0b100000, 0b010000.0b000100, 0b100000,0b000100, 0b000100,0b000010], 0b001111, coasts cbar TRISAvalue tgl = {0b001111, 0b101011,0b101011, 0b011011,0b011011, 0b111001' 0b111001) t const char NOIPORTAI8I = (0, 0, 0, 0, 0, 0, 0, 0', nain
()
t
I!
F
EORTA = 0, Cl'tCONo = 7t AI{SEL = 0,
ll //
Tlt!'j T)n
j
//
ReE€l
//
I,oop Foreve!
= 0;
while(1
== 1)
off ol.t the
conltalatola atlc DisDLaY
counte!
{
.*{
f o r ( i = 0 r i < 8 r i + + ) Each of th€ I / / Loog through | (n = 0t n < D1ayt n++)i for ( (vaIue & (1 << i)) == 0) lf PORTA = NqIPoRTAIil,
?-
t:r{
IJEDS
+ 1r
//
Inerdl€nt !/ 2s
lh€
Counler
(J >= s0)
| ) I /
value=va1ue+1i
//
j = 0; // ti
//
// E'ld
61ih!t clEDDiaD
DisDLaY Incldlent Counter Reset the couDter
2
This applicationtakesup lessthan half of the space of the original (both in terms of lines of code and instructions required), although it usesonly four more variable b1'tes.By just about any measurement,this rewdte is substantiallybetter than the original, but still I would consider replacing the original with it only if the application required more program memory than was available.Therefore, you should keep the knowledge regarding using an array to implement the multiple LED display code in the back of your mind until you have to implement a similar function. The built-in hardware featues of the PIC16F684 provides similar opportunities when you are looking over working applications.As you first start programming, you will implement basic input and output functions using the standard digital I/O capabilities of the microcontroller pins.Thesefunctions will simplify generating motor control signals,help you processanalog data, and help you more easily communicate with other devices.Although thesebuilt-in features will seemdauntingly complex in the beginning,they will becomeeasierasyou becomemore familiar with developingapplicationsfor them. I can promiseyou that you \ryilllook back and consider rewiting the applications to take advantageof the hardware "behind the pins."But remembermy advice:You should rewrite this code only if there is a concrete reason for doing so. Of course,you can avoid the whole question of whether or not to rewrite to take advantageof hardware featuresby implementing the features in your application right from the start. In this section,I introduce the different built-in functions of the PIC16F684 alongwith somesampleapplicationsthat illustrate how thev work and what can be done with them.
g
# (-) at {,*
90
€very
{
I
,tl
= j
if
In Section4,I showedyou arrays,and you might have thought about using them to rewrite the CLEDDisp.c application. I have done this and listed the programhere: #incluale CLEDDiED 2.c - 2trd velaiorr /* increm€nt ing counter
€la€ PORTA = PORTAvalus I i I t TRISA = TRISAVaIUe lil t // tof
l , P 3 P I C o l ' l C l JE x p e r i m e n t s f o r
the Evil
6enius
frt
Experiment 32-BrournoutFleset
X {}
1 Prc15F684 1 1M317 adjustable
t
voltTO-220
age lelfulato! package
in
1k bleadboald
mountable
;3
(D
:
l
Potentiometer REd LED L
Gleen LED
1 330C) l/4-vratt
1 0.01 p"F capacitor tYpe)
DMM sclewdriver Jekeler's lk potentiomete!)
(for
(any
{^J }'.l t I
B!eadboa!d-mountable (E-Sr{itch SPDT switch 8G1903 lecoaunended)
Needle-nose pliers B!eadboa!d WiliDg
resisto!
k j.t
g-volt
batterY
g-volt
battery
I H
pack
L"' In a previous experiment I explained that when I first started working with the PIC MCU and writing about it, various specializedcircuitry would have to be added to provide reset with brownout protection for the application.The PIC16F684, like other recently releasedchips,hasthesefeatures built into it, allowing you to take advantageof these featureswithout adding to the cost or complexity of your circuitry. Unfortunately,you may find that the work required to add the advancedreset functions to your application code is not trivial. In this experiment,I will demonstratehow the brownout detect and reset circuitry built into the PIC16F684works andprovideyou with somecluesas to how to decipherthe datasheets when a hardware functiondoesn'twork. The PIC16F684is designedto work in the voltage rangeof 2.0 volts to 5.5volts,which makesit ideal for battery power without a voltage regulator.When the voltagegoesbelow2.0volts,the PIC MCU can no longer operate reliably, it may stop,it may run different parts of the program memory,or it may executethe instructions incorrectly.To help avoid theseproblems the brownoutreset(BOR) canbe enabledin the configurationfusesto detectlow voltageconditionsand enablethe PIC MCU'S reset. To demonstratethe operationof the PIC16F84's brownoutreset,I createdthe test b/ownoutdetect(or
BOD) circuit shown in Figure 5-1.This circuit usesa power supply(basedon the LM317 variable-voltage chip) to reducethe operatingvoltagefrom 5 volts (nominal)down to 1.25volts.Note that eventhoughI am using the brownout detect reset function of the PIC MCU, I did not enable the MCLR function of RA3. The LM317 (seeFigure5-2) is a nice little adjustablelinear voltage regulator circuit that is ideally suited for a task like powering the PIC16F684in this ckcuit to test its brownout detect function. The lower end of the chip'soutput is 1.25,and the upper end is definedby the V'" power source.Its output is defined by the formula: V*r=1.25vx
(1 +
(R2lR1)) +
i$ssdxR2
Ptc16F684
_-a: ._ I
Figure5-l
Section F i v e P f C l , t F E A ql ' il c r o c o n t r o l l e r
BOD circuit
BuiIt-in
Functions
91.
pt
H
(0
BasicCircuit
.) LM317 Label
Adjust
V.
Figure5-?
il". LM3l7
but, asIo,r,is only 100u.A,the productof it timesR2 is normallynegligible.This is why in Figure5-2,I have the simplifiedformula.For thisapplication,Iuseda 1k potentiomcterfor R2 and a 3300 resistorfor Rl; this givesme an output voltagerangeof 1.25volts to 5.00 volts when a g-volt batteryis usedfor application power.Thesmallsizeof the breadboard-mountable 1k potentiometer meantthat I hadto usea jeweler's screwdrivcrto changethe potentiometer(whichcan be seenin my prototypewiring in Figure5-3). The plan wasto havethe PIC16F6U4 light the green LED on RC3 after reset,but if the resetwascausedby a voltagebrownout,thc red LED on RC2 would be lit. Thc originalapplicationcodewasbasedon cReset.cin whichthe _BOD bit (knownasBOD in PICCLitefM compiler)of PCON wasset after power up.Along with settingandcheckingthis bit, the BOREN label, insteadof the typicalBORDIS label,wasusedin the configuralionfusespecification.
I shouldpoint out that a numberof different optionsexistfor brownoutreset,includingignoring brownoutresetduringsleep(or low-power)modeand allowingbrownoutresetto be controlledby application software.Also, a numberof bits are setin the factory.which will tune the actualbrownout resetvoltage. For this application,I avoidedthe more complex brownoutresetoptions,wantingsimply to staywith a hardwareresetwhenthe voltagebecametoo low. With this setup,the red LED alwayslit on power up,regardlessof the voltageinput and whetheror not I setor resetBOD on power up.Additionally,I tried different configurationregistervalues-all with no success.Untbrtunatelythe useof the brownout resetin the Microchipdatasheets, or apnotes,is not shownand a Googlesearchdid not revealany codethat usesthis feature.As I scouredthe datasheets. I noticeda differencein hov{the PCON registerbits were specifiedfor power up.For the BOD bit, in one caseit wasmarked as"unknown" insteadof 0 at reset.which meantthat for it to havea valid valueafter a brownoutreset,it would haveto be set manually.With this information in hand,I then recodedthe cBOD.c applicationso that it would first checkfor a power on reset,at which time it wouldsetthe BOD bit.And on subsequent resets, the stateof the BOD would be checked. #include cBOD.c - Monitor /*
Reaet
o l r Bfown
Out
This Program !vi11 light an r,ED baseil ( Powe! Up or Browtt out ) nras reset Polrer Suppliedl to the PIc16F681l LM317 wired to proviale 1.5 to
Det€ct
on how it
comes fron 5 Volts
an
LEDS are connecteal to: RC3 - Power Up Reset RC2 - Brown Out Res€t myke predko 04.11. L0
& WDTDIS & P!\IRTEN & MCI,RDIS & -CON!'IG(INTIO I'NPROTECT \ & UIIPROTECE & BOREN & IESODIS & FCMDIS)t // <- Note "BOREN" nain(
)
t PORTC = 0i Cl,lCONo = 7 t / / .r\arn off Comparator6 ANSEL = 0t / / Flrrn of f ADc T R I S C = 0 b 0 0 0 1 1 0 0 1 1 t // RC3:RC2 as Outputs if
(0 == PoR)
//
Power-on
POR = 1r BOD = 1r Rc3 = 1r
// ll //
rrralicate Powe! Active Make suf€ BoD se! r,ED Set Polrer uplcood
Reset
occulred
t Figure 5-3 ctrcLutry
9Z
Assembled broytnout detect experiment
I if
l , e l P I C @f l C U E x o e r i m e n t s f o r
(0 :=
BOD)
the Evil
//
Cheek PCoN Regist€r
Genius
( RC2 = 1r RC3 = 0, BOD = 1,
// // //
BOD EaDDeneal Not a Gooal Pow€r llp Inallcat€ Prc Mcu Powereil UP Onc€
//
No Browa
//
IJoop Forever
2.
) Ou!
Detect
Reset
3. !rhi1e(1 )
//
== 1)r
Elral cBoD
cBOD did not simulatewell,which addedto my problems in trying to figure out what washappening. Now,whencBOD is run in hardware,the hardware powers up with the greenLED, and when the potentiometeris adjustedto a lower voltage,the greenLED dims a bit and then tums off completely.And, when the LM371'svoltageoutputis raised,the red LED tums on,indicatingthat the applicationcode(and hardware) hasrecognizeda brownoutvoltagesituation. In everyPIC MCU datasheet, Microchip marks eachbit whena registeris defined.Eachregisteris definedand then labeledasRegister#-x (where# is the datasheetsectionand x is the numberof the register definitionin the section),and the ability to read and/orwrite the bit alongwith its power up valueis specified.Readand write are specifiedwith a R andW, respectively, aswould be expected,but asI showin Table5-1,there are four initial valuesthat you should be awareoi Microchipdocumentationis uniformly excellent, and it is very unusualto find a mistakelike the one I found.(In caseyou are wondering,the mistakeis in Register3-1:PCON Registerof DS31003.{,pages314,and I havenotified Microchip of this error.So hopefullyit will not appearin later datasheets.) When you are confrontedwith a problem,asI havebeenin this experiment,wherethe codedoesn'twork as you shoulddo the [ollowing: expected. 1.
Check over the codeto seeif you can find the problern.Simulation(althoughnot possiblein
4. 5.
this experiment)of the program is alwaysa goodidea. Rereadthe datasheetto make surethat you are usingthe function properly.Often the datasheetwill haveexamplecodethat you can use. Look for apnoteson the Microchip web site that illustrate how the function works.Don't expectthere to be an apnoteon everyfeature built into the chip that you are using.You may haveto look at how the function works (and is programmedor wired) in anotherPIC MCU part number and understandany differences. Look for examplecircuitson the Internet using Googleor anolhersearchengine. Compareresourcesto find any discrepancies or cluesasto how the featureworks by cornparing the different descriptions.
rd f3
w
!_t
ia'
l"j&J t
It's importantto know that theseinstructionsare for gettinga hardwarefeatureof the PIC MCU working;they shouldnot be consideredthe most appropri ateway to debuga failing program.Later in the book I discusssomeof the techniquesfor finding a logic problem in a programand makingsurethat you havefixed it correctly.
i
f
i
(J
t$ |'{
Table 5-1 MicrochipEatasheetInilial FlegisterBit Value qno.ifi-rtinn<
r"*'
Eit PouJer Up Value MPaning 0
After Reset,the Bit valueis 0.
1
After Reset,the Bit valueis 1.
u
After Reset,the Bit is the samevalueasbefore Reset.
x
After Reset,the valueofthe bit is unknown.
5
Experiment 33-FUE Operation If you wereto look in the PIC16F684'S datasheet, you would discoverthat the functionof the analog-to-digital (ADC) functionis explainedover eightpages.I find this descriptionof the ADC function,althoughthorough,a lot more complexthan it needsto be.Using the ADC itself is surprisinglysimpleand doesnot require a lot of codeor understandingof how it works.In this experimentI am goingto explainthe functionand
S e c t i o nF i v e P I C l t F h B t l l l i c r o c o n t n o l l e n
Built-in
Functions
93
!
characteristics of the ADC and give you an example experimentthat samplesan incominganalogvoltage and displaysit on the eightLEDS of the PICkit I starterkit. The ADC functionof the PIC16F684canbe seenas a simpleblock diagramlike the one shownin Figure54;the linewith voltageto be measured is connected to a capacitorin the ADC. When the ADC operation starts,this capacitoris disconnected from the input and the voltagefrom the capacitolis passedto a comparator input.The other input to this comparatoris connectedto a slreepgenerator.whichproducesa ramping voltageat a known rate.To measurethe voltage(which canbe a maximumofVdd), the sweepgeneratoris startedand the time whenthe sweepgenerator'svoltvollageis ageto be grealerlhan thecapacitor's recordedusinga counter.This is reallyall thereis to it, althoughyou shouldknow a few other things,including beingfamiliar with the registersusedto control the ADC. The operationof the ADC is quite simpleand easyto integrateinto your applicatrons. Becausethe ADC operateswith the sweepgenerator, it doesnot executeover a singleinstructioncycle; it takesat least20 ps to perform the 10-bitdataconversionoperation.You shouldalsoallow at least12 ms betweensamplesto ensurethe capacitorchargehas changedto reflectany changein voltage.The time requiredfor the capacitorto chargeis why Microchip recommendsthat the impedanceof the signalshould be lessthan10k.These delaysmeanthatsamples shouldbe madeafter 32 ps or so,resultingin a maximum sampletiequencyof about30 kHz.This is fast enoughto implementaudiosampling,but not fast for manyreal-timedata-monitodngactivities. Fiveregistersare involvedin working with the ADC. The ANSEL registeris usedto selectwhich of the eightpossibleADC inputs (RA0 to RA7) will be connectedto analoginputs.On reset,the ANSEL register,which controlswhich of the eightbits are analog inputs,hasall its bits set.lf you look back at previous experimentsthat usethe PICkit 1 starterkit, one of the hardwareinitializationstatementsusedwasto clear
the contentsof the ANSEL register.For this experiment and any applicationthat requiresanaloginputs be measured,the bits representingthe analoginput pins are left set. The next registeris the ADCON0, which controls the operationof the ADC.This registeris usedto enableand start the ADC hardware,to selectwhich pin will haveits analoginput sampled,and to set the output fomrat.Thble5-2 liststhe functionof the different bits usedin the ADC. The sweepgeneratorhasan internal counter,which is run from a built-in RC oscillatoror the processor's clockand is known asthe A/D ConversionClock.It hasthe timing signalTAD. Its sourceand prescaler valueare selectedby bits 6:4of the ADCONl register. In Table5-3,I havelistedthe differentADC clock optionsand the resultingprescalervalues.TheTAD valueshouldbe between1.6ps and 6.4 ps for proper operationof the ADC, and this time is calculatedby simplymultiplyingthe PIC MCU's clock period by the TAD operationlistedin Table5-3.If you don't want to calculatethe TAD operationthat will give you the
Table 5-2 F U E 0 N 0B i t F u n c t i o n s Bit Name
Function
7
ADFM
Output Format:0 = Left Justified(ADRESH has8 Bits):1= RightJustified(ADRESH has2 Bils)
6
VCFG
VoltageRelerence biI: I = Vrel Pin (RAl); 0=Vdd
5
Unused
4:2 CHS
= RAo; AnalogChannclSclcct:000 0 0 1= R A l i . . . l l l = R A 7
1
GO/_DONE ADC OpeIalionStaft/EndIndicator
0
ADON
1= PowerADCr0 = ADC Off
Table 5-3 FDC0NI Bit Functlons Bit '/
TRD Operation
Unused
:'2 6:,1 0oo-Period r'3 001 Period * 32 010-Period xl-Internal,{UsRC 100 Pcriod* 4 * 16 I01 Period 110-Peiod* 64 Genefatof
Commentg
3:0
Figure 5-q
ADC bl.ockdiagram
94
l , a 3 P I C o l l C U E x o e ri m e n ts f o n t h e E v i l
Example:For a PIC16F6B4 runningat 4 MHzClock Period = 250 ns DesiredTAD = 1.6!s to 6.,1Fs ClockPe od +TAD Operation001 =250ns*E =2!s Unused
Genius
fastestADC operation,you cansimplyselectthe built(RC) clock-this runs at a nomiin resistor-capacitor nal 4 r.r.s and will allow the PIC MCU'SADC to operateunder all conditions. The fourth and fifth registersareADRESH and ADRESL, respectively. Thesetwo registersstorethe 10-bitresultof the ADC operation.The10 bits are displayedaseightand two,with eachregisterhaving either two or eightbits.I recommendthat you left justify the data,or storethe eightmostsignificantbits in ADRESH and the two leastsignificantbits in ADRESL.The two leastsignificantbits are generally consideredto be in the noiseregion,and their valueis not accurate;by readingonly the mostsignificanteight bits,you shouldbe gettinga reliableeight-bitanalogto digital conversion. With the registerssetup,you will setthe GO/_DONE bit (known asGO in PICC Lite compiler) and wait for it to go low.Hopefully,my description of how the ADC workshasn'tconfusedyou, becauseto carry out an analog-to-digitalconversionon a PIC16F684'sRAOpin, only the following six C statementsare required: INSEL
= 1r
ADCONo = / I BlE // Bit ll BiE / / BiE / / BiE A . D C O N I=
//
|
//
= ADSESE'
//
aa Analog
Turn on the sarDl.e
hput }Irc
the
hpu!
Value
This program salnpl€s the voltage on RAo uEing the A.Dc aaal DisDlayE the value on the 8 IJED3 uaiag .cr,EDDisD 2" as a base. rnfke 9realko 04.10.03
of
PORIA = 0t CUCONo = 7t ANSEI = Li ADCONo = // BiE // Bits // BiE / / B,.E // BfiLDCON1 =
I / ll.fi'l// Juat
on
' ;
ADC
oft Conpa?alorE ItAo ia art Aaalog
0b00000OO!i olr th€ ADC // Tlta 7 - I"ef,t ,tustifieal Salnlrle 5 - Uae vDD 4r2 - Chann€1 0 L - Do nol Start O - Tuln on A.DC 0b00010000r // Select lhe clock Foac/o == Ll
//
:--3
i*
Input
ti;"* a ;
( (ADcvalue & (1 << i)) PORTA = NOIPORTA til t
i
lat
rt
tshe I LEDS "on'r //DiEPlav Delay Loop == 0)
-*1' i i i
'.: i""4
Machine
case 0: starl Next' salllple // EiniBhefl, CiODONE= Lt LDCgtat€++t bleak; case L, / / waits for ADC to codnplete ( lGoDoNE) if PiniEheal ADCStsate++, // Sarple breakt in cas€ 2: // Save Sanple value "ADCvaIue " ADCVA].rIE = ADRESH' ADCSlate = 0t bleak; // hctirtr's l // elihw ) // End clrDc )
When you run this codeon the PICkit 1 starterkit, you will be ableto changethe valuedisplayedon the LEDs by changingthe potentiometer(marked"RP1" on the PICkit 1 starterkit). You may find that the least
Built-in
,
rurl-
t
5 e c t i o nF i v e P I C l , h F E g qf l i c r o c o n t r o l l e r
t
as
Loop Foreve!
PORTA = PORTAVaIUe lil t TRISA = TRISAVaLUe lil t // '.of l (A.Dcstatsel acrilcb ll ADC State
save sarll)le value After Operation
Po!
K€€p Track OI,eration
{
if
couldl also be ncODOl[E = 1rtr for A.Dc Eo wait Completse
Prcki!
//
nain( )
//
For this experiment,I haveusedthe scannedeightbit LED displaycodeto displaythe valueof the ADC. To ensurethat it doesnot negativelyaffectthe operation of the LED displaycode,I haveprogrammedthe ADC operationin cADC.c asa statemachine,withthe sampletaking placeover severalpassesof the LEDs. Thiswill avoidspendingtoo much time with any one LED lit longerthan the othe$. +inclutle CADC - DiaDlay /* the builts in rJEDs
= 0,
f o r ( i = 0 r i < g r i + + ) Each of I / t oor, thlough I (i = 0t i < Dlay, i++)t for
IntelnaL
. rr
= 0; lnt ADcvaluo int Dlay = 53r // LED Tirre on Delay Variable cotrst char PORTAvalue [8] = {0b010000, 0b100000. 0b010000,0b000100, 0b100000,0b000100. 0b00010o, oboooo1olt const cltar TRrgavalue [8] = {0b001111, 0b001111, 0b101011,0b101011, 0b011011,0b011011, 0b111001,0b111001)t c o n s t c l r a ! N O I P O R T At 8 l = t 0 , 0 , 0 , 0 ' 0 , 0 , 0 , O l l
(
Select th€ RC Clock
s-J L"{
& &
q!r' i, j; e.Dcslale
int int
while(1
(1 << 1)r
IGODONE)t
ADCValue
RAo iE
0b000000001r // 7 - I.eft ilustifietl 6 - uae vDD 4t2 - channeL 0 L - Do not Stalt 0 - Tulr on ADc 0b001110000r //
A.DCONo = AI'CON0 while(
Just
& WDTDIS & PWRTEN & IICIJRDIS CONI.IG ( II{TIO IJNPROTECT \ & ('T{PRO!!ECT & BORDTS & IESODIS FCMDIS ) '
Functions
95
r 1
significantbit flasheswith certainsettings:Thisis due to slightlydifferentreadingseachtime the ADC operates.If the leastsignificanttwo bits were alsoshown, you would probablyseesignificantlymore flashingat other potentiometersettings. What you shouldconclude from this experiment is that the most significant sevenbits of the ADC output will be accurateand the leastsignificanttbreebits shouldbe ignored. For this experiment,I am usingthe circuit built into the PICkit 1 starterkit shownin Figure5-5.This circuit consistsof a potentiometerwired asa voltagedivider with a currentlimiting resistorand a capacitor.The voltageoutput of this potentiometercircuit can be
I-Figure5-5
ADC circutt
readmore than one way,asI will showin the next two experiments.
rt; t i
ExFeriment 3t-.1-EomFarator Operation $i-a
Table 5-4 EMCON0BegisterBits and EomparatorOperation Bit
FunEtion C2OUT
Comparator2 Output. if (0 == c2rNV)
r!*
C2OUT= 1ifC2Vin1 > C2Vin, else// if (1 == C2INV)
tr*
1-t
I ,
1' J
f1
!i.ii ,!! 11
One of the measurements that I useto gaugethe difficulty of applicationsin this book is whetheror not the circuit I designand the codeI write works the first time.WhenI startedthis experiment,I had a perfect recordof 72 applicationsthat worked the first time I built them,and burned their codeinto a PIC16F684. Other factorsfurther bolsteredmy confidencefor first-timesuccess for this experiment:My plan wasto basethe codeon the previousexperimentand my familiarity with the PIC MCU's comparatorand integratedvariablevoltagereferencecircuits.In this experiment'swrite up,you'll get an explanationof the operationof the comparator,plus you'll get a story of hubrison my part.
C2OUT= 1ifC2vinl < C2VinC1OUT
if (0 == clrNv) CIOUT- I if ClVinl > ClVinelse// if (1 == CIINV) CIOUT= I ifClvinl - ClvinC2INV
Set to IDvertthe Comparator2 Output Condition(SeeC2OUT)
ClINV
Setto Invert the Compantor 1 Output Condition (SeeCIOUT)
CIS
ComparatorInput Switch,Usedwhen CM bits == 010
if (0==crs) RA1 is Clvin-
The comparatorcircuit built into the PIC MCU is quite simple.It consistsof two comparatorswith differing input and operatingoptions,which are controlled by the CMCONOregisterexplainedin Table5-4. Beyondthe CMCON0,a COMCON1 registeris used to controlthe operationof one of the built-in timers andsynchronizeone of the two comparators'output with a timer.I havepassedover this CMCON0 register becausetheseoptionsare requiredonly for specific applications The CM bits of CMCONO selectthe operating modeof the comparator(seeThble5-5).In most
96
Comparator1 Output.
RC1 is C2 Vinelse// if (1 == CIS) RAO is ClvinRCo is C2 VinWhen CM bits == 001
if (0==crs) RA1 is Clvinelse// if (1 == CIS) RAO is ClvinCM
l , a 3 P I C @l " l C UE x p e n i m e n t s f o r
ComparatorMode SelectBits (seeTable5-5)
the EviI
6enius
Table 5-5 EomparatorBperatingMode 5elected bg the EMEONOEM Bits
f'1
X
F0
EM 2:O Operation of Comparators
o
111(7)
ComparatorsOff Requiredsettingto useRAo, RA1, RC0,and RC1 asdigital I/O.
r-t
110 (6)
Comparators On, RCo is common Vinl for two compamtors.RA1 is Clvin-, RA2 is C1OUT,RCl is C2Vin-, and RC4 is C2OUT.
F.
101 (5)
Comparator 1 Ofl Comparator 2 On. RCOis C2Vin1 and RC1 is C2Vin-.
100(4)
Both comparatorsoperating.RAo is C1Vin1,RA1 is Clvin-, RCo is C2Vin1,and RCl is C2Vin-.
011 (3)
Both comparatorsoperatingwith commonVinl on RC0. RAl is Clvin-,and RC1 is C2Vin-.
010(2)
Both comparato$operatingwith commonVinl ftom Vref module. Clvin- and C2Vin- are selected by CMCON0 CIS (seeTable5-4).
001 (1)
Both comparatom operating with common Vinl on RCo. Clvin- selectedby CMCON0 CIS (seeTable5-4) and RC1 is C2Vin-.
000(0)
ComparatorsOflAnalog input on RA0, RA1, RCo, and RC1.Default setting.
ss
To Comparator Inputs
w *r I Figure 5-5
Vref circuit \ J
Table5-6 VFEONFlegisterBit Bescription
o u !{
Blt Name Functlon applicationspresentedin this book,I havetumed the comparator bits off by writing 0b0111to the CM bits. For this experiment,I want to use RAO as a comparator input along with the controllable Vref voltage sourceto measurethe voltage coming from the potentiometer built onto the Plckit 1 starter kit. The Vref sourceis available only to the comparator. In someother comparator-equipped PIC MCU part numbers,the Vref value can be output to other devices.This circuit consistsof a tapped voltage ladder with different voltagespassingthrough a 16-to-1 analog multiplexer. The VREN bit of VRCON controls the power,andVRR selectsthe operatingmode (see Figure 5-6). Figure 5-6 also lists the output voltages basedon the stateofVRR and the VR bits of VRCON which are listed in Thble 5-6. To demonstratethe ability of the comparatorand Vref circuitry asan analogto digital converter,I used cADCc asa basefor the eighth LED output control loop,and I usedthe statemachineto poll the ADC. I cameup with cComp.cin which I found the potentiometer's wiper voltageby usinga binary searchalgorithm. lliacluile - R€aal th€ ccoq) /* uBing conpalator/cr€f
PICkit
Pot
laDut
Vollage
Thia Drogrrm arrrpleE the voltag€ on RlAo uaiag lbe CorE)arator rdith the Cref Dtotlule anfl DiEplayB tsbe four bit r€Eults on th€ l€aEt Eigaificant LEiDa on Eh€ PICkit PCB.
5 rt
'7
VREN vref Module PowerEnable
6
N/U
Not Used
5
VRR
Vref Voltage Select (1 = Low Range; 0 = High Range)
gl Ft )r,
4 N r u
Not Used
3:0 VR
VoltageSelectionBits (seeFigure5-6 for formula) I 7
}{ lth€ ADC oDelation algoritbrn
consiatg
of
a binary
aearch
o U
Ilyk€ predlko 0{.10.05
l{ -CONjrIG(INTIO I'NPROTECT \ FCUDIS) t
F'
& WDITDIS & PWRTEN & T''CLRDIS & & I'IIPROTECT & BORDIS & IESODIS &
c+ F.
LnE lnt cdDstate
= 0r
//
Nextvrefvalue; vrefvalu€ t Di69value = 0t
//
K€€p Track ODeration
of
Comparator
DisDlay value to avoLtl F].ashirg int Dlry = 53r // LED !!ime on Delay variable coaat char PORTAVaIUe [8] = { 0 b 0 1 0 0 0 0 ' 0 b 1 0 0 0 0 0 ' 0b010000,0b00010o, 0b10000o,0b00o100, 0b000100, oboooolo],
S e c t i o Fn i v e P I C l , b F b A q i c n o c o n t r o l l e r B u i l t - i n
Functions
97
L) X
corr6t
char
colrst
char
nain(
= t0b00X111, 0b001111, 0b10x011,obx01011, 0b01x011,0b011011, 0b111001,0b111001), NOTPoRTAI8] = t0, 0. 0. 0, 0, O, O, O], TRISAVaIUe [8]
)
t PORTA = 0, C M C O N o= 0 b 0 0 0 1 1 0 1 0 r // Iaitialize Conparators // BiE 5 - Conp 1 Output (v- > v+ = X) // BiE 4 - Inverts corlr (RcO C2 rnpur ) // BiL 3 - RtAo C1 Inpur // Rit 2tO - CofirDarator with Cref VRCON = 0b10L00000r // Vr€f MoaluJ.e Control //Bit7-Enable // BiE 5 - Low Range (0 - 2/3vdd) // BiE 3.O - anaJ.og Lev€Ls aNSEI, = 0t // No ADC hputa while(l
{
== 1)
//
Loop
For€ver
f o r ( i = 0 r i < 8 r i + + ) | / / Loop through Each of the 8 r,EDS for (j = 0, j < Dlayr j++), "on" D€tay Loop //Display (0 == (DisDvalue & (1 << i))) if PORTA = NOTPoRTAlil, e16e PORTA = PORTAVaIU€ [i] , TRISA = TRISAVaIUe [i] , l // rof (Conpstate) svritch // CdtE)arator Stat€ l4achin€
{
// = 8t // Nextvrefvalue = 0; vrefvafue vRcoN = 0b10101000t Compsta!e++i
Filrished, Start Salnple sEatL witsh rligh
N6xt value
b!eaki
/ / waiE for ADC to conpl€te lO != (o'tcolro & (1 << 6))) // v!^ > vtef? (1 == clou!) if // vin > vref? = Vrefva1ue Vrefvalue + Nextvrefvatue, €tse // No - Take Alray fron Vref VRCON = VRCON - Nextvrefvalue, I I Ttr \e'*E bit of binary search = Nextvrefval"ue Nexlvrefval"ue >> 1; VRCON = VRCON + Nextvrefval.uet (0 -= Nextvrefvalue) if ( / / Einisheat, Display New vaLue = Vrefvaluet Dispvalue = 0i Conltstate // and Restart Analog lt€asurement /l fi , break; ) // hctiws ) // elihw // Erd cconp ) //
if
To measurethe potentiometervoltage,you could haveuseda simplealgorithmthat startedwith the Vref voltageat a minimum value(VR = 0b00000)and incrementedit until the comparatorchangedstate.I usedthe binary searchalgorithm,becauseit requires the logarithmbase2 comparisonsof the numberof bits insteadof potentiallyhavingto run througheach bit. In this case,usingthe binary searchalgorithm reducedthe number of comparisonsfrom a maximum
98
of 16 to four.A binarysearchalgodthmusedin comparisonoperationslike this one continuallyhalvesthe comparisonincrementuntil nothing is left.As I show in the followingpseudocode, a test valueis used,and if the valueis greater,it is left asis,else,the valueis removed.After the comparisonis complete,the test valueis dividedby two againand addedto the comparisonvalue.Thisis repeateduntil the comparison valueis zero. = Maxinu! / 2; // Stalt at 1/2 Maximum = Conparisonvalue; ConDarevalue // add to the Cofiurarison value u'hiL€ (0 != Coq)arisonvalue) // Repeat while a value to Add { I / Deternine if vaLue to b€ Saneal (Conparevalue if > InputvaLue) = Compalevalu€ - Conparisonvalu€i Cornpar€Value = cdll)arisonvalue comparisonvalu€ / 2t // R€peat O!|eration = Comparevalu€ Conparevalue + ConDarisonvalu€, | / / eli})w ComparisonvaLue
The binarysearchis ideal for digital systems becauseit works nativelywith binary bits.The previous codeis not significantlymore complexthan codethat doesan incrementingcompare,and the operational speedgainedis significantand growsin significancefor eachadditionalbit to compare. As I alludedin the introductionto this exDeriment. whenI firstrurnedon the originalcodenothinghappened.I wasvery surethat the hardwarewasgood (it worked fine for cADC.c),so the problem wasclearlya programmingproblem.This is a very difficult program to debugbecausethe MPLABo IDE simulatorwill not simulatethe operationof the comparatorandVref modulewith an analoginput.To find the problem I reviewedthe operationof all the program,sstatements (fortunatelyit's a shortprogram)and found the following one line if
( 1 = = ( C M C O N o& ( 1 < < 5 ) ) )
that neverbehavedasif the expressionwastrue.This instructionANDS the contentsof CMCON with bit 6 set and returnstrue if it is equalto 1.My initial responsewasto rereadthe comparatorsectionalong with previouslywritten applicationsto figure out if I wasdoing anythingwrong.The codelooked great.I then changedthe programso everyhardwareregister wasrenamedto a variable(for example,CMCONO became CMCONO)and went on to try different valuesof _CMCONOto find out if therewassomethinsI wasn'lseeing. Usinglhis merhodI discovered there wasn'ta valuefor _CMCON0 that would causethe expressionto be true. I looked at the expression"1 == (CMCONO& (1 << 6))" in the if statement,and when I checkedits
l , e 3 P f C @i l C U E x p e r i m e n t s f o n t h e E v i I
6enius
resultusingthe simulator,I discoveredthe error:the expressioncanneverequal1-it will equal 0b01000000, but never1.WhenI changedthe expression to testfor not zero the programworked fine (this is commentedout statementin ccomp.cabove).Further improving on the statement,I simply polled the C1OUT bit to be high,rather than manipulatingthe contentsof CMCONO. This descriptionofwhat I did to solvethe problem wasn'tput in to scareyou.You probablyaren't comfortableyet doingthis kind of debug,especiallyconsidering the simulatorcannotsimulatethe operationof the comparatorandVref hardwareand registers. But I want to point out the stepsI followed: 1.
2.
3.
Check over the hardwaredocumentationto make sure the hardwareinterfacesare properly coded. Test the operationof eachstatement.If necessary,changefrom a registerto a variable;a variable can be declaredby usinga registername with an underscore(_) characterprecedingit. Clearly articulatewhat the problem was.For me the problem wasthat the registerexpres-
4. 5. 6.
sion "(CMCON0 & (1 << 6))" could never be equal to the comparisonvalue (1). Fix the problem accordingto what you feel the problem is. Testthe fix usingthe simulatortools createdfor the task of discoveringthe problem. When you are satisfied,burn the new program into the PIC16F684and seeif this works better ror you.
You shouldbe able to follow thesestepsin debuggingyour own applications, and althoughthey may you will seemslow and tedious, find the problemand have an idea how to fix it. I want to point out that the root causeof my problem wasmy doggedinsistenceon programmingapplicationsusingstandardC and not usingPICC Lite compilerextensionswherethey make sense.As I have said,C is not well designedto manipulateindividual bits,but PICC Lite compilergivesyou the ability to accessbits individually,and all the registerbits are codedin the includefile.
rs: * *e4 fl1 r)
*\r ;-i ,.-*
9 . 1 r :ai
!
.1,::9 '_*11
i,i
Experiment35-l-UatchdogTimer
;:.,ir,:
.{:-: 1 Ptc15F584 1 10-LED bargraph I
display
0.01 pF capacito! tlpe)
i
Breadboard-mountable (E-Switch SPDT switch EG1903 reconmended)
lfi
Two-cell AA or AAA battelY pack
D}4M Needle-nose
AA o!
AAA batteries
pliels
B!eadboard Itiling
kit
T\e WatchdogTimer(WDT) is built into all PIC microcontrollersto provide a reliablemethodof resetting the rnicrocontrollerif executioneverstopsfollowing the expectedexecutionpath.This can happenwhen the PIC MCU runs in a high electrical-noise environment,suchasnear the flybacktransformerof a TV set or near a car'sienition svstem.When the WDT is
enabled,it continuallycountsdown a set delay,and if it is not resetwithin this period (usingthe clrwdt instruction), the WDT resetsthe PIC MCU and execution startsover.Personally, I haveneverusedthe WDT in any of my applicationq and I can think of only one commercialapplicationthat takesadvantageof it. Along with this,the advancedresetfunctionsof modern PIC MCUs eliminatemuch of the practicalneed for the WDT. Chancesare you will never require it in your applications, but you shouldbe awareof it and
S e c t i o nF i v e P I C I h F h g q f l i c r o c o n t r o I l e r B u i I t - i n
Funct i ons
;.tr.
(any
99
H
0, ,J
r en rt "r{
tr,
rv tFa ! t
4""{
&.} 1,".
how it operatesas there is one trap you will probably fall into whenyou work on your own applications. That trap is to not correctly disable the WDT in the configuration fuse specification.Many new PIC MCU application developerswill specify only the labels for the configuration fuse functions that they believe are required for their applications.Unfortunately, the configuration fuse functions are both positively (bit set) and negatively (bit reset) active,and not specifyinga value for the bits could result in an unwanted function being active.The most common unwanted function being made active is the WatchdogTimer. When the WatchdogTimer is enabledinadvertently in a simple application,with no clrwdt repeatedly executing in the application,the PIC MCU will reset itself after two secondsor so.The reasonfor the reset is indicated asthe _TO bit of the STATUS register being reset on power up.The problem ig that the application will have executedfor a couple of seconds,giving the appearancethat the application started correctly,but a software problem causedit to resetitself and start over. The reasonfor the reset can be clearly seenby running the MPLAB IDE simulator, by setting a breakpoint at the first executingstatementand addingthe Stopwatchfunction.If the WDT is active,the program will executethe first statementa secondtime,about 2.1secondsafter the start of the simulation.Ifyou see this behavior at any time during your application development,you can fairly confidently assumethat the WDT is becoming active. The circuit that I usedto test the operationof the WDT resetis shownin Figure5-7 and wired on a breadboardasshownin Figure5-8.Thetestcodeis cWDT.c and increments the number of LEDs that are lit on the 10-LED bargraphdisplayonceevery500ms To disablethis function, simply changethe WDTEN argument to WTDIS in the _CONFIG macro.Unless you are goingto usethe WDT in your application, then the WDTDIS argumentmustbe presentin every applicationthat you create. You should find that after you turn on power to the application,the first four LEDs light but are then turned off whenthe tenth LED is lit, and the process repeatsitself over and over again.The 2.1-second delaybetweenWDT resetsis determinedby hardware within the PIC MCU. I will discussit in more detail later in this chaDter.
1 OL E D Bargraph
-:---E,, t I I Side
Figure 5-7
WDT circuit
Figure 5-8 Testapplication to demonstratethe operattonof theWDT reset
Previously I stated that I know of only one application that takesadvantageof the WDT. That is the Parallax BASIC Stamp(and BASIC Stamp2). In these PIC Mcu-based devices, the WDT is usedto time the s/eepstatement,which puts the BASIC Stamp to sleep for increments of 2.3 seconds(the rnaximum WDT resetintervalfor the PIC MCU chipsthat are usedas the basisof the BS2).
, r.{ FI
r't I 14{ a,
r-1
100
l , e i P I C @f l C l JE x p e n i m e n t s f o r
the Evil
6enius
Exp e r im ent 36- S hor t T i me rD e l a g sU s i n gT MF 0 WhenTMRO overflows,it setsthe T0IF bit of the INTCON (interrupt control) register;to do so is an interrupt request.I do not discusshow interruptsare implementedin this book,but this bit canbe usefulto poll to find out if TMR0 hasoverflowed.Inthe lowend PIC MCUs,no interrupt capabilityexistsand no T0IF bit existsso the contentsof TMR0 will haveto be continuallypolled.
For mostof the experimentspresentedin this book,I usesomekind of incrementingor decrementingloop for producingdelays.In the latter half of the book,I showhow you cancreatevery precisedelaysby counting out the executiontime of the instructionsand loops of instructions. But whena delayis requiredfor programmingin C, I tend to createa simpleloop and then tune the delayvaluesempiricallyusingthe MPLAB IDE simulator'sStopwatchfunction.The empirical approachworkswell for mostlarge(i.e.,tensof ms or longer)delays,but for shorterdelaysthat requiresome precision,this methodjust isn't goodenough. A better way of producingaccuratedelaysis to use a timer.ThePIC16F684hasthreebuilrin timen that you can usefor producingdelaysof known lengthsas well asfor someof the hardwareperipheralfunctions built into the microcontroller.In this experiment,I will introduceyou to the operationof TMR0 (or Timer 0) and how it canbe usedto produceaccuratedelaysup to 256ps.In the following experimentEI will present the other two timers,their standardoperation,and how they work with peripheraldevrces. TMR0 is an eighfbit timer that canbe driven either from an externalsourceor from and internalinstruction clock.Most applicationsusethe instructionclock asa methodof providinga set delay.In TMR0's basic configurationwhile runningin a 4 MHz PIC MCU, delaysof up to 256ps (23)canbe addedto the application.An externalsourcecanalsobe used.And. as somepeoplehavenoticedin the datasheets for different parts,the PIC MCU TMR0 modulecantake up to 50 MHz of input,leadingto someinterestingpossibilitiesfor measuringvery high-speedsignals. Control for the input sourceforTMR0 is the T0CS bit of the OPTION register(seeFigure5-9).The OPTION registerprovidesa numberof executioncontrol bits for the I/O pin internalpull ups,Watchdog Timer/TMROoperation,and interrupt operation (Table5-7).When you are working with the different hardwarecapabilitiesof the PIC MCU, you will find the OPTION resisterto be a verv usefulresource.
TheT0IF overflowbit is set whenTMRO changes from OxFFto 0x00and is the basisfor basicdelaytiming.Assumingthat the internalinstructionclockis usedfor TMR0 and this clockis 1 MHz (the instruction clock speedof a 4 MHz PIC MCU), the formula for determiningthe delayis: Delay
(in ps)
= (256
TMRo Initiaf
Value)
So,to specifya 200ps delay,the formula canbe rearrangedto find the TMRo initial Value: TMRo Initial
Value
= 256 DeLay = 256 - 200
In cTMRO.c,the operationis demonstratedfirst by the while loop in which the incrementingof TMR0 can througheach be seen.Thisis done by single-stepping
TOCKI Fosc Figure 5-g
BasicTMRq
Table5-7 OPTI0NFlesisterBits Bit Name Number Function _RAPU INTEDG
'/
Enable PORTA pull ups
6
Selecttheedgefor RA2 inlerrupt request(1 = Rising) Selectthe TMRo clock source(1 = RA2, 0 = lntemal Clock) Selectthe
PS2:PSo 2:0
S e c t i o nF i v e P I C I t F t A q f l i c r o c o n t r o l l e r
wDT.0
\ alue(Prescdler \ alueSeleclprescaler ?Psr:Ps\
BuiIt-in
Functions
1.01
statement.Each C statement is made up of multiple PIC MCU assemblylanguagehstuctions, so the different valuesby which TMRO incrementsshould not be a surprise. *inclutl€ - 1'!tR0 Opelat.ion cTu8o.c /+ Thia TllRo I t
*-{ :jc{
i
:
i
Drogram dlenonstrates Harakra!€.
ant[ Short
the
Delays
oD€ration
of
th6
rE ke Drealko 0{.11.24
-CONUG(INTIO UI{PROTEC! \ FCMDIS ) t
& WmDIS & PV|RTEII & I'ICLRITIS & I'NPROTECT & BORDIS & IESODIS
1 a-
{ OPTION = 0 b 1 1 0 1 1 1 1 1 t Bun TMRo from
nhi16 t
=t\-i
-:,-,
// Denon6tra!€ (1 < 1000) = i + 1t a fairly
TgRo - 55t l / I'riEi,alize ToIF = 0t / I \$n oft
the
Cloch
Opelatl.on
pr€clae
of
200 us
TlR0/Blealrl)oin! Peniling
OEciLlator
rnt€rrupt
TMRo
tl€Iay
]
// rchtle / I NoP O t //
Enabl€ T!4R0 Oeerflorc to Request ( !ToIF), Wai.E for 1l!4R0 !o O'lrerflow
whil€
(1 == 1)t
//
Breakpoint
Here //
- ,Iim€
to
Ints
Previous
I.ooD Foreve!
Enal cT!,1R0
In the secondpart of cTMR0.c,I demonstratehow to code a 200 ps delay controlled by TMRO.The first statementis putting in the TMRO Initial Value,whichis followedby a statementresettingthe TOIFbit, and then one setting the T0IE bit to enable the interrupt request.In the while loop, I am simply waiting for T0IF to becomeset when TMRO overflows By clickingon "Debugger"and "Stopwatch,"and then placing breakpoints where I have indicated in cTMR0.q I was able to time the execution from the settingof the TMR0 Initial Valueto the final NOPO;.I found the delay to be 207instruction cycles,which is an effor of seveninstruction cycles.This translatesto a delayof 3.5percent.For mostpracticalapplications, this error is acceptable. Although someapplications require absolutelyprecisetiming, when providing a basic delay,an error of a few percent will not negatively affect the operation of the application and will keepyou from carryingout what is essentiallyuseless debugging.
Here Requ€stE
*i
Experiment 37-Using the TMH0Prescaler
,l
i'4.{
When you looked at the OPTION register definition (seeTable5-7),you probablynoticedthe PSA bit, which selectedwhether the prescalerwaspassedto TMRO or the WatchdogTimer (seeFigure 5-10).The prescaleris a programmablecounterthat canbe used to changethe TMRO (or WatchdogTimer) timeout
102
interval. This convertsthesedelay interuals from just a few hundredms to severalps or evenseconds The prescalercanbe usedwith eitherTMRO or the WatchdogTimer, and its use is selectedby the PSA bit of the OPTION register.When the prescaleris selectedfor the timer,it dividesthe incomingclock signal accordingto the OPTION register's PS bits, with the divider being the zPs2'Ps. When the prescaleris usedwith TMR0, the signal is slnched with the internal instruction clock, which results in another division by two. So essentially, the prescalerdividesthe TMR0 * 1. input by 2Ps2'Pso In cTMROPre.c,I specify that TMRO is driving by the internal instruction clock, and I also reset the T0CS bit, which passesthe clock signal through the prescaler.
l,ei PfCo ilCUExpeniments for
the Evil
6enius
( ltrolP), whil€ NOP(),
//
BreaLDoint PteviouB
TURo = oxFFt
l/
Exec\rEe 255 ci'cle Delay/Breakpoint flele
- Tine
II€re
to
i.1: {}
ToIF = 0t
Figure 5-10
f , o ! ( i = 0 r i < 10r i++), ll I'rtRo = TI.,IRo I 0 x 8 0 r // ( ! ToIF) t lrhile NOP O T // BreakDoint Previous
CompleteTMR}
(1 == L>i
lthi1e
Becausethe prescalerbit selection(from PS2to PS0) is still set,the prescalerdelayis 1:256.Or, put another way,TMR0 is updatedonceevery256instruction cycles. *iacludle - TuRo operatioda ctMRoPle.c /* P!€acal,er This Drogram alenonsllet€s r!!Ro anal P!€sca1€r.
lbe
with
th€
oDelation
of
the
rryke Drealko 04.LL.2A
)
//
nain(
)
{ OPIION = 0b11010111t // Rua T!{Ro with //
1:255
Use Same Coat€ as fairly of uct![Ro.c"
TURo = 55r ToIE
= 0i
ToIE
= 1t
m{Ro = 0x6t
$IRo
preciae
200 us
al€lay
//
Run TuRo with 1!{ PreacaLer Execute 1000? cycle D€Ia1'/Bleal
t //
Brealeoint Ptevioua
0b11010111r
= o:iFF;
t'o
//
//
t1 ;"'i,
.$
s
Loop Eorever
t:,
Like cTMRO.c,cTMR0Pre.crequires the MPLAB IDE Stopwatchto understandwhat is goingon. In the first TMR0 delay,TMR0is loadedwith an initial value of 56,and the time taken to reachthe NOP0; is 51,208 rycles.This is 256times200plus 8.The productof 256 and 200is exactly what was specifiedby the TMR0 Initial Value,and the eight additional cyclesare similar to the seven-cycle overflowof the previousexperiment. prescaler, Usingthe a delaycanbe specifiedas: = 2r"""ur""
I X
i: (256 - TMRo Initial
Value)
i:.L
wherethe prescalervalueis definedasthe base2 logarithm of the delaydividedby 256(the maximum TMROvalue).This is a complexway of sayingwhich power of 2 would produce a number large enough to storethe valueof delay.For example,if you wanteda 1 msecdelay,you would usethe followingprocess:
].tr' 'r i:l
Pleacaler
Initialize I'llRo/BreaLpolnt He!€ // 'I'luin off Penaling Intelrupt Requ€atE TURo Ov€rflow to // E[able Requ€st Ints ll WaLE fot I'MRo to Overf,low Here - Time Eo .// Breekpoinl Previous
OPTION = 0b11010001r
OPTIoN -
- Time
Hele
Prescaler = Log, fnt(1,000/256 = Log, 3
) f::iJ
//
(!T0Ir)r rrhile NOPOr
loIF = 0, roIE = 1, ( ! T0Ir) while NOPOT
//
waj.t a Eew cycles set Bit 7 Again
Enal cI'MROPre
Delav ( INTIO & WDTDIS & PWRTEN & !4CIJRDIS & -CONFIG I'NPRC'IECT \ & I'NPROTECT & BORDIS & IESODIS & FCr{DrS ) ,
ffi
ll6re
- TLne to
Run ,ITtRo with pteacale!
Execute 256 Cyc16 D€lay/BreakpoinE Eere
TOIF TOIE
S e c t i o nF i v e P I C l h F b A q
1:255
t**: Now to find the TMR0 Initial Value,the formula is rearrangedagainto the following: TMRo Initial 2P'4€Ler
Value
= 256 -
(Delay
t1''f
/
+ 1)
,: :i
= 2 5 6 - 1 1 A 0 0/ 2 t ' r ) = 2 5 6 - 1 7 A 0 0/ 2 ' ) = 2s6 - t1400/ 4)
{r} f-1
The seconddelayin cTMR0Pre.cshowsthe delay producedby this calculationand executedin 1,009 cyclesaccordingto the MPLAB IDE simulator. The final two timer delaysdemonstratewhat happensif you incorrectlypollTMR0 duringits operation. In both cases, I setTMR0 to OxFF,and with a 1:256
icnocontroller
BuiIt-in
Functions
103
i*i ,€:
;*'9
ra
prescaler,you would expectthat the delaywould be 256plus 7 or 8 extra cycles. And, this waswhat I got (264cyclesspecifically).In the secondcase,a few cycles in,I write to TMR0 again:This couldbe considereda no operation becauseI am writing TMR0 with the samevalueasthe one alreadystoredin it. When you time the secondcase,you will discoverthat the delayis significantly different than the first. In my case,it was 429cyclesinsteadof the 264of the first case.
The difference is that I am writing to TMRO. Even though I am not changingthe value of TMR0 (and this canbe confirmedin the simulator),the write operation alwaysresetsthe prescaler. This is true for wdtes to any timer that hasa prescaler(e.g.,TMR1).For highJevel programming,this is not an issue,but it will be when you are programmingin assemblerand you just want to testthe valuein the timer.Make it a rule to always savea timer valuethat hasbeenread somewhereelse.
tfi
Experiment 38-Long TimerDelagsUsingTMHI
nal rrt 9""S fi!
Table5-8 TICONFlegister Eit Name
Number Function
TlGINV
&{
TMR1GE
{tt .r* '.L
t
Lir &.; iJ x i
]
I
! -
Onceyou haveworked with TMR0, you will not have any problemsusingTMR1 ro provide the samedelay functions.Looking at a block diagramof TMR1 (see Figure5-11),you shouldseea lot of similadtiesto TMR0. The major differencesare thatTMRl's operation is controlledby a dedicatedregister(TMR0 has somefunctionsspecifiedin the OPTION register), TMR1 canhavea uniqueoscillatorassignedto it, and, mostimportant,TMR1 is 16bits in size.ThesedifferencesmakeTMR1 quite a bit more flexiblethan TMRO and one that you shouldconsiderusingin all your applications. TheT1CON register(seeTable5-8)is usedto control the differentexecutionaspectsof TMR1, including its sourceand prescalervalue.In rnanyapplications, a 32.768KHzwatchcrystalis connectedto TMR1, giving the PIC MCU a real-timeclockcapability.The overflow output of the clock can be usedas an interrupt requestsource,similarto TMRO.Or it canbe usedin
,?r
Timerl Gate Invert (1 = ExternalTMR1 control bit is activelow) 6
ExternalTMR1 Control Bit Enable (1 = TMR1 controlledby extenal control it whenTMR1ON is set)
T1CKPS1:0 5:4
TMR1 PrescalerSelect(0b11for 1:8. 0b10for 1:4.0b01 for 1:2,0b00 for 1:1)
T1OSCEN 3
EnableExtemal Oscillatorwhen set
_TISYNCH 2
Resetto SynchronizeExternal Clock to InstructionClock
TMR1CS
1
TMR1 Clock SourceSelect(1 = Extemal clock,0 = Internal instructionclock)
TMR1ON
O
Set to EMble TMRl
two functions of the Enhancetl CapnrdCompard PI{M (ECCP) module,which will be demonstratedin more detail in the next experiment. I createdcTMRl.c to demonstratethe code requiredto createa 300ms delay: *incluale /* c1'!tR1. c - T!|R1 Denonstslalion This TllRl
Droglam tlemonBlrat€s Haralware.
the
op€raEion
of
the
myke prealko 0{ . 11.29
*i t..
!&
CoNFrG(INTIO & WDIIDIS P!9R,TEN & MCIJRDIS I'NPROTECT \ & UIIPROTECT & BORDIS & IESODIS FCr'rDrs ) ,
Figure 5ll
BasicTMRI
104
l , A 3 P f C @i l C U E x p e r i m e n t s f o r
i.;
the EviI
6enius
&
//
Itse Tl41 for
a 300 ns alelay
Parameter
cTMEl.c
PIC MCU Instructions
22
File RegisterBytes
0
2
ProgrammingIterations
1
tt
l)
1.,, 3
T1CON = 0b0011000L, //
TvaL O|r/lnternal 8x Preacale! TMR1E = ( 5 5 5 3 5 - ( 3 0 0 0 0 0 / 8 \ l > > a i a 300 ma alelay // InltialLze (55535 - (300000 / 8)) & oxFEt = ITMR1IJ a, ll Enable PeriDhelal In!€rrul)ts = 0t
TIIRIIF
lllJ,i Peatliag InlerruDt off RequeatE TUR1IE = 1r to // Eaab1e |!URl. O!'erflow Requesl rnts (lTuRlIF)r while // waits fo! tn{R1 to Ovelflow Here - Tfurc lo Previous NOP()' // Br€alr9oirt //
(1 == tr,
lrhile ]
Enil
//
ll
Loop
For€ver
cT!41
Looking at cTMRl.c, I was impressedwith its simplicity and wonderedhow it comparedto the standard for loop delaythat I usein mostof this book.The test caseI ffeated is the following cTMRlAna.c: *incluale cTMRlAna. c - coale Baseal 300 ms Denoastlatl,on /* proqlen lhis solution to
al€nonstrat€s cllMRl. c.
th€
equlvalent
coale
qyke plealko 04.rL.29
CONFIG(INTIO & }IDTDIS & PI{RTEN & !{CLR.DIS & UNPROIrECT \ & T'NPROIECT & BORDIS & IESODIS & FCUDTS), ungigrr€at
int
It
rnain ( )
(
//
rql X
Table 5-9 ComparingTMFIIto for Lcop DelagE
nain( ) t
uee coae for
NOPOr
//
a 300 ns alelay
BreakDoint
for (i = 0t i < 27272, 1++t, NOPO, Eer€ // Brealgroinl whil€ |
//
ba
(1 =-
1)r
//
cTMElBna.c
- T:i:r0€ to
b
o
P!€vLoua
Loop Forevor
o
F
rf
cTMRltAna
Table 5-9 comparesthe two programs over a number of parameters.The Programming Iterations parameter is the number of times I changedthe final value of the constant in both programsto get a delay that was within 300,000cycles.This measurernentconsistsof how many times I had to changethe code,rebuild it, andretestit with the simulator'sStopwatchto get the specific delay.I wasn't surprised that usingTMR1 for longer delayswasbetter than the for loop; I was surprised at hovt much better TMR1 was Aside from producing code that is two-thirds the size of the for loop, the TMR1 delay was also much faster and easierto get working correctly. The obvious question that arisesfrom this analysis is why people use the for loop to create delays.I believe two answersexist to this question.First, most low-endPIC MCUs (andlow-endmicrocontrollersin general)do not havea 16-bitcounteravailablefor delays,so they have gotten into the habit of creating a delayusingthe for loop.Second,simplynobodyhas thought to do this analysisbefore.But if they had, the better delay would be obvious,and maybe somebody would have written a macro to produce the delay.
H€re
(r) 6
I
r
o 4
q €
l,r,
u o X
U
o
ts 0, \< CI
a
F.
5
q
Fl
K
n H S e c t i o nF i v e P I C l , b F h A qH i c r o c o n t n o l l e n
Built-in
Functions
105
;*
Experiment 39-ComparingClockOscillators
;.* *
.pl ,$ PIC16F58 4 Prc12F5?5 t
:
"r!
2 MIIZ oscillator
t-:
4 MHz clystal
d3
4 MHz celamic vrith internal
*E ij
DMM
I
NeedIe-nose pliers
1 470O resistor
Breadboa!d
1 l0k breadboard-mountable potentiomete!
Wiring
e
kit
33 pF capacitors
t-
i* ,:-*
{'i {*,
tlx i:-: {.-f {'f
t
,sl .:* ;*
di #
".4 :,.t $ {,1< i..a ,'.: 1:l:
4. ?k tesistor
0.01 p,F capacitors
a--.: ."
resollato! capacitols
Part of the evolutionof the PIC microcontrollerhas beenfor Microchipto provide accuratebuilt-in oscillators,freeingthe applicationdeveloperfrom the chore of selectingand wiring a clockcircuit into his or her applications. For peopleleaminghow to developapplicationsfor the PIC, this wasanotherpotentialproblem area:If the clock circuitrywasnot correctlywired,then the applicationwouldn't work.This is not a concernfor you.The oscillatorsbuilt into the PIC16F684and PIC12F675are surprisinglyaccurate,allowingyou to usethem insteadof externaloscillators.In this exoeriment.Iwantlo look at the accuracy oI thedifferent oscillatorsavailableto the PIC MCU. The mostefficientmethodof testingdifferentclocking circuitsis to usea frequencycounteror an oscilloscopewith a measurementoption.I realizethat most peopledo not havethis equipmentavailableto them, so in this expeiment I will usea very simplecircuit that will giveyou a goodvisualindicationof the accuracy of the different clocking methods.I will run two PIC MCUs (a PIC12F675and PIC16F684)at the sarne time,usingthe sameprogram,and then passa counted-downoutput to the differentpins of an LED (seeFigure5-12).For simplicity,I put both PIC MCUs on the samebreadboardasshownin Figure5-13,using a long breadboardto allow for lots of spacefor the different clockoptions. If the two freQuencies are identical,the LED will light and the brightnesswill not change.If the frequenciesare different. the LED will flash on and off. The
L06
I
22 pF capacitot
I
SPST breadboald-mountable switch
1 Three-cell crip
AA battely
3 AA batteries
slowerthe flashing,the closerthe two frequenciesare. If you are familiarwith tuninga musicalinstrument, you will understandexactly how this works. In this circuit. I will tse a cannedoscillator to drive the PIC12F675; this deviceis a highly accurateclock (usuallyto within 10Hz for a 4 MHz device)that is usedasa referenceclock.The PIC16F684clock will be changedto one of the four differenttypesavailableto it.Along with the internalclock,or cannedoscillator like the PIC12F675uses,the PIC16F684can be clockedusingone of the threecircuitsshowin Figure 5-L4.Thesecircuitsare connectedto the oscillatorpins of the PIC16F684. For this experiment,I am assuming that eachclock is runningat 4 MHz (the mostcommon clockspeedfor PIC MCU applications). The codeI usedfor the PIC12F675wascalled c675Clk.cand usesTMR1 to count down 5 ms before togglingthe output of GPIO0.ThePIC16F684uses appropriateregisternamesand similarcode,exceptit dividesthe constantby 4 rather than the 8 of C675Clk.c. To testthe differentoscillators,the only changes madeto the PIC16F684codewere in the confisuration
l , P 3 P I C @l l C U E x p e r i m e n t s f o r
the Evil
6enius
14
Prc16F684
x
PtclzF675
0.01 uE
tld 0.01 uF
o
Fl F.
3 o
5 ct (, -
I:
to
tI '
2 MHzOsc Enable
OscillatofPins
Figufe 5-la
Clock circuit
I
n
o 3 id s, n
Fr.
p
fuse clock specification.Theclock polling loop does not produce an exact 100IIz output;it actually outputs 99.78IIz due to overhead of the loop and the polling of the TMR1 registers I could have tuned this to an exact frequency,but by keeping the code constant between the two PIC MCUs,I didn't feel this was necessary.The differencesin clock speedswould show up asflashing LEDs. In Table 5-10,I have listed the different PIC16F684oscillatorsused,their output ftequenciesmeasuredby my oscilloscope(nominally 100Hz), their LED flashing rate, and the configuration fuse specification usedfor each. To try and improve upon the accuracyof the resrsnr/capacinr (RC) oscillator,I replaced the 4.7k resistor with a 10k potentiometer and tried to tune the signal.This proved to be quite difficult, and I never was able to closely match the PIC16F684'soutput frequencyto that of the PIC12F675. Next, I drove the PIC16F684using the cannedoscillator to look at the accuracyof the PIC12F675'sinternal oscillator.The PIC16F684'sinternal oscillator automatically usesa programmed calibration value,
q
o
ts
o o ?f
o (n
Figure 5-13 Long breadboard usedto test different PIC MCU 4 MHz clocking options
o
but the PIC12F675'sinternal oscillator can optionally run with calibration. I wascurious to find out how accuratethis clock was.Theresults are in Table 5-11. To enable the PIC12F675'scalibration. the followins
ts 0, ct
Fr. F
o rt
a S e c t i o nF i v e P I C I h F h B q H i c n o c o n t r o l l e r
Built
in
Functions 102
Crystal
Resistor/Capacitor
(Rc)
H
T"
a'!
F{
r-f .rl
PrcMcu ?un clkln -----
PIC Muu l"ru MCU
Pin
Pin
v, O
I:
T"O' Htn
t !
Figure s-lq
Clock options
codestatements(takenfrom the PIC12F675 datasheet)were addedto the start of the application: //
#aam baf
f,n
(l H
.-{
1{
a) *J'.1
X td
loaat
cLock
3, 5
RPO caLL 03FFh Getscalibrat€vaLu€ 010h
(Jt
+
PICMCU ClkOut Pin
r-l
iI
^--ilr\,----l--l
Optional 100- 200Ohm
PICMCU Clkln------------l
tl
LI rr{
lT
CeramicResonator
,r4
Li "FN
Clkout
I
U
s
PICMCU Clkln Pin
i
Ca1iblation i
b.f
t
call
gTATus,
morrlrf OSCCAL ^ 0x90 bcf STAIUS, r
RPO *enalaam
To get the PIC MCU's actual operating frequency, the scalingfactor 40,080is multiplied by the 100Hz output. This is the ratio between 4 MHz and the 10,022 cyclesthat were measuredin the MPLAB IDE simulaTable 5-10 EomFaringOifferentPlClSFEBr.l Clocking0ptions to a Fleference
tor for one complete output cycle.Using this factor, the PIC16F684's internaloscillatorruns at 3,987976H2 (0.3%error);the resonatorruns at 3,995,992H2(0.1% error); the crystal runs at 4 MlIz; and the RC oscillator runs at 3,330,662 Hz (16.77oenor).The PIC12F675's uncalibratedclockis 4,2U/49 Hz (5.6% effor), and its calibrated clock runs at 4,092,784Hz (2.3Y" enor). The obvious conclusionfrom this experiment is that the PIC16F684's internalclockand the PIC12F675's clock are quite good and are sufficiently accuratefor virtually all applications.The applicationswhere these clocksare not adequatewould be timing measurement (e.g.,in frequencycountersand real-timeclocks).In thesecases,either a cannedoscillator or an extemal crystalwould haveto be used.In older partswithout a
Table 5.11 PlE|aF675InternalOscillatorFccuracg
Clock Tcpe
Measured LEU Frequencg Flash Eate
_CONHG clock Parametef
Ealibration
Measured Frequencg
None
105.4Hz
severavsecond
Intemal
99.5H2
3 flashes/second
INTIO
Using CalibrationCode
102.7Hz
several/second
Resonator 99;7 IIz
2 flashes/second
XT
Crystal
993H2
1 flash/6seconds
XT
RC
83.1I{z
many/second
RC
l.08
l , P 3 P I C @l ' l C UE x p e n i m e n t s f o r
the Evil
LED Flash EaIe
Genius
builtin oscillator,the RC oscillatorcanbe used.But remember,you can't expectthe accuracyof the oscillator to be in the samerangeasthat of the crystalsand ceramicresonators. I shouldpoint out that the resultsof this experiment,althoughreasonable, are not completelyaccurate due to the limited samplesze of parts.Still the purposeof the experimentwasto showthe different oscillatorsavailableto the PIC MCU. how thev are
wired to the chip,and how they compared.When you repeatthis experiment,you may find that different partsbehavedifferently,and althoughthe overall resultswill be similar.the measuredvalueswill most certainlybe differentfrom mine.For this experiment to be completelyvalid,a largesamplesizeof the different partswould be required,and thesepartsshouldbe chosenover a wide rangeof manufacturingdates.
tl.;i !.' J 1t
::ar
ExFerimentt-.|0-Timedl/O Pin Flesistance
,,,-,'i'
Measurements Usinethe CCP
I
Pr c 1 6 F 5 8 4
1 10 LED balgraph
display
1 10of,) res i"stor t
10k breadboard-mountable potentiometer 470f,) 10-pin
1.,'.
resistor
'f:',1
2 0.01 pF capacitors
T,oo1 Box
1 SPST b!eadboard-mountNeedle-nose pl iers
able
Breadboard
fhree-cel,I clip
Breadboald
wiling
kit
switch AA battery
AA batteries
i1' i'-:j: L:i
Even if you are a teenager,I'm sureyou'veseenthe earlyvideo games(like "Pong"),in which the userwas givenan analogcontrol.The first home and personal computersalsohad analogcontrols,the joystick being the mostcommon.But did you alsoknow that 20 years ago,analog-to-digitalconverters(like the onesbuilt into the PIC MCUs) often costrrore than basicmicroprocessors? The ability to readpositioninformation wasvery importantin theseearlygamesand simple computers,but addingan ADC chip wasout of the questionbecausethe cost. Imagineyourselfasa designerof one of thesesystems.How would you providethe ability to read a potentiometer(whichwasnormallyusedto read the positioninformation)?You could usea comparator and a programmablevoltagereferenceasI haveused, but thereis a mucheasierway to do this-by measuring the time it takesa chargeto passfrom a capacitor throughthe potentiometer.If you havereadmy previous123RoboticsExpeimentsfor the Eytl Genius,you
would know that the ParallaxBASIC StampII hasthe ability to time how long it takesfor a chargeto pass througha resistor(seeFigure5-15).In Figure5-16,I showwhat the electricalsignallooks like.First the capacitoris chargedby an I/O pin, and then the I/O pin changesto an input to allow the capacitor'schargeto passthroughthe resistor,with the delayfrom being fully chargedto reachingthe I/O pins high-to-low thresholdbeingapproximatelyproportionalto the potentiometer'sresistance. As a rule of thumb, the maximum time delay for the circuit in Figure5-15is:
l:1;,
ii: r:,. i
f, !':l
TimeDelay=2.2XRe.tXC
So,for a 10k potentiometerand a 0.01pF capacitor, you would expectthereto be a maximumtime delayof approximately 220 ps. I say"approximately" because potentiometersand smalicapacitorsare not known for
S e c t i o nF i v e P I C l h F h 6 t { I ' il c n o c o n t n o l l e n
BuiIt-in
Functions
1.09
tlr rl": ,,,".,
The obvious way of timing the code would be to start a timer and save its value when RCPin changed state as in the following code:
vcc
I" Fiqure 5-15
rctimefunction
RCPinTRIS = 0i // Make RCPin an Output RcPin = 1., // c})arge capacitor ( i = 0 r i < o n e r n sr i + + ) , for / / waiL fot Charging RCPinTRIS = 1r // llake RCPin anal Intrrut TMRo = 0r // Rese! the Tirne! (0 l= RCPin) t while / / warL for Pin to Go Low = lltlll.Oi Potvalue // Save the Pot Value 'i" proportionaL // contains a value to the ResiBtance
But a betterway is to usethe Capturemodeof the ECCPTimer Generator.This function will savethe contentsof TMRl at an externalevent.Usingthe ECCP module,there'sno needto savevaluesor worry abouthow many instructionstake placein a loop or beforeor after the loop.The circuitry for this experiment (seeFigures5-17and 5-18)is quite simpleasis the code,which I call cPotTime.c.
Figure516
Pot rea(l ----
their accuracyand you couldhaveyariancesof up to 20 percent. Unfortunately,the rctimelunction isn't availablein the PICC Lite compilerlibrary of functions,and it can not satelybe programmedin by simplyusinga few C statementslike the lollowing:
Figure 5.117 Pot read circuit
RCPiflTRIS = 0r // Make RCPin an Output RCPin = 1r // C}rarge Capacitor (i = 0r i < onensr i++)t for // :i::"i:; RCPinTRIS = 1r // l4ake RCPin anal hput for (i = 0r ((i < fivems) && (0 != RCPin))r i++)t "i" contains a value ploportional // to the Resj.staltce
This is true for two simplereasons:the executiontime of the secondfor loop is not known and the returned valuefor i is proportionalto the resistanceof the potentiometer.If you havelooked at someintroductory PIC books,you may think this statementis wrong: many PIC bookspresentcodethat canbe usedto find the resistanceof a potentiometer,but the example codeand projectsin thesebooksare written in assembler whereeachinstruction(and the time requiredto execute)is known,not in a high-levellanguagelike C.
110
Figure 5.18 Breadboardwiring for the potentiometerreadcircuit
l , P 3 P I C @l l C l J E x p e n i m e n t s f o r
the Evil
Genius
When you look throughthe cPotTime.ccodeyou'll noticethat it waswritten without usingany variables. All the delaysare providedby TMR1, which is loaded with constantvaluesinsteadof the contentsof variables.I havenot explainedthe operationof the Capture modeof the ECCq becausewhenyou are first startingout, therearen't that many applicationslike
this one whereyou can take advantageof it. But you shouldbe ableto figure out how it and Comparemode work if you feel they havecapabilitiesthat you would want to take advantageol The lessonI want to impart with this experimentis that if you havea problem,it can often be solvedby looking at the datasheet.
Ul-Eenerating PtUM Experiment SisnalsUsingthe CEPand TMRa I
The PWM generatorfunctionbuilt inro the PIC MCU's ECCP is the latestand probablythe most andusefulpulsewidth modulation sophisticated (PWM) generatorthat I haveseenon any microconPWM generatordepartsfrom troller.ThePIC16F684's the typicaldesignby providingthe capabilityto intelligentlyinterfacedirectlyto high-currentmotor drivers software.As without interveninglogic or sophisticated I will showin a later experiment,it is an ideal basefor an intelligentDC motor controller.Thisexperiment, howeveris somewhatmore modest.It will simply introduceyou to the operationof the PWM generator hardwareand demonstratehow an LED's brightness canbe changedwith a PWM signal. Before explaininghow the PWM generatorworks,I shouldprobablyspenda few linesexplainingwhat a PWM signalls.A PWM signal(seeFigure5-19)consistsof a repeatingdigital signalin which the time on is variedto control the amountof power that passesto a device.PWMs are typicallyusedin DC motorsto control their speedbecausethey are much more efficient output power supply.Thetirue than a variable-voltage on is usuallyreferred to asthe duty cycleand is measured asa percentageof the total cycletime of the repeatingsignal. The heartof the PWM is the TMR2, which is a repeatingtimer driven by the PIC MCU's instruction clock.When enabled.this timer will count to the value
S e c t i o nF i v e P I C I t F h g q
LED
in the PR2 registerand then resetitseli TMR2'Soperation is controlledby the T2CON register(seeThble 5-12)andhasa prescaler,which dividesdown the which dividesthe incomingclock,and a postscaler, provide a delayedeventindiall to resetsignaldown, to usethe PWM postscaler is not required The cation. generator.WhenTMR2 is run in a PIC MCU that has a 4 MHz signal,a prescalervalueof 1:1,and PR2 equal ro 0xFF (255),the TMR2 (andPWM) period is 255ms (or 3,922kHz), The PWM generatorcircuit (seeFigure5-20)uses the resetcommandftom the PR2/TMR2magnitude comparatorto set the output in an RS flip flop.The currentvalueof TMR2 is continuallvcompared
PWMOn DutyCycle= PWMPeriod Fisure5-19 PwM
icrocontroller
Built-in
Functions
111
Table 5-? T?CONBegiEterDefinition
Ftc..Label
Function
7
Not Used
6:3
TOUTPS TMR2 Output Postscaler, 0b0000is a 1:1
Table 5-13 ECPIEONFlegisterBits Belatinsto the PIIJM6enerator Blts
Label
Funclion
7i6
P1M
PWM Output ConfigurationBits
Postscaler, 0b1111is a 1:16Postscaler
u, r-{
m
2
TMR2On
Must be setfor TMR2 to be operational
1:0
T2CKPS
TMR2 Prescaler
0b11for Full-Bridgereverseoutput (P1B Modulated,P1C Set,P1A/P1DReset) 0b10for Half-Bridgeoutput (P1A, P1B Modulated,P1C/PID Port Pins)
0b1xfor 1:16Prescaler
0b01for Full-Bridgeforward output (P1D Modulated,PlA Set,P1B/PlC Reset)
0b01for 1:4Prescaler 0b00for 1:l Prescaler
brt
0b00for Single(standard)output (P1A Modulated,P1B/P1OP1DPort Pins)
.r"i
CCI
5.4
DC1B
3:0
CCP1M ECCP mode selectbits
\r F
0b1111for P1A/P1C:/PlB/P1D Active Low 0b1110for P1A/P1CActive Low, P1B/P1D Active High
F g{
trt
Leastsignificanttwo bits ofPWM compare value
0b1101forPlA/PlCActive High,P1B/P1D Active Low
Figure 5-20
0b1100for PlA/P1C/P1B/P1DActive High
PWM block diagram
0b0000for CCP/PWM Off
l.{
"tJ d 11
0 $
13 II ?.,{
.-l
s
P..
X KT
againstthe value in the CCPR1L register,and when it is greater than the value in CCPR1L, the RS flip flop is reset.If the valuein CCPR1Lis greaterthan the value in PR2, the PWM output will alwaysbe high.This is what the basicPIC MCU PWM generator provides. But the PIC16F684hasadditionalcircuitryknown as the output controller, which can be usedto simplify the control of different types of motor controllers. In Thble 5-13,I havelistedthe relevantbits of CCP1CONas theyrelateto IhePWM generator. when I work with the PIC MCU CCP PWM,I generally work only with the most significant eight bits of the PWM Counters and ignore the two least significant bits.The extraaccuracyprovidedby the leastsignificant two bits is generally not required. In Figure 5-20,I imply that the PWM compareregister(CCPRIL) valueis comparedagainstthe valuein PR2.This isn't strictlythe case;the valueof CCPR1Lis bufferedand useduntil PRz is reset.Thisis done to ensurea larger valuefor CCP1RLis loadedin, causingthe PWM output to go high unexpectedly.To keep everything simple for your initial PWM applications,Irecommendthat you either passa single PWM signal from the module (on P1A, or RC5) or work with full H-bridgescontrolled asshown in Figure 5-21. When the UO pins are describedin the MicrochipPIC16F684datasheet, the labelsP1x (wherex is A, B, C, or D) are usedexclusively.To try and avoid some confusion,in this experiment,I haveincludedtheselabelsbut alsoincludedthe traditional pin namesaswell.
112
Motor Power
PlA (Foruvard Active)
P1B (Reverse Modulated)
Figure 5-?l
P1C (Reverse Active) P1D (Forward Modulated)
PWM full H-bridge contol
I realize that I have thrown a lot of information at you regardingthe PWM generatorbuilt into the PIC16F684, but it is actuallyvery easyto set up and work with. I will showjust how easyin the following expedment,which varies the brightnessof an LED accordingto the positionof the PICkit 1 starterkit's
l , A 3 P I C @f l C U E x p e n i m e n t s f o r
the Evil
6enius
potentiometer. Unfortunately, none of the PWM outputsare connectedto any ofthe LEDS on the PICkit 1 starterkit, and,further complicatingmanners,P1A (RC5) is not available on the PICkit 1 starter kit's inline socket.Fortunately,RC2 (P1D) is closeto the socket'sgroundpin, so you put an LED into the PICkit 1 starterkit to demonstratethe operationof the PIC MCU'S PWM by varying the perceivedbrightnessof the LED. In this experiment,I wantedto take advantageof cADC.c, which readsthe voltage coming from the PICkit 1 starterkit's potentiometerbut alsodisplaysit as a binary value on the eight LEDs. A single LED can be wired from RC2 (P1D) to groundon the PICkit 1 starterkit (seeFigure5-22)to demonstratethe operation of the PIC16F684's PWM generator.The code written for the application (cPWM.c) is quite simple, with the only additions to cADC behg the TMR2 enable,the PWM enable in full-bridge output forward mode,andthe ADCValuereadby the PIC MCU's ADC passedto the PWM valueregister(CCPIRL). *includle CPWU - Dia!,lay /* r! LED Brightnesa
lhe PICkit Level
Pot
Input
Value
ADCSlale
iat iat
= 0,. ADgvalue Dlay = 53,
//
of ADC
tr1
X
r,ED Tlm€ oa D€lay variabl€
F?{
= {0b010000, 0b100000, 0b010000,0b000100, 0b100000,0b000100, 0b000100,0b000010], conBt cha! TRIgAValue [8] = {0b001111, 0b001111. 0b101011,0b101011, 0b011011,0b011011, 0b111001,0b111001)t const char NOTPORIAI8I = lO, O, O. O, O, O, O, Ojt conal
nain(
char
P O R T A V a I U e[ 8 ]
E'tr'.a of.f
//
ANSEL = l.t // .tuat ADCONo = 0b00000001, // Turn // BiE // Bil // BiE / / BiE // BfE ADCON1 = 0b00010000,
Colllrarators
RAo is on 7 6 4r2 L 0 -
an Aralog
F{
7V
the Alc .tuEtified Left Itae ltDD - Channel 0 Do dot Stalt Turn on ADC lh€ // Seldrct Eoac / I
s
Input
F
S.np1e
, I
Clock
aE
EaabLe PwM with Active Eigh No Tura on/off Delay ttake RC2/P1D OutDuts Active
Ptcu].coN - Ot ll TRISC2 = O, ll -
0x040, //
Stall
//
PWU at
Iatellnedliate
&
TU P1D
//
Loop
F"t vt
valu€
& & == 1)
6) t-t
Eh€ Ful1 Range // I'uR2 on wltsh No PrescaLe!
ccP1coN = 0 b 0 1 0 0 1 1 0 0 r
whil€(l.
}J.
.'ts
PORTI = 0t CltCoNo = 7r
CCPR1IT
$
t1
F)
)
t
PR2 = 0x0EF, // wolk T2coN = 0b00000100r
pletlko
( INTIO & IID1IDIS & PIIRTEN & IICIJRDIS -CONFIE I'NPROIECT \ & IINPROTECT & BORDIS & IESODIS FCMDTS ) t
// ' KeeD rrack Operation
aB
Thia Drogram aarq)leg the voltage oa RAo uElrlg lhe ADc ana DiaDlaya lt usl.ng a Pwtt va1u6 on trP1Dn (RC2). ThiE Program ia ale8lgn€al fo! the rryk6
= 0t
iDt
Foieve:.
,-, " }{
q
t ints i,
j,
kt
f , o r ( i = 0 r i < 8 r i + + ) / / Loop through Each of, lhe 8 I,EDS | for (j = 0t j < DIaYt j++)t // Diaplay tron" Delay lJoop if ( (aDcvalue & (1 << t)) == 0) PORIA = NOTPORTAIiIt €1Ee PORTA= PORtAValue [L] , TRIIIA e TRISAVaIlle lil t , // rof ErtrlEch (A.DcstaEe)
//
ADc staEe uachine
t
Fieure 5-?? LED anodewired into the PICkil I starter kit connector at RC2 (third pin from bottom) with its cathodewired.to ground (bottom pin)
caBe 0: star! N€xt salllrl€ // Finiaheil, GODONE = 1, ADqgtat€++i breakt caEe 1: for ADc tso conDlete / / wait ( lGoDoNE) if ADCState++t // S€mp1e Finishetl break; case 2: // Sav€ SarDLe Value in nADCVaLu€tr = ADRESII, ADcltalu€ .e.Dcgtat€ - 0; breakt , / / rLcEiwa
S e c t i oF n i v e P I C I h F h A Tl + li c r o c o n t r o l l e n B u i t t - i n
Functions 113
ry ,Zt
td Ft
&3 F,. € tsa
gr #3
) l
I . = ( k + 1 ) % 1 0 t
//
Irl)date
(0 -= k) if CCPR1IJ = ADCVaLue,
//
sinply Change the PWM Value to Change the I.ED Output'
PVIM Every
100
// elihw // Enat cPl'Dl
Two pointsshouldbe notedaboutthis application. First,becauseI decidedto usethe full-bridgeoutput modeof the PWM generator,pins RC5 (P1A),RC4
(P1B),and RC3 (P1C)cannotbe usedin the application. If this werea stand-aloneapplication,I would recornmendthat you use the single-outputmode of the PWM generator(CCPICON loadedwith 0b00001100) and the LED connectedto RC5 (P1A).Thesecond issueis that whenI simulatedthe application(in MPLAB IDE version6.60),therewasn'ta CCPR1L registeravailable;insteadtherewasa CCPRL register, whichperformsthe samefunction.This discrepancy will orobablvbe fixed in later versionsof MPLAB IDE.
ExperimentU2*5toring and Fletrieving Dat a Us in gEE PF OMMe mo rg EEPROU_WRITE(unsigneat cha! ulsigneal ehar EEPRouData) i
An often overlookedfeatureof the PIC MCU is the EEPROM datamemorythat is built into the flashbasedchips.EEPROM is an acronymfor electrically programmableread-onlymemory.In the PIC erasable MCU, EEPROM consistsof a numberof bytesthat canbe written to with the expectationthat the value written will still be therewhen the chip is powered down and then poweredback up sometime later.This expectationcannotbe madeof the staticrandom accessmemory(SRAM)-basedfile register'sthat loosetheir valueswhen the PIC MCU is powered down.EEPROM datamemory(often referredto as srmplyEEPROM) rs callednonvolatile to indicate that it retainsits contentsevenwhenpowereddown.Not surpdsingly,the SRAM-basedfile registersare saidto be volatile.The flashprogrammemoryusedin the PIC MCU is a variationof EEPROM with sliehtlvdifferent operatingcharacteristics. To accessthe EEPROM datamemory a seriesof assemblylanguageinstructionsare used.Fortunately, the PICC Lite compilerprovidestwo library functions that can be usedto read and wdte the EEPROM. Their prototypesare asfollows: (unaign€al unsign€al cha! EEPROM,REA.D EEPROMAdItITeSs ) ;
114
EEPROltIAalalresE,
The PIC16F684has256bytesof EEPROM while the PIC12F675has128bytesof EEPROM. Therefore, the maximumEEPROMAddressis 0xFF and0x7Ffor the PIC16F684and PIC12F675, respectively. The data valueis a full eightbits,which meansthe valuestored at eachEEPROM locationis in the ranseof zero to 0xFF (255decimal). The typicalusesfor the EEPROM includesaving calibrationvaluesor savingconstantsinsteadof creating constants.To demonstratethe operationof the EEPROM,I createdcEEPROM.c,which will initialize the EEPROM memoryof a PIC16F684with a standard pattern (0x00,OxFF, OxAA,0x55)so that on subsequentpower on cycles,the storedvaluewill be recognizedasvalid.The valueat the next address(or zero if this is the first power cycle)will be displayedon the eightLEDS of the PICkit 1 starterkit.When the button is pressed,the ADC will be read and the value will be displayedon the LEDs, and whenthe button is released,the ADC valuewill be storedin EEPROM for the initial displaywhenthe PIC MCU powersup. *incLude CEEPROM - Display /t if Butston Preeseal
the
Saveal EEPRO!{ Value/llDc
Thia program Displays a gaveat EEPROM value ItnleEE th6 Button on RA3 is D!€ss€tl and then the a.DC is Displayeal. When the Button is Released, the ADC Value is Saveal in EEPROM. Thia coale is baseal on ncADc.cr. ttvke prealko o4.12.20
cha! -CONFIG
( I1!:!IO
& WIITDIS
l , e 3 P I C @l ' l C UE x o e r i m e n t s f o n t h e E v i l
& PWRTEN & !'ICIJRDIS &
Genius
I'TVpROTECT\ FCUDIS) t
InI int irlt int lnt
& IJNPROTECT & BORDIS & IESODIS
I, J' AItCStsat€ = Ot ll KeeD Track = 0t ADgvalue = 0i Buttsonstat€ Dis91ay, olalDisDlayt
of
&
Lf
ADC Ol,€ratioa
{
7 5 4r2 L O -
ADcoNl = 0b00010000, if
Inpu!
// T.Irln on lhe IJeft iluslif,iedl Use vDD - chaDnel 0 Do nol SlarE tnrrn on ADC
ADC Samlrl€ ) I
// soromct the clock as FoEc/8
((0 == EEPRoT'r-READ ( o ) ) && ( o'rFF == EEI'RorrREAD(1)) &&
(4) r Dispray = EEPRoM-READ
( 1 , onEr ) r EEpRo!'r,wRrrE Ox55) '
= 0t
== 1)
//
Loop
Forever
t f o r ( i = 0 r i < 8 r i + + ) Each of th€ I { / / Loor, thlough (j = 0, j < Dlayr j++), for ll Di-Bp lay "On" D€Iay l,oop ( (DiBpIay & (1 << 1)) == 0) if PORTA = NOTPORTAIiI t elg€ PORTA = PORTAVaIUe [i] t ARISA = TRISAVaIU6 lil t j Eof ll
X
trd
0
r-{ F.
{0
Ft
l& t\ I
I
en
To test the application rather than continually plug the PICkit 1 starter kit or the PIC16F684 in and out. you can control the power to the PIC device in the plCkit 1 starter kit by clicking on,.programmer" and
PIC MCU'S RA4 pin.
( 3, o,rAA), EEpRoM_wRrrE EEpRoM wRrrE({, o)r // No rnirial
while(1
- Displayt oLtlDiaDlay = Ii Buttonstate DiaDl.ay = ADRESET ADCgEate = 0t breaki // hctiwg ) // elihw // Entt clDc
that comesup will giveyou the option of turning on or off the power to the PIC MCU in the PICkit 1 starter kit's socketaswell aspassinga 2.5kHz clockinto the
;t"" (o, o) , EEpRoM-wRrrE
Diaplay
tql
F.t
thenon"Properties"intheMPLABlDE.rhewind lsa
l3lfi ==ll|l!il_ffili]i,*
E E P R O MW R I T E ( 2 ,
R€leaseal
ADcgtsat€++t broaki case 1: // WaL1cfot }DC to cornplete if ( lcoDorrE) ADcstate++r // sarE)le Finishedl bt€akr case 2. // Save sarq)le velue in trADcvalu€n if (0 -- Buttonstale)
In in( )
AItCONo = 0b00000001r I / BLE // Bil ll Bi,E / / Bj.E / | BiE
Button
GODONE = ]'t
0b011011, 0b011011, 0b111001,0b111001)r conat char M)rPORTAISI = {0, 0, 0. 0, 0, 0, 0, 0}t
T.lrrd off comparator8 .fus! RAo is an Ana1og
//
| ll fi } €Is€ // Button PreEs€al Ewilch (nlrcSlate) // ADC State Machine t case 0: // riaiBh€al, gEar! Next SsrDIe
0b101011,0b101011,
// //
!= RA3)
A.Dcgtale - 0t // Resel .e.DCOperation (0 != Butlonslate) if HaE AI'C // Diaplay value ( EEPRO!{_!fRITE ( 4, Disl)lay), DLaDlay - OlalDisDlayt = 0i Buttonstale
iat Dlay = 53i // LED Tine on D€Iay varlable conet cbar PORTAvalue [ 8l = {0b010000, 0b100000, 0b010000, 0b000100, 0b100000, 0b000100, 0b000100,0b000010)r conat char TRISAVaIUe [8] = {0b001111, 0b001111,
PORTA = O' C!|CON0 = 7, .aNSEL = 1r
(0
IJEDS
value
s 5
To test this application, burn the cEEPROM.c code into the PIC16F684 and let the PICkit l starter kit exe-
cute as it would normally. Next, pressthe PICkit 1 starterkit's button and turn the PICkit 1 starterkit's potentiometer to somevalue (which will be displayed on the PICkit 1 starterkit's eightLEDs). When the button is released,the power up valuewill be displayed,but after cyclingthe power on, the PICkit 1 staderkit the PIC16F684will displaythe valuepreviouslysetinto the EEPROM usingthe buttonandthe
potenbometer.
41-
F r'n ht t"r, fia
ly
\
r,,.
H *J !'.l
F-t \J $! -* n! i4
S e c t i oF n i v e P I C l , h F h A qH i c r o c o n t r o l l e r B u i l t - i n
Functions 115
Section
Six
InterfacingProietrtsfor the PIC@ Microctrntroller
DMM NeedIe-nose
plie!s
B!eadboa!d Wiling
I
Plc16F68 4
470f) resistors
I
7451383to8decoder
100f,1 resistors
1 74LS174 hex D fLip
flop
2 0.01 pF capacitors
2N3906 PNP transistols 1 fwo-line,
16-colulrm
I
Seven-seghent displaY
lk
svritch matrix keypad with an eighto! nine-pin breadboa!d inte!face
LCD
1N914 (1N4148) silicon
1 Seven-row, display
(any type)
1 16-button
1
coilnon
1 Dual seven-seghent LED display
kit
diode
corlnon
five-column
LED
cathode
ano
LED matlix
Breadboard-mountable push button
1 Three-cell 1 Two-cell
AA battery AA battely
3 AA alkaline
resistor
Before I start demonstratinghow the PIC MCU interfacesto other digital electronicchips,I feel it would be usefulto reviewthe basicsof digital logic andnote someof the important characteristicsto keep in mind when you are creating applications with the PIC MCU There are literally dozensof different logic technologies, eachwith differentoperatingcharacter-
Breadboard-mountable SPDT sw j.tch (E-Switch EGl903 reconanended) momentary
On
pack pack
battelies
istics.I've listedthe mostpopular onesin Thble6-1. For the different varieties of TTL, C,AC, and HC/HCT logicfamilies,the part numberstartswith 74, and the 4000seriesof CMOS chips have four-digit part numbers,startingwith 4.Table6.1liststhe characteristicsof the different types of logic chips you will want to work with:
',17
Table 6-1 Digital LogicTechnologiesuith ElectdcalCharacteristic-5 thlp Tcpe
VT
r!
H F,r.{ htr "t{
tl
6
t!F{
ti $ .&,r X t"J
I
X
.*l
n '.'d t l
dll
PoLuerSupplg
6ate Delag
lnput Threshold
O Dutput
I Output
Output Sink
vdd - 0.7
25 mA
3.3V
\2 nA
3.4v
5mA
3.4v
8mA
3.4v
40 mA
Vcc-2V VcN- 2V
20 mA
3.5V
20 mA
PICMCU
Vdd=2to5.5V
N/A
50% vdd
TTL
Vcc : 4.5 to 5.5V
8ns
N/A
LTTL
Vcc - 4.5 to 5.5V
15 ns
N/A
LSTTL
Vcc : 4.5 to 5.5V
l0 ns
N/A
STTL
Vcc - 4.75to 5.25V
5ns
N/A
AS TTL
Vcc : 4.5to 5.5V
2ns
N/A
ALS TTL
Vcc = 4.5to 5.5V
4ns
N/A
FTTL
Vcc = 4.5to 5.5V
2ns
N/A
0.6v 0.3v 0.3v 0.3v 0.5v 0.3v 0.3v 0.3v
c cMos
Vdd=3to15V
50 ns
0.7Vcc
0.1Vcc
0.9Vcc
3.3mA*
AC CMOS
Vdd=2to6V
8ns
0.7Vcc
Vcc-0.1V
50 mA
HC/HCT
Vdd=2to6V
9ns
0.7Vcc
Vcc-0.1V
25 mA
4000
Vdd=3to15V
30 ns
0.5vdd
0.1v 0.1v 0.1v
vdd-0.1v
0.8mA*
Tt1eoutput sink ctfrrentsare specifiedfor a power voltageof 5 volts If you increasethe power supply voltageof the indicatedCMOS parts(notedwith an asterisk),you will also increasetheir output cunent sourceand sink capabilitiesconsiderably. In this table,I markedTTL input thresholdvoltage asnot applicablebecauseTTL is current driven rather voltagedriven.You shouldassumethat the current drawn from the TTL input is 1 mA for a 0 or low input. CMOS logic is voltage driven, so the input voltage thresholdspecificationis an appropriateparameter. Knowing that eachTTL input requires a current sink ofjust over 1 mA and mostTTL outputscansink up 20 mA, you might expectthe maximumnumberof TTL inputs ddven by a single output (which is called fanout) to be 78 or 19.The actualmaximumfanout is eight to ensurethere is a comfortable rnargin in the output to be ableto pull down eachoutput in a timely manner.Practically,I would recommendthat you try to keep the number of inputs driven by an output to two but neverexceedfour. Somedifferenttechnologiesthat you will work with do not havethe sameelectrical drive characteristics andmay not be designedto pull down eightinputsof anothertechnology;so, to be on the safeside,alwaysbe very conservativewith the number of inputs you drive with a single output. The output current sourcecapability is not specified becausemany earlychipswere only ableto sink current. This wasall that was required for TTL and it allowed extemal devices,such asLEDs to be driven from the logic gate'soutput without any additional hardware,andit simplifiedthe designof the first MOSFET:basedlogic chips.The asterisk(*) in Table 6.1 indicatesthat the sink cuffent specificationis for 5 volts of power; changingthe power supply voltage will changethe maximum current sink capability aswell.
118
8mA
There are threebasicoutput types:totem pole,open collector, and the tristate driver, which is presented later in this chapter.In caseswheremultiple outputs are combined,different output t)?es shorj'ldneverbe combineddue to possiblebus contention. The TTL output (seeFigure 6-1) is known asa ntem pole outputbecauseof its resemblanceto its namesake.If you were to connect a totem pole output to a TTL input and measurethe voltage at the input or output pins,you would seea high voltage,which the gate connectedto the input would recognizeas a 1. When a low voltage is output, the TTL gate will respondasif a 0 wasinput.What you are not measuring is the current flow between the two pins.
"High" Output Control Current
Output Pin,Can EitherSource orSink Current
"Low" Output Control Current Figure 6-'l
l , P 3 P I C @l l C l JE x o e r i m e nt s
for
TTL totempole output
the Evi I
Genius
Output Pin,
EffectiveOperation Sional ,^-__,,,
NPN
Output Control Current
ulrpu
_-,-
<j"'p"r
"'
I
I Tn-gate Conirol
Transistor CanONLY PullPinto Ground
LogicSymbol
t,:,!
Figure 6-a
TTL open-collectoroutput
Thereis anothertype of output that doesnot source any currentand is known asthe oper?collector(or open-drainfor CMOSlogic) output (seeFigure6-2). This output typically hastwo uses.The first pulls down voltagesthat are greaterthan the positivevoltage appliedto the chip.Normally thesevoltagesare less than 15V and cansourceonly 10 to 20 mA. For higher currentsand voltages,discretetransistorsmust be used.The seconduseis for dottedAND bussesin which multiple open-collector/open-drain outputsare tied togetherwith a singlepull-up-the output is at a high-voltagelevel aslong asall the output transistors are off. Totempole outputsare the recommendeddefault gateoutput becauseyou caneasilycheckvoltagelevels betweenintermediategatesin a logic string.You cannot usea volt meter or logic probe to checkthe logic levelsif a TTL gateis driven by an open-collectoroutput.Additionally,if a CMOS input is connectedto an
Figure 6-3
Tri-statedriver
i'i'i
open-collector/open-drain output then therewill be no high voltagefor the gateto operate.An open-collector/open-drainoutput can be usedwith CMOS inputs if a pull-up (typically10k in value)is addedto the ouf put.The only caseswherean open-collector/opendrainoutpulshouldbe usedis whenyou arewiringa dottedAND gateor are switchinga power supplythat is operatingat a voltagedifferentfrom the gate's power.
:-*1
:.
The third output type,the tri-statedriver, can nol only sourceor sink currentbut can be turned off to electricallyisolateitself from the circuit that it is connectedto (seeFigure6-3).This type of output drivers is usedon the PIC MCU IiO pins. Exceptin the conditionof open-collector/opendrain driversbeingusedto ddve CMOS inputswithout a pull-up resistor,thesethreeoutput typescanwork with all of the digitallogic inputslistedin Table6-1. t-;:.
Experimentq3 - Drivinga Seven-SegmentLEDDisplag Directlgfrom the PlElSFEBq P rc 16!'68 4
;,.€
Seven-segrmeot common cathode LED display 0.01 pF capacitor tYpe )
(any
Breadboa!d-mountable (E-Switch SPDT switch 8G1903 recomnended) Two-cell pack DMM
AA battery
AA batteries
Needle-nose pliers Breadboard Wiring
S e c t i o n5 i x
kit
Interf acing Projects
f or
t h e P I C @t l C U
t-ri
119
h'r' t'fi
ai,1
I found this experimentto be very satisfying.In about a half-hour,I wasable to make it displayeachof the 10 digitson a seven-segment LED, with a half-second delayin between.This includedmodifyingcodethat I stolefrom other applicationsto executethe application finding out the wiring wasnonstandardon the seven-segment LED I usedfor my prototype.I expect that you will be able to createyour own versionof this applicationand seehow easyit is to createa usefuldisplay usinga singlePIC microcontrollerin short order. The basisfor the experimentis the seven-segment LED display(seeFigure6-4),which is normallywired rn a commoncathodeor commonanodeconfiguration. The schematicdiagramfor the seven-segment LED displayin Figure6-4showshow a commonanodedisplay would be wired.Even if you havea nonstandard LED display(asI have),you canplot seven-segment out the commonpins and the pins for eachsegmentin just a few minutes. The basic10 digitscanbe displayedby turningon the LEDS for the differentsegmentsasshownin Figure 6-5.Additional characterscan be producedusing differentsegments. Although other than the six most significanthexadecimaldigits (A, B, C, D, E, and F), you will be hard pressedto comeup with all the alphabeticcharactersthat look good on this display(for example,M). The liquid crystaldisplay(LCD) display discussed later in this sectionis a much better tool for this task. The circuit for this application,not unexpectedly, poweredby two alkaline consistsof a PIC16F684, radio batteriesand driving a seven-segment LED display (Figure6-6),and can be wired very simplyon a breadboard(Figure6-7).Theactualcircuit is very similar to othersthat you havecreatedalthoughwith a different LED display.Simitarly,the applicationcode (cTSegment.c) shouldnot hold any surprisesfor you.
7-Segment LED
Figure6-6
Figure 6-7 Singleseven-segment LED experiment circuit on a breadboard
*incluale c?SegmenE.c - RoIl /* Segment LED Diaplay
':
thlough
10 Digits
on 7
Thia program will each of the Decilra1 aliaplay dligilB on a 7 Segmen! Cormon Calhodle LED Display. Earalware
3
Seven-segment L E D circuit
aA5 RC5 RC{ RC3 Rc2 Rc1 Rco
-
Notes:
Segment a Segrnent b Seg:nent c Segment tl segment e seqment f gegment g
nl'k€ pr€ilko 0{ . 11. 10
Figure 6-q
Seven-segment LED display
*/ CONFIG(ITVIIO & I'IDTDIS & PWRTEN & MCLRDIS & IINPROTECT \ & UNPRCTIIECT& BORDIS & IESODIS & FCIIIDIS) t
int codst
i,
i, char
kt LEDDigit
Fiqure 5-5
Seven-segment numbers
L20
l , e 3 P I C o l l C l JE x o e r i m e n t s f o n t h e E v i I
t10l
= {
6enius
10
// RRRRRRR - PIC15F584 Pin // ACCCCCC / I 554321-0 - LED Segmonl abcdef,g // 0b1111110, 0b0110000, 0b1101101, 0b1111001, 0b0110011, 0b1011011, 0b1011111, 0b1110000, 0b1111111, ob1].11011) t
fo! (i = 0r i < 255r i++) // for (j = 0r j < a29, j++\, DLgit Digtt Digir Digit Diqit Diqit Disit Digit Disit Disit
// // // // // // // // // //
zeto One rwo Three Fou! Five Six Seven Eight Nine
nain ( )
t PORTA = 0, PORTC = 0, C!|CON0 = 7, ANSEIJ - 0, TRISA = 0b01U11; TRIsc = 0b000000t
k = 0r $ht1e(1
--
!>
Conparatsora / / TIlxIL oft // Tuln of,f, tlDC // RA5 iB an Oulput // A1t BibB of PORTC are olrtputa al
Digits
//
Starl
//
Loop Foreve!
0
RAs= LEDDisi![k] >> 6, // PORTC = rEDDisittkl
k = (k + 1) %10, l ,
Sinll'le Delay l,oop
Ld
li;"??!"
"t"" ""
& 0x03F,
,,
llillil"olr*,"nr" i-r
// ellhv // E'rdl cTgegmenl
In the applicationcode,I do want to point out that I storedthe digit pattemsin a 10-elementaray and that I tried to make the bit specifications assimpleaspossible for the programmer(includingmarkingthe segment lettersand the I/O pin over eachbit of the array).With only sevenwiresrunningfrom the PIC MCU to the display,I felt I could work at making the program assimple aspossiblefor the programmer to coffectly define the set pin outputs required for each disit.
: :!.;4
r.
Experimentqq -
MultipleSeven-SegmentLEDBisplags
'tl
n Prc16F684 2N3906 PNP tlansistors
L
Dual seven-segmedt commo!! anode LED display
i
1o o,f) resistols 0 .01 FF capacitor tYpe)
(any
B!eadboa!d-mountable (E-Switch SPDT switch 8G1903 recornmended) Needle-oose
plj,ers
Breadboa!d
Two-cell pack
Wiring
AA alkaline
kit
There are a number of ways to add multiple seven-segment LED displaysto an application.You could route seven(or eight,if the decimalpoint is required)PIC MCUs to eachdisplay.You could use a comrnercially availableseven-segment LED driver chip (the7447is most commonly used) for eachdisplay.You could also usea commerciallyavailablemultidisplaycontroller
S e c t i o nS i x
p
battelies
chip (suchasthe MAXIM MAX7219). Or you could programthe application'sPIC MCU to sequence throughthe displays. The latter methodis surprisingly easyto do and involvesthe leastamountof hardware. Thereare a coupleof pointsthat you shouldbe aware ol however,that I will presentin this experiment.
Inten fac i ng Proj ects
for
. t )
AA battely
t h e P I C @t l C u
L2t
t
The first is,you cannotdrive the commonanodeor cathodepin usinga PIC MCU I/O pin.The PIC MCU I/O pin cannotsourceor sink enoughcurrentto light all sevensegments. Instead,I usea commonNPN bipolartransistorfor commoncathode(seeFigure6-8) displaysor a PNP bipolar transistorfor common anodedisplays.These transistorscan be controlledby either a PIC MCU IiO pin with a proper base-currentlimiting transistoror by a data-selector logic chip (asI will showin the next section).You might be surprised to discoverthat commonanodedisplaysare most often usedbecausethey can be usedwith 74xr series logic data-selectorchipsand PNP bipolartransistors. To sequencethroughmultiple seven-segment LED displays,the controllinginterfacedeviceoutputsthe valuefor a speciticdisplaywhile enablingonly its common pin transistorasshownin Figure6-8.Togive the appearancethat all the displaysare activeat the same time and avoidflickering,you mustrun throughthe entire sequenceat least50 timesper second.This meansthat for the four seven-segment displayexample,eachdisplaycan be activefor a maximumof 5 ms To demonstratethe operationof multiple sevensegmentLED displays,Icreatedthe simplecircuit shownin Figure6-9.I havenot beenspecificon the type of dual commonanodeLED displayto use becausequite a bit of varianceexistsin differentpafis and you may find someinexpensiveonesthat are wired differentlythan the standarddisplays.Alldisplaysshouldhaveconnectionsfor the segmentsaswell ascommonanodesfor eachdigit display.Thedisplays that I usedwire a singlepin to eachsegment,necessitatingtwo connectionsfor eachsegment,which resultedin the rather messywiring of the circuit as seenin Fieure6-10.
r,m
ffi Figure6-9
Dual seven-segment LED circuit
Figure 6-10 Breadboardwiringfor clualsevensegmentLED displaycircuit
#incluale - Ro11 through c2*?Seg.c /' 7 Segment LED Display
15 DigitE
ThiB program nri11 aliBplay each aligits on two 7 Segm€nt Codfiron Displays.
Second
The codle/wiling that Nesativ€
---'-----*
Eardlware
I
1 <-
aA5 RC5 RCll RC3 RC2 RC1 RCo
-
Segment Segnent S€gment segment Segnent Segiment segment
ThirdDigitDisplayed
is baseat on "cTsegment.c'i Activ€ LED wiring is useat.
a b c tt e f g
7 segment 7 segment
Display Display
Inyke prealko 04.42.09
Figure 6-8
Multiple LED operation
L22
l,El PfC@ CU Exoeriments for
orl a Dual
of the Her. 15 Cathoal€ LED
Notes:
Right Ireft
FourthDigitDisplayed
ffi
Dual 7-SegmentCommon AnodeLED Display
the Evil
6enius
Noting
( Ilvrlo & v{EtlDIs & P!{R!EN _coNrlc I'NPROTECT \ & I'NPRCIIIECT & BOBDIS & IESODIS
L, j, DisDlal^Ialue,
l'at iat
& MCLRDIS
RA5 = r,EDDisit [ (Diapla]ryalue >> {) & 0r0Fl >> 5t PORlrc = IrEDDigtt t (Dl.ap1ar/Va1u€ >> 4) & 0x0Fl & 0x03F, | // fi TRISA = TRISA ^ 0b0111ur // Sloap leftlBighl PORTA = PORTA & 0b1U100, // Make gure BitE
&
& FCUDIS) '
DisDLeylEDt = DisDIayIrED
DiEplayLED RRRRRRR
//
NoPOr for (i
= 0t Di aplat4lalue = 0i DiapIaYLED == 1)
// ll // //
NoPO, l = j + 1r (25 == j) if
// //
i
Errt *, }
DI'LE
/ / U s e f l f o ! 1 0 m a Tinids < 550, i++)r / / 10 ma Delay IJoop / / u s e i l f o r 1 0 m B Tining
= 0r
t_*
-
p
Inc!€menl th€ counler? 1/4 Seconal Paaaeal?
Diaplayvalue++t j I ] |
{ PORTA = 0, POREC = 0, CMCONo = tt ANSEIJ = 0, TRISA = 0b011101t TRISC = 0b000000;
oE}ret Ne'I!
t d
t
nain ( )
$tra| of,.f Cornpalatola $)zn otf. AN R}5/RA1/RA0 are OulDuta Alt BitsB of POBTC are Outputa
// //
DiBplayl.ng Stalt at DlB!,lay lhe 1a fLrat
//
IJooP Forever
0x00
{ if
//
LEDDigit tl = { - PIC16F58{ Pin
/ / 5543210 // abctl€fg - r,ED segmellt 0b0000001, 0b1001111, 0b0010010, 0b0000110, 0b1001100, 0b0100100, 0b0100000, 0b0001111, 0b0000000, 0b0001100, 0b0001000, 0b1100000, 0b0110001, 0b1000010, 0b0110000, 0b0111000)t
while(l
^ lt
t l t
(0 == DiEDlayrJED)
{ RA5 = IJEDDigir lDiaDla]ryalu€ PORTC = rJEDDl.ltLr[Dlsplat/Value
& 0x0Fl >> 5, & 0x0F1 & 0x03r',
Increm€nt lhe counler another 1/4 geconal //
= 0t // rte3el // 1A // elihw // E^d. c2x?Seg
for
The basicapplication,incrementingthe displayonce every 250ms to count from 0x00to OXFF,is quite simple and is calledc2xTSeg.c.There really shouldbe no surpdsesin the codeother than the fact that segment valuesfor eachbit are reversedfrom cTSegment.c becausethe PIC MCU are connectedto the display's cathodesinsteadof anodes. The two NOP0;instructions aroundthe final for loop wereplacedthere to giveme somewhereto break and to ensurethe applicationdelayed10ms,givinga 50 timesper second update speedfor the two displays. After creating c2x7Seg.c, I thought it would be fun to comeup with a czxTSegPc in which the lightedsegment seemsto run aroundthe two displays. These typesof displaysare quite easyto write and a lot of fun to watch.After watching this, I can't help but think theremustbe a simplegraphicalgamethat couldbe createdusingseven-segment LED displays.
!
's l 1
p'
ffi 41X
r*,t
) eLse
tsr€
-.{: tt*
S e c t i o n5 i x
Intenf acing Projects
f or
t h e P I C @l l C U
L23
r-15-LEDMatrixDisplags Experiment
1 Plc16F68 4 1 74SI383to8decoder t
Seven-!ow, LED display
five-col,umn
4?OO tes istols 0.0I pF capacito! tYpe )
B!eadboa!d-mountable (E-Switch SPD! switch 8G1903 reconmended)
Needle-nose plie!s
thlee-cel1 pack
B!eadboard Wiring
kit
Seven-segment LED displaysare excellentfor displaying numericdata,but whenyou havecharacterdata, their usefulness reachesthe end very quickly.A number of differenta/phanumericLED displzysexist.The mostbasictype is the 14-segment LED display,which is similarto the seven-segment displaythat you just experimentedwith. However,due to the specificposilions of differentsegments, it's difficult to make all the differentcharactersrecognizableon a 14-segment display.T\e dot-matrix LED display allows arbitrary charactersto be displayedwhile usingfewer I/O pins than the 14-segment LED display,but it requiresmore work to useand plan how to build your characters. The dot-matrixLED display(whichI calljust an LED matrix) consistsof a numberof LEDs arranged with their anodesand cathodesasshownin Figure611.By pulling a columnconnectionto positivevoltage, individualLEDs canbe lit by connectingthe appropriate row anodesto ground.For this experiment,I useda 5-columnby 7-rowLED matrix,but if you look around,you will discovera numberof differentsizes are available.Regardlessof their size,they will be driven usingthe samemethodologyasshownhere. Using a 4700 resistor,the batteryclip,and a couple of wires,you canfigure out the wiring of your display.I startedby connectingpin 1 (the top left corner)to negative voltageand then scanningthe pins to try and identify the sevenanodes.I wasnot successful at light ing any LEDs, so I repeatedthe procedurewith pin 1 connectedto positivevoltage.OnceI startedgetting LEDS to light,it wasa simpletask of identiflng the functionsof the variouspins andmappingthem out on
L24
(any
AA alkaline
AA battely batteries
a sheetof paper.In doing this,I discoveredthat the rowsconsistedof the LED'S anodesand the columns werethe LED'S cathodes. The 5X7-LED matrix displaythat I usedrequires 12pins to operate;althoughthe PIC16F684is quoted ashaving12 I/O pins,it actuallyhasonly 11 I/O pins and oneinput pin. RA3 can only be usedasan input, so to take advantageof all 35 LEDs of the matrix that I used,I had to comeup with someway to multiply the
Row 0 Row 1 Row 2 Row3 Row4 Row 5 Row 6
Col
Col
Col
Col
Col
Figure 6-11 LED matrLr
l , E 3 P I C @I ' l C l JE x p e r i m e n t s f o r
the EviI
Genius
umn of LEDs is wdtten at the sametime and eachcolumn is scanned.This is similarto the dual seven-segment LED displayexperimentand givesthe appearancethat eachcolumnis activeat the same time.cMatrix 2.cruns throughthe first four characters of tlie alphabet.
5x7LED
-: - --r-
#includle 2.c - Display cMatrix /* r,ED DiEplay
Soine Letlera
on 5x7
l
I
74L5174 Figure 6-l?
MatrLrcircuit
numberof operationalpins.In this application,I used a 74S138decoderto providethe columnnegative power supplyselect.The selectionof the S technology decoderwasselectedover the more commonLS technologyto sink the mostcunent (LEDS fully lit) aspossible.This allowedme to usethreepins to select betweenfive columns,requidnga total of l0 pins to control the LED matrix.Thecircuit that I cameup with for this applicationis shownin Figure6-12.Note that I tried to arrangethe wiring in sucha way that the anodes(rows)are all driven by PORTC (with the seventh bit beingpassedto RA4), while the cathode's (columns)pull-downdecoderis selectedby the three leastsignificantbits of PORTA.
8A0-Decoale!0gelect RA1 - Decoale! 1 Select Rt2-Decoaler2Select aA{ - Anoale 5 Rco - Anoale 0 Rc1 - A$oale 1 Rc2 - Alotl€ 2 Rc3 - Atroale 3 Rc{ - Alotl€ 4 Rc5 - Anoit€ 5 nyke predko 04 . 12. 04
& WDTDIS & PWRTEN & MCLRDIS & -CONFIG(INTIO UNPROTECT \ & UNPROTECT & BORDIS & IESODIS & FCfiDIS), int
i,
const
j, char
k,
n,
Dlay,
lJ€ttsers[]
CurLettert = {0b1111110,
Start
//
0b0010001, 0b0010001. 0b1111110, 0b0000000. 0b1111111. //
To testout my mappingof the LED matrix and how presumed I to wire the application(seeFigure6-13),I createdcMatrix 1.c,which turns on eachLED in the matrix in sequence. With the LED matrix and driving circuit behaving asI expected,Ithen createdcMatdx 2.c in which a col-
0b100L001, 0b1001001, 0b0110110, 0b0000000, obo1,141,1,o, 0 b 1 00 0 0 0 1 , 0 b 1 00 0 0 0 1 , 0b0100010, 0b0000000, 0b1111111,
with
Next r,etter
//
nct
//
Einal
0b1000001. 0b1000001, 0b0111110, 0b00000001t
nain( )
{ PORTA = 0i PoRTc = 0b000001t CMCOIiIo = 7t a.NsEt = 0 t TRrSA = 0b101000t TRrSC = 0t Curletter
= 0t
// // ll // //
ALl Bits are Low stalt with Top lreft altrrL off compalatols off rrDc $rrn na5/RA3 Input8
//
start
wit'h
'A"
Fisure 613 5x7 LED matrix driven by a PICl6F684and 745126
S e c t i o n5 i x
Interfacing
Proj ects
for
the PICo llClJ
125
while(J.
== al
ll
Iroop tlorever
t (Dlay = 0r Dlay < 50r Dlay++) for for (i = 0r i < 4, i++) Character t // 20 mB to Diaplay * 5) + ilt j = Leteera[(CurlJett€r k = (j >> 2) e 0b010000, PORTC=j&0b1U111, PORITA=k+it for (n = 0t n < 259r n++)r / / 4 mE Delay // tof | Curlfette!
) |
= (Curletter
// elihw / / ED,d cMatrix
+ 1,, e.4,
ll
Increnent IJettser
It is interestingto seethat the characterdisplayis not substantiallylongeror more complexthan the first setof codethat movesthe lit LED acrossthe LED matrix.Most of the work wasspenttuning the 4 ms delayin the displayloop (the conceptusedwasto cycle through eachcharacter over 20 ms,requiring 50 repetitionsto displaythe characterfor 1 second).After mappingthe LED matrix pins and beforewiring the application,I spenta few momentsthinking how to most efficiently wire the application and wfiting out somecodeto figure out the wiring arrangementthat would keepthe codeto asfew instructionsaspossible.
2
E x F er im e ntlt 6 -L C D D i s p l a g
r. Prcr.5F68 4
tri
1 Two-line,
16-column
LCD
1 10k breadboard-mountable potentiometer , . 1
1 0.01 pF capacitor tYpe)
(any
Breadboa!d-mountable (E-Switch SPDT switch 8G1903 recomrnended) Needle-nose pliers
Breadboard-mountable momeotary On push button
B!eadboard
;'-':,:
Wiring
kit
Three-ceLI pack
AA battely
3 AA alka1i.ne
t.a
-;-i
:;i.a r,:,f
Creatingapplicationswith LCDS hasa reputationfor beingdifficulr.I would disagreewith this statement, noting that if you follow a simplesetof guidelinesyou really won't haveany troubles.The circuitpresentedin this applicationcan be built andprogrammedin aslittle as5 minutes.And, if you would like to enhance(or change)the output messageor add more functionality to the application,you will find it to be quite easy(asI will demonstratein the next experiment). In 123RoboticsEtcperiments for theEvil Genius,I includeda fairly comprehensive explanationof how to interfaceto Hitachi 44780controlledLCDs.I am not goingto repeatthat informationherebut will point you to my web site (www.myke.com) whereyou'll find informationregardinginterfacingto theseLCDs and
L26
batt eries
programmingthem.Along with thesetwo references, you'll find additionalreferenceson 44780-based LCDs. I shouldpoint out that 44780-based LCDS are text basedonly and havea 14- or 16-pininterface,andyou canprobablyfind somesurplusor old productsforjust a dollar or two. Graphic LCDs have a different interface and require a completely different interface. The circuit that I usedfor this experimentis shown in Figure6-14,and there are two thingsI want to bring to your attention.Most LCDs require4.5to 5.5volts, not the 3 volts I haveusedup to this point on breadboard circuits.To provide the LCD with the correct voltagelevel,I usedthree alkalineradio batteriesin a seriesclip to provide4.5volts.If rechargeable batteries are to be used(whichproduce1.2volts per cell,instead
- JE x p e r i m e n t s f o r l , e 3 P I C @l ' 1lC
the Evil
6enius
tlitachi 44780 Baaedl LcD This Ptoglaln rnitializes to in 4 Bit Moate anat then vrriues a sfurD1e atring nras useal to tir€ alelay values. it. The simulator can be founal
'.cD write Infomalion hltp: / /www. rnyk€. con
RC3:RCo - I . c D I / O D 7 : D 4 ( P i n s Pin RC4 I.cD E clocking RC5 LCD R/S PiN
at
1{:11)
rnyke prealko 04.11.08
-: I I
Figute6-lq
CONFIG(INEIO & WDTDIS & PITRTEN & I'ICLRDIS & IINPROTECT \ & UNPROTEC!! & BORDIS & IESODIS & FCIiIDIS) i
LCD circuit
int
j,
i,
k,
ni
Use clobal Debug
//
for
variables
Display <- usedt to organize // f23t567B91f23455 "i PIc Mcu const char TogMessage [l = rr "i = " Evil- Genius const char BolMessagel] +define
E
Rc4
*ilefine
Rs RC5
Define contlof
//
Declare a con8tant f o r 2 0 m s Delay
const
int
TwenEf.nr6 = 4250i
const consl
int int
Fivems = 300t TvroHundlrealus = 10t (int
r,cDwrite
iflt
tcDData,
the LCD Pins
//
Rsvalue)
{ PORTC
=
(',CDDaCa
>>
{)
& OxoE i
//
Fisure6-15 LCD breadboard RS = Rsvaluet E = 0t E - 1r
of the 1.5volts per cell of alkalinebatteries),you will haveto usefour in series. Normally whenI presentan LCD applicationfor the first time,I usethe full eight-bitinterface.Inthis case,becausethe PIC16F684only has 11pins with output capability,therewould be no pins left for interfacing.Therefore,Iusea four-bit interface.To reducethe requiredpin count to six,I alsotied the positiveactive read,negativeactivewrlte(RJW)low and don't poll the LCD.The six-birinterfaceusesall of PORTC,leaving PORIA free for interfacingto other devices. Whenyou look at the schematicin Figure6-14,you might be surprisedat someof the pin wiring choices.I wantedto makesurethat the circuit couldbe wired easilyand clearlyon the breadboard(seeFigure6-15). Secondly, I wantedto arange the bits so that the programcouldhandlethem easilywith a minimum of processing. #incluate - write clcD.c /* 4{780 LCD r/E
PORTC = IrCDData
& 0x0Ft
RS = Rsvaluet E = 1t E = 0,
S e c t i o nS i x
to
a 4 Bit
Toggle the Bits out
//
GeL Low 4 Bils Output
4
for
TJow 4
((0 == (LCDData & oxFc)) && (0 == RsvaLue) ) n = Eivemsi // Set Delay IntervaL else n = Tvollunalrealu s t if
(k = 0r k < nt
for )
//
k++)i
DeTay fo'.
//
clEractel
Enal LcDlsrite
nain( )
t PoRTc = 0, CMCONo = 7t aNSEr, = 0t TRISC = 0t
// // // //
Ei.tachi
Intenfacing
High
//
the / / aoggfe Bits Out
!or,t vrith Ev€rything Start B)tn otf Comparators Turn off iulc Alf of PORTC are Outputs
/ / a')iEi.aJ-i,ze LcD accortling j = tltenttzns, (i = 0r i < jr i++)r for a String
Gel Hish { Bits f,or OutsI)ul
Proj ects
for
to //
the
web Page
wait f,or IJCD to Power Up
t h e P I C @l { C U
L2'7
PORTC = 3, E
=
T;
E
=
U'
J = Fivemat f o r ( i = 0 r i < j t
i?. r:
qi; --},,: i"{
#-4
E = 1r E = 0t J - TwoHunalrealuBt f o r ( i = 0 r i < j , E =
r;
= ut
!
j = TrroHunalrealus; for (i = 0, i < jr
rt
start
//
Senal R€a€t. Cdunanal
IJcDwlile(0b0000U10,
//
Repeat
Reae!
Colnnanfl
LcDwrite(0b11000000,
cqmanal
(i = 0, Botuessage lil for LCDWrite (BotMe€sage Ii] ,
//
Rep€at Reset Third Tine
?urn On IJCD antl Enable Culsor
t= 0r i++)
//
Move Curaor !o th6 geconal ].ine
whil€(l
== 1)t
l= 0r i++)
//
Einished
i++), Inittalize Mode
i++)t /l
I.CD is { Bit !/t. 2 tJlne
LcDvlrit€(0b00000001, 0),
/ / Clear
I,cDwrite ( 0b00000110, 0),
/ / llove
]JCD
Curao! After Each Characle!
f!i
//
Erd
cr,cD
LCD 4 Bir
ut
j = TwoHurar€aluat for (i = 0r i < jr
0) t
//
i++) t
//
E =
0),
(i = 0t TopMessageli] for IrCDWril€ (TopMeEEage I i l ,
i++) t
(0b00101000, Ott IJCDWritse
.r-.9
Inilializalion
)
PORTC= 2, E =
//
LCD displaysin electronicapplicationsare useful from a number of perspectives;first they allow you to createverbose,usefulmessages either to yourself(as debugginginiormation) or to the user.Secondly,they add a level of commercializationto an aoDlicationthat givesthe appearance rhala lot morewoik hasgoneinto it than actuallyhas.Although requiring a bit more work to add to a microcontroller project than, saya few LEDs, LCDs can add a lot to your application,and I recommend that you considerthem wheneverit is possible.
j.=.*r
Experiment Q7-ProducingFlandsmNumbers
a :
.# ! ' ?
-"1
I
P I C 1 6 F 5 84
1 tvro-lj,ne,
I6-column
LCD
1 10k bleadboa!d-mountable potenti,ometer
3.,.{
0. 0l pF capacitor tYp€)
x :
Breadboard-mountable (E-Switch SPDf st{itch 8G1903 reconmended) B!eadboard-mountable momentary On push button
Needle-nose pLiers B!eadboard Wiring i,:
kit
fhree-cel1 pack
l'a ,.-1 . ,:'€
i.; ,i!!
i...-;
(any
AA alkaline
Peopleare usuallysurprisedto find out that producing random numbersin a computer systemis an incredibly hard thing to do. Probably one of the most creative methodsfor generatingrandomnumberswascreated by SiliconGraphics,Inc. engineerswho pointed a video cameraat a "Lava Lamp" and usedthe digitizedoutput asa randomnumber.Computersare poor random numbergeneratorssimplybecausethey are designed to work the samewav everv time. and for most com-
L28
AA battery batteries
puter applications, randomresultsare not a good thing. Although very few large(on the order of billions of bits) randomnumbersare requiredwithin microcontroller applications, you'll discoverthat thereare a numberof applicationswherea few bits of random datawould be useful.Computergamesare a common computerapplicationthat usesrandomnumbers,asare other applicationsthat interfaceto humansThe element of randomnesscanmake a gamemore interest-
l , P 3 P I C @l ' C l l - JE x p e r i m e n t s f o r
the Evil
Genius
ing or help keepan applicationfreshto the user.In this experiment,Iwill showyou how the usersthemselvescanbe usedto createthe randomnumbersfor an application. Thismight seemlike a paradox How cana user generaterandomnumbersfor an applicationthat apparentlybehavesrandomlyfor the user?The answer comesfrom the unexpectedtime the usertakesto respondto programoutput.By runningthe TMRO eight-bittimer at full speedand addinga debounced button on a pulled-upinput pin to the LCD display application,a computersystemthat generatesand displaysrandomnumberscanbe built very easily(see Figure6-16). In cRandom.c,I haveenabledthe PORIA pull-ups to allow me to wire to grounda simplemomentaryon switchasmy randominput device.When the user pushesthe button to producea new randomnumber, the cunent valueof TMR0 is read and convertedinto a decimalnumberto displayon the LCD. This techniqueis very simpleand,other than addingthe switch,doesn'trequireany extra hardware. High-endrandomizersproducetheir datafrom such
---Ti.:
I Figure 6-'fE
Randomcircuit
esotericsourcesasthe electricalnoiseinsidea diode. Granted,the high-endrandomizerscanproduceessentially limitlessstringsof randombits,but for most PIC the eight bits that are microcontrollerapplications, producedeverytime a userpressesa button are more than adequate.
l
. l
LED Displag Experimentt-.18-Ttno-Bit l . , i
I
,:. ' r,l
Prc12F6?5
1 74LS174 hex D ftlp I
fl,op
1N914 (1N4148) silicon diode
1 Two-line,
15-column
LCD
1 1k resistor 1 10k breadboard-mountable potent iometer 0.01 pF capacitor tlpe )
Needle-nose pliers B!eadboard Wiring
Three-ceLl
S e c t i o nS i x
Intenfacing
(anY
Breadboa!d-mountable (E-Switch SPD! switch EG1903 recor nended)
kit
A six-wire LCD interface is a great improvement over the full 11-wireoriginalinterface.It's still a lot of I/O pins,especiallyfor the lirnitednumberin the PIC16F684or the PICIZF675(whichalsocamewith the PICkitrM1 starterkit).What is neededis someway of convertinga serialsignal.A serialsignalwould be ideal,and a numberof serialLCD interfacesare on the
. . :
AA battery
market.Thesedeviceshavethreedrawbacks.One is their cost:Theseinterfacescancostanywherefrom $20 to $100.Secondly, they do not work at the speedof the microcontroller.Lastly,neitherthe PIC16F684nor the serialinterface. PICIZF675havean asynchronous Theseissuesdo not eliminatethe useof a serialLCD interface;theysimplymakeits usemore problematic.
Projects
f o n t h e P I C @l l C U
129
A better solutionis the two-wiresynchJonous serial interfaceshownin Figure6-17.The shift register allowsthe minimal condition six-wireintedaceto be usedwith the LCD module.This circuit combinesthe mostsignificantbit (which shouldonly be set whenall the other bits are loaded)and the data line to form the E clock.This methodis obviouslyquite a bit slower than the methoddemonstratedin the previousexperiment,but for most applications, the speedis not a major concern.
-_1 ' ---l J
!
l.-{
T
I
._;
.-+
The actual operating waveforms are shown in Figure 6-18.First the contentsof the shift registerare clearedby shiftingin six zerosand a high bit. Next the RS bit followed by the four databits for the nibble are passedto the 74LS174,which is wired asa shift register.When the data is valid,the data line is strobedhigh and low to load and storethe new characteror instruction into the LCD. When I createdthe codefor this experiment'scircuit,I usedthe codefrom the previous experimentasa base. For this experiment(seeFigure6-19),I usedthe PIC12F675that camewith the PICkit 1 starterkit.You couldusea PIC16F684, but I wantedto usethe PIC72F675as anLCD enabledsensorcontrollerin a (much)later experiment.By creatingthis experiment usingthe PIC12F675,Icreatedthe basethat I would needfor the later sensorexperiments:APIC16F684 (or any other PIC MCU) couldbe substitutedin the
-Ti]-TB-T
--f
Dab
l];-l
tr l
61651ffi
;,0. a -,e.- a"
2q-,o. 36-:c.
F---]-;-EE-fii-r"r-T]JT*-TilitTu-iif-T.iiTfil1;iir--T-$-E?;-
-roo-2oo-la"
4e-iao 5Q-
5ro -!oo - rae-,0
6A_
610 - 5oo- !€o- :0.-,oo-'oc
E 4
'E Active
(60. Data)
Figure 5lB
Two-wirewaveform
Figure 6-fg
Two-wirecircuit
!.!"9
: ; i i
{..
t
circuit. You would simply have to changethe Clk and the Data #definestatementsin the cLCD2Wire.c application with the pins and devicethat you are using, and then make surethe specialfunctionperipheral analogpin controlswill allow thesetwo pins to execute asdigital I/O. When I wired my prototype circuit, I useda long breadboardto allow a comfortableamountof sDace for the 74LSl74shj[tregister. I alsospentsomerime trying to keepthe wiresasneat aspossiblebecauseI want to use this circuit in later experiments.If possible, put this breadboard circuit asideuntil you work up to the sensorexperiments. which usethis circuit asa base.
Figure 6-f7
Two-wireblock diagram
130
l , e 3 P I C @l l C U E x p e ri me n t s f o r
{li
e'i !"*
t-t{ ,i-?
the Evi I
Genius
Experimentt.l9-5tuitch Matrix KegpadMapping
Needle-nose
pliers
B!eadboard Wiring
I
P I C 1 6 F 6 84
0.01 pF capacitols
1 74LS174 hex D flip I
I
16-column
I
diode
LCD
10k resistor
SIP
10k breadboard-mountable t iomet e !
A switchmatrix keypadcan be a very usefultool for enteringarbitrarydatainto an applicationor for applicationcontrol.It canbe so useful,in fact,that you will considerpayingthe often-exorbitantfee for a single keypad.New,they costanywherefrom $25to $100for a 4x4 switchmatrix keypad.With a bit of hunting,you canprobablyfind useablesurplusswitchmatrix keypadsfor a few dollars.But, asthey don't comewith a you will haveto figure out how they are datasheet, wired on your own.Thetaskof r??rpping, or decoding, the keypadis surprisinglyeasyand can often be done usingthe samehardwareasyou will usefor the final applicationthat usesthe keypad.
Figure 6-20 Keypadmappingcircuit consistingot' a keypadconnectedto a PIC16F684driving an LCD
S e c t i o n5 i x
(any type)
16-button switch matrix keypad or nine-pin bleadwith an eightboard interface Breadboard-rnountable SPDT switch (E-Switch EG1903 recoftnended)
1k lesistor
1 10-pin, I
flop
1N914 (1N4148) silicon
1 Two-1ine,
kit
1 fhree-cel1 poten-
3 AA alkaLine
/dA battely
pack
batteries
The keypadI choseto map for this experimentis the l6-pin keypad,shownin Figure6-20,and hasnine pins on the backsidethat canbe presseddirectlyinto a breadboard(whichis why I choseit). The circuit used to map the keypadis basedon the two-wireLCD interfaceshownearlierin this section.but insteadof the PIC12F675,Iuseda PIC16F684to take advantage of its 1l I/O pins.Thecircuit usedin this application simplywireseachpin to a pulled-upkeypadpin with the two leftoverpins connectedto a two-wireLCD interface(seeFigure6-21).
Figure 6-el
I n t e n f a c i n g P n oj e c t s
Keypaddecode
f o r t h e P I C @l l C U
131
The mapping software (cKeyDcode 2.c listed after t h i sp a r a g r a p hi)s q u i t e s i m p l e I. r c o n t i n u l l l vm a k e 5 one pin a low output and scansthe remaining pins to seeif any are low (a key is pressed).Ifan input goes low,it is assumedto be a row, with the column b"eing the output pin.These two pins are displayed on the circuit's LCD.When the key is lifted,the LCD values are cleared and the program resumes its scanning.I have not debounced the inputs, as multiple keypresses would be invisible to the user and not affect the oDeration of the application.I have not included the listing ior cKeyDcode 1.c,as it is a copy oi;a;-rwi,."".-* modified for the PIC16F684 and created as a base for cKeyDcode 2.c. #inclutte cK€yDcoale 2.c /*
- Ket pail
t ._- . Data = 0t for (i = 0' i < 6i i++) {
,
coat€ is
else Data lcDout
Decoale util.ity
aA2 RCo RC1 RCz RC3 RC4 RCs
-
Pin Pin Pin Pi.n Pin Pin Pin
7 6 5 4 3 2 1
Kelrpaal Ket paal Ketrpaal Kepaal Ketrpaal Ketzpaal Kq4)aal
of of, of of, of, of of
Data
RA{
L32
r,
lcDData,
i'It
Rsva]"ue) / / send
Bvte
to
],cD
li
Nvbbl€shi ft ( ( r,CDData >> {) & 0x0F, RsvaLue) t ( r'CDData & 0x0F' Rsvalue) t NvbbJ eshift // Shift out Bvte
& rEsoDrs
//
Twenlyms
//
the IJCD Serial PinE
Declare a Constant fo! ms Delav-
20
!cDou!,
j.nr
Rs)
//
shift out Nybble
i,
< i;
j++)t
Delav
//
f,or
charactel
j;
PoRTA = 0t CMCONo = ?i ANSEI. = 0; TRISA4 = 0, TRTSAs = 0t //
Fivems = 300, = 10r TwoHundreilus (inr
j
rnain ( )
int
= f25O,
= 0t
Enat lcDwrite
//
]
& FcltDrs),
orz34567ago!2345 = nRc'xr: , ' C o hlnn: "t = Defi'Je control
(j
for
& pwRTEN & Mcr,RDrs &
TopMessage [] Botl4essaEe []
*alefilre
Nybbleshifr
End Nybbreshift
//
anc
& BoRDrs
AA5
in! int
Clock the Nybble int the LcD
NOPO, Data = 0,
LCDW?ite (int |
& wDTDrs
Clk
const const
//
((0 == (rJCDData & oxFC)) && (0 == Rsvalue) ) i = Fiv€ms, // Set Detay Interval else a = TwoHuftl-ealst
#alefine
int
//
shift up the Nett Bit Clock uhe Bi! iltto the s/R
j.f
-coNFrc(rNTro I'NPROTECT \ & uNpRorEcr
eonst
//
NoP()t Data = 1r
-t
char char
<< 1t
ait
0t rof
-ctk.= // )
myk€ pretlko 04.12.05
/| const const
= 0t = LcDout
C1k = lt
] Ket|I)aal
out the
Hiqhegt
based on cKeyDcode 1.c
9 of
c1k = 0, // 1.or
if (0 r= (r,cDou! & (1 << s) ) ) Data = 1t // shift
R:A4 _ Data RA5 - clock AA0 - Pin
// irusr rossle rh€ clock
IJcDout= rcDout | (1 << 5) | {(Rs & 1) * (1 << 4))t ror (i = 0' i < 5' i++) // shirt Data c'ut
This ProEram constantl.y Ecarrs the Ketrpaal wireal to RAO-RA2 andl Rco-Rcs ba makingr one pin a tow (trColunnn) anal lhen scanning the pulleat output (trRowr) to 6ee if any are Low pins up r€naining anal lhen alisplays the trCathoale" and nltnodle" oa an attacheal 2 Wire LcD Interfaee. This
clk = 1,
// clear the shift R€Eiseer
// // // //
starl with Evervthing ConEarator Off rurn off ADC Enable r/O Pins
IniEialize LCD accoraling j = Tweatlansi (i = 0r i < jr i++), for
rhe
l , a l P I C @l l C U E x p e r i m e n t s f o r
the EviI
to //
th€
Web Page
Wait for r,CD ro Po\rer I'I)
Genius
Low
( 3,
lBrbblesbifl
j = Fiv€ost for (i = 0r i
0),
//
< jr
// i++)t
trl
gtart
InltlallzaEion Proc€aa Corutantl Seltl Res6t
for (j = 1r j swilch(j )
<= 9,
X
j++)
b
t 0)t Nybbleshift(3, j = T$oHuadlr€ilust fo! (i = 0, i < j; ( 3,
Nybbl€sbift
ReDeat
//
R6aet
case 1l if, ((i
Cormaatl
0),
//
J = Tarofluntllealua i for (i = 0r i < j;
i++);
rDabbleshifr (2, 0)r
//
R€peat R€set rhirit Tinre
I.cD { Bit
raitialize uod€
breahi caa6 2: tf ((I
//
LcD is { Bit 2 Lin€
LcDwrite ( 0b0000000L, Ol,
//
C1€ar LCD
I,cDwlite ( 0b000 001LO, Or,
ll
llov€ Cursor After
r/F,
cas6 3: ((i if {
rurrr On LCD anal Eaable curaoi
ll
(i = 0t lloDll€asag€ [ ll for l= LcDlltite(TogMeEsagetil ' 1) t ( 0b110000 OO, Ol?
(i = 0r BotMeesag€lil for LCDwrit€ (BotM€ssage til , rcbile(J.
== a)
ll
(i
= 1t i
<= 9t
0,
l++)
llove Culsor Seconal IJl,ne
ll
t1) t
0r
to
the
(i )
i++)
Einiah€al Ket'9eal
-
o
F
af
PuII Fiail
ll
Rolr
.t\
Colur|a
tA v I I
l= 51 69 19 == Rc3))
Writ€ Row
a
llrite
{
Co1trl[n
r= j)
Scan the
Down Each 'Colu![ns"
Pi!
to
0,
0t
0t
0,
0,
f-,
cr
ff
o
r
&& (0 == Rc2))
tCDryrite(0b10000101, 0), LcDwrite(j + r0,, 1)r // LCDwrite ( 0b11001000, 0) t r0', 1); lcDt{rite ( i + // wbile (0 == RC2)t | // fi
{ caa€ 1: TRISC5 = b!€akt caae 2: IiRISC{ breakt cage 3l TRISC3 = breakt caaa {: liRISC2 = br€akt caae 5: ERISC1 r breaki case 5: TRISCo = breakt caae 7t TRISA2 = br6akt caae 8: TRISA1 = bleakt caso 9: TRISTAo = br€akt // hctilta )
colurn
t
i++) //
I
breakt caae 4: if, ((i
{ avLtcb
vrrire
Ft F. =1
&& (0 == Rc4))
LCDwrit€(0b10000101, 0), ( j + r0,, 1)r IJCDDrrit€ // I.cDwrite ( 0b11001000' 0) t lcDvEite (i + r0', 1)r // while (0 -- RC3)t
t for
Rolt
lcDwrtte ( 0b10000101, 0) t r,cDwrlte(J + r0', 1)r // wtile LcDwrite ( 0b11001000, 0) t + t0,, 1)r lcDvEite(i // write while (O == RC{)t , ll fL breakt
Each Cbaracler Ot,
t= j)
writ€
{
( 0b00101oOO,olt lI,CD0EIfite
LCDWrit€
o
&& (0 == Rcs))
I,cDtflite ( 0b1000 0101, o); + t0', 1), LcDwribe(j // lcDwrltse ( 0b110 0100 0, o)t 1), lcDwrl.tse (i + r0,, // lthLl€ (0 == RCs),
cdurenal
j = TaroHuadr€auEt fo! (t = O, I < J, i++),
T,CDw:.it€ ( 0b0 0001L10,
l= j)
{
i++)t
Wril6 Rolt wrlt€
coluan
b!€akt
caae 5: tf ((i != j) && (0 == Rc1)) t LCDwrIt€{0b10000101, 0), LcDwrLt€(j + r0', 1)r // vlrile Row Lcryrrtr€ ( 0b11001000. 0) t LCDIYIit€( j. + r0,, 1)r // Wrile Colu$! while (0 -- Rc1) t ll ti, breakt case 6! it ((i l= j) && (0 == Rco)) t LcDvfritse ( Ob10000101, 0) t lcDwrile (j + r0,, 1)r // Wtite Rort LCDwrit€(0b11001000, 0); IJCDg{rile ( i + r0,, 1)r // Wtile Coluffi vhile (0 -- Rco)t
9' cf r-l l-r.
x
X o r<
rd 0, g
0t
breakt caaa 7l lf ((i
0,
!= j)
{ LcDwrite(0b10000101, 0) t + r0', 1), lcDyElto(j // writse Row LcDwrile(0b11001000, 0), LCDWtile(i + r0,, 1), // Wrlt6 CoIutB while (0 == RA2)t I // EL br€aki
0t
0t
S e c t i o n5 i x
Interf acing
Projects
f o n t h e P I C @l l C U
3 s
p,
&& (0 == Rr2))
1.33
6
F. Lt
uq
((i
if
t
&a (0 == RAl))
!= i)
r,eDwrile(0b10000101. 0) t
+ \O', L)i LcDwrite(j // rcDwriLe (0b11001000. 0) t + \O', r), lcDwrite(i l/ $rhi1e (0 == RA1) t // fI I break; ((i
if
!= j)
write
Column
&& (0 == RAo))
t LcDwrite (0b10000101, 0) t + .0,, 1)r r,cDwfite(j // wrire (0b11001000, 0) t Lcrfirite LCDWrite(i + \0,, 1)r / / w r i t € colurn while (0 == RAo); // fr l bleakt // hctiws ) lcDwrite ( 0b10000101, 0) t '. 1), I,cDwrite(' // Clear Row lcDwrile (0b11001000, 0) t I,cDwrite ( r \, 1), // C1€ar Column TRIsc
= 0b111111,
//
Restore Everything lligh for Next
TRISA = 0b001111t j // rof // elihw ) / / E'ld cKeyDcoale 2 ,
After runningthe program,I createda tablethat mapsthe rows and columnsfor eachof the keypad's pins (seeTable6-1).The numbersafter "Row" and "Column" indicatethe keypadpin numbers,not some definitionof row and column. As I saidpreviously,I useda keypadwith a nine-pin interface-pin 9 is neverlistedasa row or column. Testingthe keypadwith a digiralmultimeter(DMM),I discoveredthat pin 9 is an additionalrow pin that gets pulled low whenthe "2nd" key is pressed. This feature allows"znd" to be pressedalongwith the numberkeys to indicatea hexadecimalnumber.I will usethis keypad (and the informationprovidedhere) aspart of a sensorcontrol module,and,insteadof usingpin 9, I havecomeup with a methodof enleringin hexadecimal valuesby recordingthat"2nd" waspressed.
Table 6-1 Sample KeUpadDecodingN4atrixlNumbers "FIDLU" "Column" beside and are the kegFad'sFin numbersl EolumnI Eolumn2
Column3
Columntl
Row 8
"2nd"
DownArrow
Up Arrow
ENTER
Row 7
9
6
3
HELP
Row 6
u '7
5
Row 5
r5{
4
2 1
0 CLEAR
When I seean interestingkeypador switchmatrix keyboard(often built for old homecomputersystems), the easeby which it canbe decodedis what leadsme to finally chooseit. In this experiment,Ishowedyou how to map a keypad;the processof mappinga keyboard is exactlythe same-it simplyrequiresmore I/O pins.Although you might be temptedto map the keypad usinga DMM, why don't you try out this application with somethinglike a PIC16F877A?This chip (supportedby the PiCC LiterMcompiler,so the ckeyDcode2.capplicationcanbe usedasa base)provides up to 33 I/O pins,which meansthat you will be ableto map keyboardswith up to 31 I/O pins with two pins Ieft over for the two-wireLCD interface.
For EonEideration Although it is goingbeyondthe scopeof this book,I did want to presentyou with the conceptof interrupts and how they canperform somepretty amazingtricks. Interruptsare specialsoftwaresubroutinesthat executewhena hardwareevent(e.g.,a timer overflowing, a pin changingstate,databeingreceived,or a conversion operationbeingcompleted)takesplace.These subroutinesare usuallywdtten to be independentof the mainlinecode,with flag bits or data variablespassing the resultsto the mainlinecode.Interruptscan reduceyour applicationcoderequirementsby up to 80 percentand variablerequirementsby 30 percentor more.It canbe difficult structuringan applicationto useinterruptsand makingsurethey do not negatively affectthe operationof the applicatlon. The executionflow of the interrupt subroutine,or handler,is shownin Figure6-22and stafiswith a hardware eventrequestinga responsefrom the intenupt handler.Whenthe processorrespondsto the request, the curent programcounteris savedand the stateflip flopsin the processorare set to indicatethat an interrupt is beinghandled.Executioncontrol is then passed to the subroutinehandler,and the registersrequired for all programexecution(calledthe contextregisters) are savedbeforethe registersare changedfor the interrupt handler.Theinterrupt handleritself should executeasquickly aspossibleto avoidinterruptingthe flow and resDonsiveness of the mainlineand to make sureit isn't executingwhen anotherinterrupt request is comingin, whichcould resultin the secondinteffupt beingmissed. I mustemphasizethat interruptsare requests;the applicationcodecanchooseto not respondto them immediatelyor evensimplyto handlethem aspart of the mainlinecode.Thisrangeof variabilitymustbe in the applicationto make sureinteraccommodated
l , e 3 P f C @l l C U E x o e r i m e n t s f o r
the EviI
6enius
rupt requestsare not lost or handledin the wrong order,which canhappenquite easily.Oncethe interrupt handlerhasfinishedexecuting,the contextregistersare restoredto their pre-interruptvalues,the interrupt requesthardwareis reset,and the execution retums to the mainline,asif nothing had happened. Despitethesewarnings,interupts can be addedto an applicationquite easilyasshownin cPKLEDInt.c. This applicationis anotherof the PICkit 1 starterkit LED sequenceprogramsin whichTMR1 is allowedto run at clock speed(4 MHz) with a divide-by-8 prescaler.Every time TMRl overflows,which happens after a little over a half second,an interrupt requestis madeand respondedto by turning off the current L E D a n dt u r n i n go n t h en e x to n ei n s e q u e n c e #incl"ual€ - Roll cPKLEDht.c /* TriIRl Int This Program rrilL LED€ built into th€ PICkit
ro11
i n t k = 0 t
consr char TRrsvalue[8]
voial |
TMR1IF = 0,
//
Reset rlne! Requ€st
pORrA = IrEDValue lkt r
//
Point I,ED
//
hcrement range of
(k
k= €ach
through
When the
(void) / / Respollal lo Inte!rupc
to
of
the
+ 1)
Tiner
1
InternPt
lhe
Culrent
[k] t
LEDS Using
PICkit
% 8,
k q'ithin 0-7
8 )
PCB.
tlnr].iat
interrupt
TRISA = TRISValue Through
= t0b010000, 0b100000, 0b010000,0b000100, 0b1ooooo,obooo1oo. 0 b 0 0 0 1 0 0 , 0 b 0 0 0 0 1 0 t) = t0b001111, 0b001111, 0b101011,0b1010!.1' 0b011011,0b011011. 0 b 1 1 1 0 0 1 . 0 b 1 1 1 0 0 1 t)
const char lEDvalue[8]
T1 intelrupt
tn.rlint
//
ia nain( )
The r,ED valu€s rrED DO D1 D2 D3 D4 D5 D5 D7
A.noale RA4 RA5 nA4 RA2 RA5 RA2 AA2 RA1
t
are:
PORTA
cathoale AA5 AJA{ Ri[2 R'[4 RA2 R]A5 RA]. RA2
PEIE = 1r = 1r GIE TMRLIE = 1; while(]. l
& CONFIG(INTIO & WDTDIS & PWRTEN & IICLRDIS TINPRC/IECT \ & UNPROTECT & BORDXS & IESODIS & EC!4DIS ) t
Handl e r Executron Mainl ine R el u r n
JumP
H a n dL er
Mainline Coaie Execut-ion
M a i n L : Ln e Code Execution
uaraware ftty v I nterrupt
Figure E-aa
Ot
rurn
off
ANSEIJ = 0t TMB1IJ=TMRlB=0t TICON = 0b00110101t
myk€ plealko 04.09.10
Execut ron
=
cucoNo = 7t //
Peq,JesL
//
// // //
Enable Enable Enable
== 1)t
Compalators ADC // Turn off 1 // Reset Tiner // Enable Tr,lR1 Interrupcs Perigheral' Gl.obal Interrupta 1 Interrupts Tiner //
LooP Fotever
E'ld. CPKTJEDInI
The main interrupt operationcontrol is the INTCON register'sglobql interruPtenable(GIE) bit, which,whenset,allowsinterrupt requestsfrom the different hardwaresourcesin the PIC MCU. For every "lE" interrupt source,thereis a registerthat endsin (for interruptenable).And when this bit is set,an interrupt will be requestedand the interrupt subroutinewill be called.In the PIC MCU, therecan only haveone interrupt subroutine,and in the subroutine,the differ(IF) bits are polled to seethe enl interruptrequeslrflag sourceof the interrupt.In cPKLEDInt.c,thereis only one interrupt enablebit set (TMRIIE for TMR1 overflow interupt requests),so I don't bother polling the register. The PICC Lite compilermakesworking with interit placesthe interrupt rupts quite a nice experience; subroutinehandlercodeat the correctaddresswithin t h eP I CM C U a n dh a n d l etsh ec o n l e xrte g i s t esr .a \ i n g and restoringfor you.When you are readyto start
Interruptflow
S e c t i o n5 i x
Interfacing
Pnojects for
t h e P I C @l l C U
135
trying out interruptsin your own application,I highly recommendusingthe PICC Lite compilerbefore assemblylanguage. Comparing the application hex file sizeof cPKLED.cand cPKLEDInt.c,you'll seethat cPKLED.cis 130instructionsand uses10file register bytes,while cPKLEDInt.c is 102instructions(a 20 percentreductionin size)and usesnine file registerbytes. What is really amazingabout this application is that the mainline,consistingof the single"while (1 :: 1);" statementnow,could be usedfor anothertaskbecause the TMR1 interrupt driven subroutine is completely independentof the mainlinecode.And becauseit
requires approximately 38 instruction cyclesout of every574,288,only 0.0075percentof the available instructioncyclesare lost.Youcan havea complete application running while the LEDs are active and not evennoticea drop in performance. This type of improvementin programparametersis pretty typical when interrupts are added to an application. When you are comfortablewith programmingthe PIC MCU in C and assembler, you will be very readyto start to implement interruptsin your own projects.You'lllearn how they canmake a programmore efficientand (ironically) easierto write becausecomplexhardwareinterfacescanbe independentof the mainlinecode.
-J
1 " ttl
1-;
i,f
136
l , e l P I C @l l C U E x p e r i m e n t s f o r
the Evil
Genius
Section
Seven
Samplef Microcontroller Hpplication5
A certainperceptionis held by many hobbyiststhat practicalmicrocontrollerapplicationshavelobe coded in assembler. The reasonfor this feelingis basedon the expectedsuperiorityof assemblylanguageapplications in termsof speedandsize.Theseexpectationsasto the superiorityof assemblylanguagereally don't hold any water;modem compilers,suchasPICC LiterMcompiler,producemachinecodethat is often just asefficient asthat usingassemblylanguagefor a given operationor statement.And no reasoncan be givento use assemblylanguageexcept in situations where custom interfacesare requiredandnot availablein prewrittenlibraries.Being ableto write applicationsin C is prirnarily dependanton the ability of the programmer to designapplicationcodethat is properlyorganized. For somereason,properlyorganizingthe microcontroller application seemsto be quite difficult, when in fact they usuallyonly needto usethe following temDlate: lrai.n ( )
There is no chancethat an inDut statewill be missed.
As a rule of thumb,you can assumethat "essentially zero time" meanslessthan 5 percentof the next loop delay.Any longer than this (especiallyif it is variable), then you will find that the application will respond erraticallyand certainlynot the way you expect. If the application'sinputsare asynchronous and thereis a chancethat somethingwill be missed,then you will haveto modify the applicationorganizationto poll the inputswhile the next loop delayis executing: nain( )
// //
//
variable/Peripheral Initialization (riner) (lf Delay Inilializatsion !rhi1€(l
== Lt
//
Int€rface
(rin€r) D€Iay oDelatiod
//
) //
I
// elihw wrd sampLe
bef,ore
fequireal)
Perf,ot
Interface
Input |
MaiD Loop
)
Nexts Loop/Interface
c Baseal ADplication
Therereallyisn't much to this type of application, althoughI shouldpoint out two very important assumptions: .
requir€d) Main
Loop
(i
Nex! Delay
IJoop
Outsput O9elation
= 0r i < Dlayr i++)
//
{ //
operat.iorl lhe
//
Aslmchlonoua
{
I
Petfotfr
== 1)
while(l
for
t //
Microcontlo1l€r InI)u! ApDLicalion coate organization
valiabLe/Pelipheral InitiaLization (Tiiner) (if Delay Initialization
{ // //
//
t
//
BaBic Microconlloll€r Aflplication Coale Orgaaization
//
.
The output responseto a given set of inputs (or internal statevalues)takesessentiallyzero time -the outputsare basedon a calculationof the lnputs.
ll
Poll/Proceaaing // tof
// elihw ErLd. sarE)le
C Basefl
Application
This organizationof the applicationcodeallows asynchronous inputsto be recognizedwithout affecting the output timing.The reasonfor maintainingthe output delayis to allow any output interfacecircuitry to completetheir operationand any devicesconnected to them to acceptthe completeoutput from the microcontrollerand respondappropriately. For proper operation,I recommendusinga timer insteadof a for loop asI haveshownpreviously,and asthe input is polled, the timer valueshouldalsobe polled. The two code samplesshown here should not be surprising;I have been using them for many of the experiments'codeandwill usethem asa basefor the applicationscontainedin this section.In mostpractical applications, a greatnumberof fuad timeexecution
137
cyclesexistthat are not requiredfor applicationexecution.And the codesamplespresentedhere take advantage of this characteristicby organizing the input and output operationsto bestimplementthe application. By correctly organizing your applications execution, you will havea simplebasethat can be easilymodified into providingthe requiredfunctions.Most importantly,thesesampleapplicationscanbe written in either C or assemblerwith equal execution efficiency.
:*'t
You probably have noticed that I have not included a list of partsand toolsfor the experimentsin this section.This is deliberate,aseachexperimentis unique and independentof the othersin the section.I have included the list of parts and tools required for each erperiment, however,so you can build them on your own,
Experiment50-Pumpkin LEDBiEplag
;13 1
Prc16F684
1 1A-pin
socket
Hi9h-intensity
orange
0.01 pF capacito! tYpe)
b.a{ t*t
I
1,20V8-pin
(any
SIP
1 t DMM Needle-nose pliets Li
Soldering
*"
Prototyping text) Thfee-cell pack
irod
PCB ( s e e AAA b a t t e r y
AAA battelies
Solde r
*,: ii
I
l!
,
. !-,lr ;.-! iii
:-: !'! t ,l',.
4,it
irl:
I am breakingnew groundin this book.In all my previ ousbooks,I showhow to take advantageof linearfeedback shijt registers(LFSRS) to create a seemingly randomdisplayfor the holidays.In this book, I am "cangoingto useLFSRSto createa random-seeming dle" (seeFigure7-1) to put insidepumpkinsat Halloween.Theprojectideawastaken from Mark McCuller's "Pumpkin Light LED" project presentedin October2004's,eslgrzNewsand usesresistor-and capacitor-basedreflex oscillators to flash LEDs on and ofi I felt that the original would be quite complex to assembleand a PIC9 MCU application would allow me to decreasesignificantlythe numberof parts required(andthe work requiredto assernble it). I daresaymy versionis somewhatcheaperto build as well.Despitethe project'ssimplicity,it actuallyworks quite well andwon't burn and dry up the insideof your pumpkinsthe way a regularcandledoes. The Purnpkin circuit usesa 4.5V power supply (providedby threeAA batteries)that servesasthe basefor a small,cut-downprototypingPCB to which a switch,a
138
PIC16F684,a 0.01p,Fcapacitor,a 120OSIP resistor, and the six high-intensityorangeLEDs are soldered.
Fisure 7l Pumpkin artificial cantlle on a three-cell AA batterypqck
l , e 3 P I C @l l C u E x p e r i m e n t s f o r
the Evil
6enius
This cilcuit (seeFigure7-2) shouldnot be a surpriseto you,and is very similarto the previousexperimentsin this book. I wasableto soldertogetherthe cilcuit neatlyon a cut-downprototypingPCB.To further simplify the assemblywork,I usedan eight-pin,l200 single-inlinepackage(SIP)resistor,which containsseven resistors,eachconnectedto a commonpoint, To mimic the flickeringcandle,I wantedthe LEDs to turn on and off seeminglyrandomly,for random periodsof time (rangingfrom about one-tenthof a secondto one or two seconds).The mostobviousway of implementingthis is by an LFSR, and I decidedon usinga six-bitLFSR for the six LEDs on PORTC of the PIC16F684and a four-bit LFSR to specifythe lengthof time the LEDs would be in a specificstate.I expectedthe codeto be very simpleand similarto someof the earlierexperiments. However,before blindly writing the LFSR codeand attemptingto debugit in the applicationcircuit,I decidedI would simulateit first. The LFSRsfor this applicationeachhavea single tap,which is XORed with the mostsignificantbit and fed into the input of the first bit of the shift register.To test and demonstratetheir operation,I createdthe applicationCLFSR.c: *include cLFSR.c - Test /*
LFSR Taps
Thi6 plogfaln Te€ts 6 antl 4 bit L!'SR Ta!,6 to sure they Perform a ( (2 ** n) - 1) Maxinlllln Numb€! of timeE
nak€
!=
1)
t =
fourBitTrFSR
fourBilcount I
(fourBitlrFsR << 1) & 0x0F) + ( fourBitIJEsR >> 3) ^ (fourBitIJEsR >> 2) & 1))t = fourBitcount+ 1r // Keep Track of, slate #
/ / eLilrw
sixBitIJFSR sixBitcount
= =
// //
1t 1t
start at 1 Keep Track of
(sixBitlFsR ( sirrBitLFSR (sixBitlFsR ( sirraitlFsR t= 1)
sixBitLEsR
while
=
<< 1) >> 5) >> 4)
fourBitlFsR, fourBitcount,
sixBitlEsR
t
fourBill,FsR
= ( (fourBittFsR ( (fourBitlEsR ( (fourBitIJFsR
// //
+
& 1))t
sixBitcount l
//
& 0x3F) ^
+
& 1))t ll Ke6D Ttae]f of State #
eti'}r'''
//
while(1 )
= ( (sixBitLFSR << 1) ( (sitrBitlFsR >> 5) ( (sitrBitLFSR >> 4) = BixBilcounE+ a,
== 1) t
End CLFSR
The two countvaiables are usedto determinehow manyiterationsof the LFSR would executebeforethe valuereturnedto 1, at which time it would start all over again.When the LFSR tapsare properly placed, thereshouldbe 2'' - 1 iterations(15 for the four-bit LFSR and 63 for the six-bitLFSR).Amazingly enough,the two taps(thoseat the shift register's secondto lastbit) producedperfectresults,and they wereintegratedinto the cPumpkin.capplicationcode:
Haralware Notea: PrC16F684 Running at RCs:RCo - 6 ]JEDS
nain ( )
= 1, = ft
& 0x3F) ^
#
IJED6 on PORTC
This Prograltr will run cofltifluously tufiing on ],EDs for varying Lengtlrs of time to simulate a candle in a Pumpkin. Six Y611ovr anal Orartg€ High ploject. Intensily LEDa shoulal be useal with this
sixBitLFSR, sixBilcountt
fourBitr,EsR f,oulBilcount
Stale
{
#include - Ranalomly lJight cPumpkin.c /i
myke Dreatko 04. !L. r7
int int
( fourBitIJESR
while
start at 1 Kee r, Track of
Slate
<< 1) & 0x0F) >> 3) ^ >> 2) & 1))t
*
4 MEz
iryke Drealko 04. !L. r7
+ CONFIG(INIIO & I{DTDIS & PWRTEN & !,ICLRDIS & UNPROTECT \ & IJNPROTECT & BORDIS & IESODIS & F C M D I S ) ,
int int
i, j, k; fourBiUIFSR.
sirrBitLFSRt
main( )
t fourBitLFSR si.xBitLFSR
= 1, = 1t
CIIICONo = 7 t
Figure 7-2
// //
//
$)rn
Starl Starl
off
at. 1 at' 1
coinpalators
Pumpkin circuit
S e c t i o n5 e v e n S a m pI e C l 1i c r o c o n t r o l l e r
Applications
139
.lll\IsEr, = 0, IRISC = 0t lrhile(l
== L\
//
Tuln
off
aDc
//
IJoop Foreve!
t (k = 0r
f,or
h < fourBitsLEgR,
k++)
//
Delay 0.18 x 4 BiE IJFSR
(1. = 0 , i < 2 5 5 r i + + ) fo! (j = o t j < 2 4 , j + + r , for PORTC = sirrBiLLFSR
| f,ourBitrFsRt
I / \t€.:ri.llize + o f IrEDs on
t&l -
foutBitLFSR
airiBitLFSR
Ft
=
( (foulBitLFSR ( ( foulBitLFSR ( (foulBitlFsR ( ai*BitLFSR ( Ei*BitLFSR ( air{Bilr,FsR
<< 1) 0x0F) >> 3) >> 2) & 1 ) ) , << 1 ) & 0x3r) >> >> 4 ) & 1 ) ) t
+
The code is quite simple and straightforward except for two placesI would like to bring to your attention. The first is in the delay loop: I changedthe end values in a 500ms delayso that it was100ms,and then I addedanotherfor statementto multiply the delayby the value of the four-bit LFSR. Similarly, rather than just passthe six-bitLFSR to PORTC,I decidedto OR the two LFSRStogetherto get the maximumnumber of LEDs on at any giventime. The application works quite well and for a surprisingly long time. I must caution you againsttrying to stare into the high-intensity orange LEDs. They are bright enoughto giveyou a headacheand produce spotsbefore your eyes.
+
&4 //
End cPurekin
ni
Experiment 5l - Reaction-TimeTesIer
f-d
ri
t!
1
Prc16F684
I
l4-pin
I
1o-LED bargraph
1
10 /rF electrolytic capacito!
I
0. 01 /rF capacitot tYpe )
as,
socket display
(any
10k !es istols
t :
1 0 10 0C, resistors
DMM NeedIe-nose Solderj,ng
iron
Solder
I l.'l
Wire-wrap
I
Prototyping' text)
1
Two-ceII pack
2
AAA batteries
wire
Weldbond adhesive
,."a.
SPST switches
pliers
PCB (see
AAA battery
'-'r ,i? 1"3 " r I
fi-! f;t i{{
t\
A gimmickthat becamequite popularwhen I cameof ddnking agewasthe reaction-time,or sobrietytester, that consistedof a simplecircuit that would run a seriesof LEDs until a button waspressed.The reaction time beingtestedwasthat of an individualwho had beendrinking,and of course,the reactiontime would vary accordingto how much he or she had to drink.The circuitpresentedhere canbe built forjust a few dollars and an hour's worth of time.
The reaction-tirnetestercircuit (seeFigure7-3) probably looks similar to the c cuit usedin the previousexperiment.Thedifferencebetweenthe two circuits is simply a 10-LED bargraph display and two buttons.You shouldalsonote that thereisn't a power switch built into the application; I take advantageof the low-powersleepmode of the PIC16F684microcontroller aswell asits ability to run on the power provided bv two AA battedesThe button connectedto
t
140
l , e 3 P I C @l ' l C UE x p e r i m e n t s f o n t h e E v i I
Genius
RA2 will start the test,andthe button at RA3 is the userrespondbutton,which is to be pressedwhenthe userseesthe LEDS start to sequenceon and off. The operationof the circuit is quite simple,after power is applied(i.e.,whenRA2 is pressed),the circuit delaysat somerandominterval (usingthe current TMR0 value)betweenone and two seconds. If RA3 is pressedduringthis time,the test stopsand the two extremeLEDS startflashing.After the randominterval,the LEDs are sequenced on until RA3 is pressed. If RA3 is pressedduringthe sequence, the operation stopsat the currentlydisplayedLED. If the userdoesn't respond,then the lastLED startsto flash.The flashingLED(s) or just one LED will stop,and the PIC MCU will go into sleepmode after 1 minute unlessRA2 is pressedand anothergameis started. When I built rny prototypecircuit (seeFigures7-4 and 7-5),I useda basicprototypingPCB that had somegenericsignalandpowertraces,and then filled in with poinlto-point wiring for the remainder.WhenI wasfinished,I useda beadof Weldbondadhesiveto hold down the wires.Beforewriting the application,I createdtwo testprograms.Thefirst,which teststhe two buttonqis cReact1.c: ilinclude cReact 1.c - C Program /r on Reaction test€r ThiB
Prog!€m
l{42 RjA3 R,AO &A1 RiA4 RiA5 RCo RC1 . RC2 RC3 RC4 RC5 -
Buttoa Button I,ED1O LED9 LEDS LEDT IEDS IJEDs tEDll IJED3 LED2 I,ED1
is
a nodtification
Connectior Connection
to
TeEt
of
(Stalt/Porder (Reapond)
=-
while(1
(
r,
aA1 = AA2i RC5 - RA3i // elihw ) // End cReact ,
//
Loop
f,oteve!
// //
Po'lrer On switch Respond sxrilch
(to LED9) (to LEDI)
1
The secondprogram,"cReact2.c" teststhe sequenceoperationof the LEDS and wasbasedon "cPKLED.c": #include cReact 2.c - c Proglam tso T€st /* Connections on Reaction Test€! This
Plogra$
RAz - Button RA3 - Button RAO - I.ED1O RA1 - LED9 RA1I - I,ED8 RA5 - I.ED? RCo - tED5 RC1 - IJEDs RC2.IJED4 RC3 - LED3 RC1I - IJED2 RCs - tEDl
is
a rnoalification
of, ncPKLEDn
(Start/Polre! (Respond)
Connection connection
LED
On)
nyk€ predko 04.L1.28
IJED Buttons
"cBuEton" On)
( IN:IIO -CONFIG T'NPRCI'IECT \ & T'NPROIECT
int
i,
j,
& I{DITDIS & BORDIS
& PWRTEAI & IESODIS
& MCI,R.DIS
&
& FCTITDTS) '
k,
nain( )
t PORTA = 0x3Ft PORTC = 0x3Ft CTiICON0= 7, eNsEL = 0t TRISA = 0b001L00; TRISC = 0;
AI1 Bits are high because LEDS active // are negativ€ coinpalatols / / Truqt off off ADc // !u!n / / B A 2/ B A 3 a r e i n p u t a // A1,1, of PORrrc are outpula //
myke prealko 0{ . 11.2I
1 OL E D Bargraph
& WDIIDIS & PWRTEN & MCIRDIS & -CONFIG(INTTO I'ITPROTEC! \ a ITNPROIIECT& BORDIS & IESODIS & FCMDIS) t
nain ( )
t PORTA = 0x3Fi PORTC = 0x3!i CMCONo = ?, ANSEL = 0t TRISA = 0b001100, TRISC = 0,
ALL Bitsa are high becaus€ IJEDs // are n€gative active off comparatols / / Tnt // Tuln off ADc // aA2/aA3 ale inputa / / All ot PORTC are outputss //
ThisEnd Figufe 7-3
Reaction-time circuir
S e c t i o n5 e v e n S a m p I e C l ' il c n o c o n t r o I I e r
Applications
141
Rc{ = 0; break, case 2: RC3 = 0t break, case 3: RC2 = 0t break, case 4: RC1 = 0t breakt caae 5: RCo = 0t breaki case 5: Ria5 = 0t breakt case 7: R[4 - 0t bleakt case 8: Rl[1 = 0t breaki case 9: RlAo = 0t breaki // hctiws )
Fiqure 7-q The prototype retrction-testercircuit was built on a prototyping PCB
whiLe(1
(
== L')
//
Loop
(i = 0r i < 255r i++) // for for (j = 0r j < 429, j++r,
Sinple
PORTA - 0x3Fr PORTC = 0x3Ft
turn
switch
//
Forever
Delay
off
lJoop
LEDS
(k ) ll
LEDT
l/
LED2
Figufe 7-5 Backside point-to-point wiring used.on the prototype reaction-testercircuit
L42
I,ED3
//
LEDA
ll
LED5
//
LED6
//
r,E,D7
ll
I'EDB
//
I'ED9
//
t'EDrO
k = ( k + 1 ) % 1 0 i
{ cas€ 0: RC5 = 0, breaki case 1:
//
I ]
I / ell}:w // End cReact
2
After usingcReact1.cto verify the operationof the buttonsand cReact2.cto showthe LEDs werewired correctly,I createdcReact3.c,which is the reaction tester. In cReact3.c,you'll seea coupleof thingsthat won't be obviousto you.The first is the group of nestedfor loopsthat alsopolls button and falls out if a button is pressedunexpectedlyor out of turn.When you look at the loops,try to imaginetheir operation You with both the button pressedand with it released. can alsosimulatethis codeto seeexactlyhow it works by usingthe synchronousstimulusfunction of MPLAB@IDE. The secondpiecethat will seemunusualis the sequenceof instructionsleadingup to and following the SLEEP0;function.This is not a function,it is an assemblerinstructionthat causesthe PIC MCU to go into a low-powermode,or sleep,and it canbe awakenedeither by cyclingthe application'spower or causing an interrupt requeston RA2.There is quite a bit of theorybehindthe sleepoperationand the different modesthat can be employedwith it. Tiust me;the "INTE : 1;/SLEEP0;NOPO;"statementsequence will put the PIC16F684into a low-powermode and will resumeoperationwhen the RA2 button is pressed.
l , a 3 P I C @l ' l C UE x o e r i m e n t s f o r
the Evil
6enius
ExFeriment 5 2 - Floke nbuk@Monora i l/Traffic Lig htE
t PICI5F68 4 14-pin
socket
2 Red LEDS 2 YelLow LEDS 1 10 pF electrolyt
ic
capacito! 0 .01 ru,F capacitor tYpe)
(any
LDRs
DI'',M Needle-nose
p liels
Dremel tool
with
10k res istors 100 Ohm resistors
ablasive
t c^l
rari
n^
r F^n
1 Prototypinq
solder
1 Three-cell.
Wi.!e-w!ap
AAA battery
pack
vri!e
2 mrn heat-shrink
PCB
AAA batteries
tubiog
Weldboad adhes ive s-minute
epoxy
Crazy glue
My daughterand I love to play with our Rokenbok remote-controlbuildingsystem.The toy consistsof a numberof remote-controlconstructionvehiclesthat interactwith buildingmaterialsusedto createdifferent buildingsandstructures.Tohelp enhancethe experience,I wantedto modify a monoraiVtrucklevelcrossing so that dummywarninglightswould flashwhen a train approached(seeFigure7-6).This seemedlike a perfectprojectfor a PIC MCU I alwaysfind that hacking toys to be somethingof a challenge;the electronics built into the toys do not lend themselvesto intedacing with rnoregeneral-purpose electronics(generallythe electronicsselectedwere the lowestcostavailableand havetheir own specialcharacteristics), structuralfeaturesare difficult to cut throughor modify without significantlychangingthe look of the toy,andthe weight of the additionalelectronicscan seriouslydegradethe performanceof the toy.I canhappilysaythat this modificationwent quite well,with the only major surprise beingin the operationof the PIC MCU. The theorybehindthe modificationis quite simple. Two light deperulanrreslstars(LDRs) were placed at either end of the crossing,by solderingthem to cut down prototypingPCBsand gluingthe PCBSinto
S e c t i o n5 e v e n
trackpieces(seeFigure7-7).On powerup.it is assumedthat the train is not over the LDRs. and therefore they samplethe ambientlight eighttimesand averagethe result.When the train movesover the LDRs, it is assumedthat the ambientlight to them is c u l o f f a n dt h ec h a n g e i n t h eL D R r e s u h isn a c h a n g e in thevaluereadby the PIC MCU's ADC ot greater than 25 percent.Thiscausesthe LEDs placedin the vehiclewarninglights to flashfor aslong aseither sensor is coveredplus 10seconds. Despitethe simplicityof operation,the circuitworks very well and is actually quite impressive. Two nice thingsaboutthis circuit are that the LDRs do not needto be wired to specificADC inputs(either one will do) and,practicallyspeaking,LED colorsdo not needto be matched.Theseadvantages eliminated the needfor testingeachwire for a specificconnection, and thuseliminatedthe difficult task of sortinsout 10 two-foot wiresin a smalltoy. The installationof the LDRs is quite simple.The2footJong piecesof wire weresolderedto eachof the LDRs' leadsand coveredin heat-shrinktubing.I used the three squareblack structuralrodsfor the track and, usingKrazy Glue,I attachedthe PCBSto the insideof
S a m pI e C I ' il c r o c o n t n o 1 I e r
Applications
L43
l
CI .tJ
bt
,l.l
FI @
lr/,
CI *a 0, J1
g,
Figure 7-6 Rokenbokmonorail-levelcrossingwith train sensorsand flashing waming lights the middle squareof the structural rod. At this position, the monorailandits trailer would coverboth sensors I was surprisedto discoverthat Krazy Glue behavesasa solvent for the black plastic,literally weldingin the smallPCBswithout needof another glue. Red andyellow LEDs were installedin two warning lights that snapinto stalks.I did so by drilling % -inch holes in the plastic on one side and 1/z-inch holes in the other to allow the flangesof the LEDs to fit through and the endsof the LEDs to poke out the other sides.Like the LDRs, the 2-foot lengthsof wire were solderedto the LEDs, but with a few modifications.The cathodesof the two LEDS were joined with a 2.5-inchlength of wire, and single cathode wire was usedfor the two LEDs. I then soldereda 100f,)resistor
c{
Thia Program will fj.rat s.iq)le lhe erDbi€at liqht oa the two LDRa for 8 SEfiD1e6, 50 n6 aDart. WLth th€se Sarq)les, tshe cotl€ will er.€cute, waitilg for lhe SeEsors lo be cov€reil anal tb€n uicover€d. $!r€n 6itbe! i6 Cov€raeal (IJDR Vo].lage changea bL 25% o:. nore) lhen the LEDa f,Iaah. Ighen both are left flaEh uncove!€tl, the lighta for an aalalitional 10 B€coDils.
4yke p!6tlko 0{.11.30
g
(u
& WDTDIA & PWRTEN & IICIJRDIS -CONTIG(INTIO T'!{PRCIIECT \ & I'NPROTECT & BORDIS & IESODIS & FCMDIS} '
H
.Fl
$.1
X kl
*inclual€ cRok 2.c - RokenJroh ApDlLcation /*
PIC15F68{ Pl.nE: RAO - I,DRI RA2 - IJDR2 RCz - I,ED1 RC3 - I,ED2
rn
g g.
to the anodeof eachLED that had a 2-foot piece of wire solderedto it and put heat-shrink tubing over the length of the resistor and its solder connectionsThese solder connectionsallowed rne to easily identify which wire wasusedfor which purpose.A simpler method of keeping track of the wfting might have been to use different color wires. I threaded the wires through the structural rods and the bottom side of the crossing.Using a Dremel tool, I cut away ribs in the center of the crossingto allow the wires from one side to passthrough without causing the crossingto rock when a vehicle or the train went over it. Thesewires were held in place using s-minute epoxy. With the toy modified and the wiring in place,I then created a prototyping PCB with the circuit shown in Figure 7-8.The 10k pull-up resistors on the LDRs will convert the LDRs into a voltage divider circuit that can be measuredusing the PIC MCU's ADC This is actually quite a simple circuit, although you will find it quite difficult to wire using the different wires leading from the toy.When planning your PCB, make sure you keep the wires from interfering with the monorail train asit passesover the crossing. To test the circuit,I created a simple program (calledcRok 1.c)that simplyflashedthe LEDs for 30 seconds,and then I jumped right into the application (cRok 2.c):
Figwe 7-7 Monorail LDR soldered to a small pi.ece of PCB and glued inside the black monorail track (one on eachside of the tossing)
L44
int int int co!6t
i, j, k, LighbTiner, FlashTi.nert IiDRo, IrDR2t int
fiftynB
= 3333,
l , P 3 P I C @f l C U E x p e r i m e n t s f o n t h e E v i l
//
LDR Av€rage
//
50 mB Delay
Genius
Valuea
nair(
{ PORTA = 0, PORTC = 0, CMCON0 = 7, ANSEL = 0b00000101, ADCONo = 0b00000001t // Bi,E 7 5 // Bit ll BiE lt2 / / BiE L ll git. 0 ADCON1 - 0b00010000t TRISC:0b110011, = 0t = 0t
LLghtsliner FleshTine! (i
for
= 0,
i
< 5,
alrin of.f. CdrE aralora ADC ON RAO & RA2 llurn on lhe AIrC garnple Ir€ft ilustif,ietl Uae VDD - Chan'lel 0 Do Dot Stalt fur|t on ADC the clock as // g€lect EoBc / I // RC2 & BC3 ar6 IrED Driv€r6 Flashing Yet // Nothlag // // //
I.DRo = 0, f o r ( j = 0 r j
//
i++)
< 8, J++) //
DeLey Eo r.et Power
get!L€ i++) t cer BA0 risht Average
GODONE = 1, // sarDLe aAo ( IGODONE)t while IJDRo=LDRo+ADRESHt (i = 0r i < flftslzns, for i++), iof
LDRo=LDRo/gt
//
Ciel Average
ADCONo = 0b00001001, I,DR2 = O, f,or (i = 0r J < 8, i++)
//
Sample
//
c€l
GODONE = 1, ( t GOITONE), !rhi1€ LDR2=LDR2+ADRESHt (t = 0, i < fiftt'nsr fo! I // to€ IJDR2 = IrDR2 / 8t (i - 0r i < fif,tt'mar for
//
Saq)le
J = 0t $hL1€(1
-=
1)
i f ( j < 2 )
R€ailiDg
on ItA2
RAo Lighl
Av€rage
RAo
i++)t //
cet i++),
Averag€
R€ading
//
uE6 J fo! chatulel se1€c! Loop Eorev€r
//
ItAo Read
//
(
{
if
(LightTilne!
l=
0)
Stsi11
//
!=
O>
ll
Chang€
TU |"{
FLa8hiag?
f",.
- 1t = LightTiner LighlTimer if, (0 == LightTLn€r) Elashlng // Finisheal | = 0, FlaahTlner // Finish€d PORTC = 0t J // fi
(LightTlm€r
= FLeshTimer FlaahTimer (0 == Flashtiner) lf | //
-
Flashingl
tst
ELashing?
Ul h3
1i
I
t
la{
When I createdcRoc2.c,I expectedit to work with minor tweaking. I was surprisedto discoverthat when power was applied, the LEDs flashed continually.This is probablythe most dreadedsituationimaginable;I had a problern with a hardware devicethat was not supportedby the simulator(whichhad worked correctlywhenI simulatedit), and I had not designedany way of passingdata out of the application.After about 3 hoursof working at characterizing the problem,I discovered that to get an accuratereading for comparison to the averagevalue,the ADC neededa dummy read after changingchannelsWhen you look at this code, you'll seethat I actually loop through eachADC's channel twice before I comparethe result to the averasedamountfor the channel.
{
A.DCONo= 0b00000001r // fo! (i = 0r i < flft!'nsr GODONE = 1t // ( IGODO$E) t wbj.le k = (I,DRESH a 100) j a j + 1 , ,
/
) elEe
serI)].e on RAo i++)t Do aDc Reaal
LDRot // Incr€{reat //
g€.nE)l€
sarE)le
on RA2
t ADCONo = 0b00001001, // S€4p1€ on RA2 (i = 0r i < flfllmsr for i++), GODONE = 1, // Do A.Dc Reaal ( IGODONE), nhil€ k = ( A D R E S H * 1 0 0 ) I LDR2I j = (j + 1) % {, , // ti
if |
((0 == (j & 1)) && ((k > 12s) ll (k < 7s))) Flashi'lg // Start/conlinu€
'Len Tfain Signal
Figure 7-B
"Righl'Tmin Signal
Traincrossingcircuit
S e c t i o n5 e v e n S a m p1 e C l l i c n o c o n t r o l l e r
ftl v/!
tld
Chans€ Flaahing Ligh!s = 10r FlaEhTirn€r // Res€t F1aah Tiner PORTC = PORTC ^ 0b001100t , /t fL | // fJ\ / / elilLv ] // Ena cRok 2
{
//
if
10 gecoDtla
{
i < flft!'nEr
,
= lO + 2Oi // Flash f,or (PoRTc & 0b001100)) Start | // If Not Flashing, PoRTc = 0b001000t = 10, FLasbTinler | // ti ll Ei l IJighlTiner (0 :E if
)
Applications
145
rl
tn ry *r.a
n
?r L
r",
To find the problem,I first simulatedthe application to make sureit worked asI expectedit to.You will find that the simulatorexecutesstraightthroughthe ADC operationswith the GODONE bit beingimmediatelyresetafter it is set.Using the Watchwindow registervalueupdatefeature(double-clickon the register'svalueto bdng up an edit window),I testedthe applicationfor differentADC return valuesand made surelhat the codeworked properly.Next,I commentedout all the codefor one of the two channels and I found the applicationstartedworking,until I returnedthe commentedout code.Next,by flashing the LEDS,I output the valuereadversusthe value averageand discoveredthey were different.Finally,I
tried to do a dummy readof the ADC channelbefore the live read,which wascheckedagainstthe averaged value. The previousparagraphdoesnot conveythe frustration and annoyanceI felt in working throughthe problem.But, by working stepby step,ensudngthe programworkedin the simulatorasI expected,checking my assumptions rigorously,and not presumingthe root causeof the problembeforehand,I wasableto debugthe application.This is a usefulsequenceyou canusewhenyou are facedwith an applicationthat doesn'twork or behavesin a mannerthat is totallv unexDected.
ExFeriment 53-5even-5egmentLEDThermometer
P I C 1 6 F 6 84 ?4HCT138 three decoder 1 14-pin
to
e j,ght
socket
2N3906 bipolar transi stors
NPN
(Radio Shack Thelmistor 271-110 recor nended) 0.01 pF capacitols tYpe)
DMM Scientific
100O res istors
calculator
330f,) res istors
Needle-nose pliers I
So lde r 9lire-yr3p
10k, 1-percent ance resLstor
tole!-
SPST switch 9i36
fwo-cell c1ip
Weldbond adhesive
Probablythe mostpopularPIC MCU projectI have ever designedwasa three-digitdigital thermometer for the PIC16C84that waswdtten in assernblylanguage.For somereasonthis circuit and softwarewas extremelypopularandwasusedasthe basisfor a wide vadetyof differentapplicationqincludingmonitoring the temperatureof a chickenincubatorlThe original digital thermometeruseda timed I/O pin resistance measurementof an RC network.Two input pinswere usedto calibratethe thermometeroutput,andthe calibration valuewassavedin the data EEPROM of the PIC MCU. The originalcircuit works quite well,but I wantedto eliminatethe needfor the calibrationvalue
L46
(any
AA battery
aswell aswrite the applicationcodein a high-levellanguagethat did not obfuscatethe operationof the thermometer.Tomeet theseobjectives,Iusedthe PIC16F684's ADC alongwith the PICC Lite compiler languageand its floating-pointnumbercapabilities. The circuit (seeFigure7-9),althoughfairly complex,is quite straightforward.One commonanode, seven-segment LED displayis activeat any one time, and the applicationsequences througheachLED display 50 to 64 timesper second,givingthe appearance that all four are activeat the sametime.The seven-segment LED displaysare poweredby PNP transistors
l , P 3 P I C @l ' l C UE x p e r i m e n t s f o r
the Evil
6enius
G1 Vdd
Ptc1 6F 684
B
C
.G2A/B Y3 \2 Y1 YO
RA5 RC5 RC4 RC3
-l-
RCI RA4 RCO
I
-L ,: Figure 7-9
"o
2x Dual7-Segment Common Display
Digital thermometer circuit
that are,in turn, drivenby an eight-bitdecoder.This may seemlike an ungainlymethodof driving the seven-segment displays,but it is requireddue to the lack of availablepinsfrom the PIC16F684to ddve the segmentcommonpns. I built my prototypeon a fairly smallPCB (seeFigure 7-10)and usedpoinlto-point wiring to createthe circuit asshownin Figure7-11.Thereare a lot of wires to solder,and whenyou havecompletedthe circuit,I suggestyou testit with cThermo1.asm.This will initialize the PIC16F684and displaythe ADC valuefor the resistor/thermistor voltagedivider.I usedthe Radio Shackthermistorbecauseit is reasonablypriced and the backof the packageliststhe thermistor'sresistance for differenttemperatures, which is nice to havewhen debuggingsoftware. *inclutle cTherno 1.c /. This program will ADC Value on four Displays.
Display
the
ADC Value
alisplay the curlent PrC16F584 7 gegnent Conmon Anoile LED
The Codle/wiring is baseal on 'c4x7s€9.c" Noting that Negative Aetive LED Wiiirlg iB useal. Eartlware AA5 RC5 RC4 RC3
-
Fiqure 7-10 Digital thermometertop with thermistorby the on/off switch RC2 - Segment RC1 - Segment RC0 - segment RAO - Right - Left
e f g
7 Segtnent 7 Segment
Display DispLay
lryke prealko 04.12.23
Not€s:
Segment Segment Segment Segment
a b c al
-CONFIG(INTIO UNPROTECT \ & ITNPROTECT
& WDTDIS & BORDIS
S e c t i o n5 e v e n S a m p1 e C l "ilc n o c o n t n o l l e r
& PWRTEN & ITCIJRDIS &
IESODIS
& !'C!IDIS)
Applications
& t
L47
o g br
tl (l
s, E
tn 0, w I
l-N
CI,
F
{l rn I
rn !J'
\v
H
--l $..1 \u P{
= (DtEplayIJED
NoPOr (1. = 0r fo!
Figure 7-'f'f Digital thermometerbacksideshowing pointto-point wiring
Eotevei
j
E j
for
/ / veed
fot
+ 1'
(s0 =- i)
if
(
+ !,
// uged L < 32"1, i++r,
NOP O T
Fl l{
l2oo!,
* 4)) = (DisDleyvalue >> (DiEplat'!@ & 0x0Ft PORTA = ( (LEDDigit lDisp1a]'Digitl >> 1) & 0x020) + (1 << 4) + (3 - DiEI)IayLED) t PORTC = r,EDDigit [DiEplayDigitl t DiEDlariIrED
Lr
"P
| /
Diq)IatDigir
o
trl
// //
Seatt. Dl.splayl.ng at 0x0000 DisDlay the 16 filgts slalt counting at zelo
//
== 1)
while(1
t
Oi
= 0t
Disl,laylED j = 0t
(,
n
-
DisDlatvalue
${
j - o;
% 4t
//
Ne*E Digrit
5 ms Timinsl // 5 ma Delay Loo9 5 ms Iimingl
// //
rncldrent !h€ couat€r? 1/{ Secolal Paaaeal?
//
R€set for geconal
anothe!
1/4
awl.tch(aDcstsat€) lnE lnt
DLapla!ryalu€, = o, ADcstate
DLsplalrDlgLt,
(
DlEplayriED,
case 0: // gtsart ADc operation CiODONE- 1t ADCSlat€ = Li bleak; ca6e 1: = 0t ADCSlate = (.a.DRESH<< 8) + ADRESIJt DiaDlat4talu€ b!€aki ] // hctiws
= { conEu char IJEDDigittl // RRRRRRR . PIC16F581I PIN // ACCCCCC / / 55432LO - IJED Segrlent // abctlefg
0b0000001, 0b1001111. 0b0010010, 0b0000110, 0b1001100, 0b0100100, 0b0100000, 0b0001111, 0b0000000, 0b0001100, 0b0001000. 0b1100000, 0b0110001, 0b1000010, 0b0110000, 0b0111000)t
| |
natn( ) t PORTA= O' PORTC= 0, CMCONo= 7t AI,ISEIJ= 1 << 2t AItCONo = 0b10001001, / / BfiE 7 // BLt 6 ll BiE 4.2 ll Bft L // BLE O A.DCONI = 0b00010000r TRISA = 0b001100, TRISC = 0b000000r
X
/ / 'r\lzn off comparatorE // 8A2/ (AN2) la a.|t Analog Input // $rr|t on the ADC .IustifL€d Right S€lnlrle u6e rrDD - Chaanet 2 Do not start Tuln or ADC the Clock as // 5€1€ct Fosc/8 // RA5/RA1/RAo a!€ outl)uld of PoRTc ar€ // ALl Bits outDuta
/ / et"rbw / / E^d cTherno
1
When cThermo 1.cis running, you can test the operation of the ADC and the display by breathhg on the thermistor or by putting it in the sun or in a refrigerator. After you have verified the operation of the display and thermistor, I suggestthat you coat the back of the PCB and all the wires with Weldbond or epoxy to hold them down and prevent them from being damaged. The next program demonstratingthe operation of the circuit is cThermo 5.c,which displaysthe current resistanceof the thermistor(in 10Oincrements).I found that the resistancedisplayedwasalmostexactly the resistancespecifiedon the back of the thermistor's package. The thermistor and 10k, 1 percent resistor form a voltagedivider,which is read by the PIC MCU's ADC. The formula for the 10-bitADC value(assumingthat the full range is 1,023)is asfollows. ADC/
j.,023 =10k/
(10k + &n"_,*",)
Rearranging this formula, R*"-'.,o. can be calculated as:
|lI
148
l , e 3 P I C @I I C U E x o e n i m e n t s f o r
the Evil
6enius
&**'"-.=t(1,023x10k) /ADcl - 10k This is the formula usedin cThermo 5.c to calculate the thermistorresistancevaluebeforeit is converted to indiyidualdecimaldigitsand displayed.I broke the formula into different piecesand put them in a state machineto makesurethat the floating-pointoperations would not delaythe operationof the TMRObaseddigit displaycode. cThermo 5.c wasmy first experiencewith floatingpoint numbers and variablesin the PICC Lite compiler, and I mustsayit wasan educationalone.In the codefor cThermo2.cthroughcThermo4.c,I tried a number of different approachesto solve the problem and discoveredsomethingthat shouldhavebeenobvious.The functions that provide floating-point operators in the PIC MCU take up a lot of instructions.I found that to bestimplementthe PICC Lite compiler codewith floating-pointoperatorEI shouldrestrictthe numberof operationsto three. In the previouscode,you will seethe three operators: . .
Floating-point-to-integerconversionusingthe "(int)" type cast Floating-pointsubtraction
.
Floating-pointdivision
To convertthe thermistorresistanceto a temperature, I found that the resistancevaries negatively with the temperature.This was confirmed by a table on the datacardthat camewith the Radioshackthermistor. This meansthat asthe temperatureof the thermistor goesup from a nominaltemperatureof zs"C,the goesdown.Similarly,when the temperature resistance of the thermistordrops,its resistanceincreases. With a little bit of experimentation with a calculator,I discoveredthat the resistancevariedby 1.039percentfor everydegreeCelsiusof temperaturechange.This relationshipseemedto be true for +/-40"C from 25'C, which waswithin the range of temperaturesfor a thermometerto be usedaroundthe home. When you order a specific thermistor, you can find this informationin its datasheet, otherwiseyou will haveto comeup with somekind of way of experimentally finding this information. This is not easyto do. The temperature versusresistanceinformation printed on the packagingis why I selectedthe RadioShack part.Whenyou look at the datasheets, you'll seethat the percentresistorchangeper degreeCelsiusis not constantacrossall temperatures,and the manufacturer will often include a formula for a temperature range of severalhundreddesreesCelsius.
To keepthe applicationreasonable,Ijust kept the operatingrangeto +^ 40"Cwith a centerpoint of 25"C and cameup with the voltage{o-temperature functionfor the thermistorand 10k,1 percentprecisionresistorvoltagedivider: = Vdd X 10k/(10k
Voltage*,
t$ fit
* &n"-r"-.)
BecauseI usedthe full 10 bits of the ADC for this application,the ADC valuecouldbe convertedto a voltageusingthe following equation:
t**
tr1 p.{
f&
VoltageRA2 = Vdd X ADC/1,023
And combining them, I could solve R*"**o, from the ADC value:
I11
Vdd X ADC/1,023 = vdd X 10k/(10k R*.*;**)
t6
Rrr,._i"rc, = ll1-,023
X 10k) /ADCI ,
+
10k
tflr
This calculationis carriedout in states65 and 66 of cThermo5.c. The next step was to convert this resistanceinto a temperaturechangefrom 25"C.Knowing that the thermistor'sresistance changedby a setpercentfor every degreeCelsiuschangein temperature,the resistanceof the thermistorcouldbe expressed as:
{u -\ l!l lqE
* { f l
ti, = 10k x
&h"-t"t.'
(1 039'5"c r)
9{
Pluggingthis valueinto the ADC equationfor Rrh"*nto.,the temperature difference from 25'C could be wdtten out as:
t i.F .J
t ( 1 , 0 2 3 x 1 0 k ), / A D C-I 1 0 k = 1 0 k X (1.039,soc a)
F
Removingthe common10kterm,the equation becomes: ( 1 , , 0 2 3/ A D ' c ) - 1 =
1 . 0 3 9 ' 6 k- r
=
e1n(Nu)
n |"{
Now, dependingon how much mathematicsbackgroundyou have,this may seeminsolvable.But, by knowingthe following: NunPowei
Frl
o
h{
t
x Pawer
o
5
o
$ tv F'
S e c t i o n5 e v e n
S a m pI e C l l i c r o c o n t r o l l e n
Applications
149
wheree is the baseof the naturallogarithm(ln), and by usingthis relationshipon the previousequation, alongwith a bit of algebra,you can find: Temp = 25oC - {Lnt (1,023IADC) 1ll1n(1.039)]
Even if you understandexactlywhat I've donehere and havehad the necessary instructionin algebra,relations,and functions,I'm sureyour brain is hurting.I suggestthat you standup and take a break.I know I had to.The temperatureformula is deceptivelysimple: It took me four daysto work throughthe circuit and equationsto comeup with this equation,which is specific ro the PIC16F684's10-bitADC andindependent ofVdd. Calculatingthe temperatureusinga formula that is independentofVdd allowsthe circuitto work with differentvoltagepower supplieswithout having to changethe software.It is actuallyquite an important featureof the formula. It seemedlike a crueljoke to me,but the worstpart of developingthe applicationwasyet to come.Despite havinga seeminglysimpleconversionformula,I found that I had a fairly serioussizeproblem;the code seemedto be 100to 110instructionstoo largefor the 1024instructionsavailableto the PIC16F684PICC Lite compiler. The problemwith the codesizewasthe needfor includingthe C naturallogarithmfunction (known as log in C,not ln asis normallyusedin mathematics). This functionseemsto take over 400instructions,and I couldonly allow 300or so.I wasvery surprisedat this situationasI believedthat the naturallogarithm(and exponent)functionswererequiredfor the floatingpoint divisionoperator.Further complicatingthe situation wasthe fact that the MPLAB IDE simulator continuallyflaggeda subroutinereturn underflow beforeexecutingthe applicationcode. It took me anotherthreedays,but I wasableto get the applicationworking for the previousformula.By carefullymanagingintegervariablesizesand looking for opportunitiesto shareapplicationcodeasmuch as possible,I wasableto shoehornthe applicationin, with a dozenor so instructionsto sDare.andit seemedto work. cThermo6a.cis a modificationof the final result, and I found that the digitswould occasionallyflash noticeably.I madethe assumption, first,that the log (C
150
naturallogarithmfunction)took longerthan the 4,000 cycles(4 ms) availableto it betweenLED display updates,and then I enabledthe 8 MHz clock and doubled the numberof cyclesbetweenLED display updatesso the 4 ms delaystayedconstant. Looking at the work that went into this experiment, alongwith the trials and t bulationsI had to endure, you're probablyaskingyourselfif the effort wasworth it. This is an especiallygermaneconcern,considering that I couldhavespreadit out into threeexperiments: LED Ohmmedriving four displays,a seven-segment thermometer. I would haveto ter, and the final digital sayyes,becauseit gaveme somepracticalexperience with floating-pointvaluesin the PIC MCU and, despiteall the problemsI encountered,the voltage-totemperatureformulais fairly easyto observeand checkvisually. I wasableto comeup with the following ruleswhen workingwith floating-pointoperationsin the PIC MCU: .
.
.
r
Limit the number of floating-point operations you are going to useto three:subtraction,division,and floating-point-to-integercasting. Do not use any ofthe logarithm or trigonometric functionsin a PIC MCU where only 1k of programmemory spaceis availableunlessyou absolutelyhaveto. If you are running displayloops with floatingpoint operationsexecutinginsidethe delays, recognizethat the floating-pointoperations take a lot of time,and plan accordingly. Do not obfuscateyour floating-pointcalculation codein order to make them more efficient. If you are going through the effort of including floating point in your application,make sure the theory behind the floating-pointoperations is soundand the formulasand algorithmsyou are implementingare reducedasfar asreasonably possible.Try alsoto avoid many of the conversionsand leapsthat are necessarywhen fitting integer operationsinto a task that requiresdata manipulation.
l , a 3 P I C o I I C UE x o e r i m e n t s f o r
the Evil
6enius
Experiment sr-.|-PlCMfU "Piano"
1 P I C 1 6 F 6 84 1 14-pin
socket
1N914 silicon t
diodes
0 ,47 ItF capacitor tYPe)
(any
0 . 0 1 p F capacitor tYpe )
(any
10k resi stors Dl''!M
Piezo speaker
Needle-nose pl iers Soldeling
1
iron
I
Solder Wire-wrap
wire
IodelibLe
ink
Three-cell clip
AA battery
3 AA batteries malke!
1 Prototyping
PcB
Weldbond adhesive
In Figure7-12,you will seethat I havearranged10 momentaryon pushbuttonsin an arrangementthat is similarto a piano'skeys.This probablydoesn'tseem like suchan amazingapplication;the PIC16F684has12 pins and 10of them couldbe easilyconnectedto individualbuttons,leavingtwo pins for driving out the musicalsignal.In the previoussection,I introduced you to switchmatrix keypads.So you might think that the 10keysare wired asa switchmatrix,resultingin only seven(five columnsof two rows) pinsbeingused. Actually,neithermethodis used.Instead,the wiring usedin this applicationrequiresonly six wiresto interfaceto the 10 buttons.If you havea smallnumberof button inputsfor an application(andyou have designedit to work with only one button at a time pressed),you will find caseswherethis is the mostefficientmethodof widng your application'sbutton input. The methodusedto providethe 1O-buttoninput can be seenin the piano'sschematic(seeFigure7-13).For six of the naturalkeys,thereis a traditionallypulled-up momentaryon button.However,for the four sharp keys,a momentaryon button connectsthe adjacent naturalkeysto groundthrougha silicondiode.When the sharpkeysare pressed,currentwill flow through the diodes,pulling eachof the adjacentnaturalkeys low.Therefore,to sensewhen a sharpkey is pressed, the two adjacentnaturalkeyshaveto be polled.
This methodcanbe usedin a numberof different applications. Rememberthat you are not limited to wiring the in-betweenmomentaryon buttonsto just two standardpulled-upbuttons;youcan usethis methodwith really any numberof standardpulled-up buttons.ln doing so,you will discoverthat locatingthe multiple diodesfor eachbutton in betweencanbe a problem.I am bringingthis up becauseit wasa bit of an issuefor me.However.I wasableto find a
Fiqure 7-la
PIC16F684-based I0-note "Piano"
S e c t i o n5 e v e n S a m p1 e C l ' il c r o c o n t r o l l e r
Applications
151
_:'-r' __L
Figure 713
o c(d .F{
A
p U
E
U H
A
I
c (l
.r{
h
o
9.
X
Piano circuit
prototyping PCB that would allow multiple connections at a singlepoint, and by experimentingwith how I placed the pull-up resistorsand the diodes,I was able to come up with a schemethat wasquite easyto wire and did not useup an excessive amountof space.In Figure7-14,I showhow the diodesare wired to the backsideof the PCB underneaththe naturalkev buttons. cPiano.cis the application code I came up with for this expedment and it delays50 ms and then polls the six input pins to seeif any buttons are pressed.If a pin is pressed, then a PWM period and duty cycleis saved in the TMR2/CCP hardware and pin RC5 is put into outputmodefor the PWM signalto passthe soundto the Piezo speaker.To corneup with the delay periods,I started with a table of the different note frequencies.I then converted them into microsecondperiods and dividedthem by four so they couldbe loadedinto the PR2 register for driving out the different frequencies. You'll find that the final output may be a bit flat or sharp;this is due to roundingerrorsthat camewith converting the periods into integers that TMRZ could work with. *itlcluae /* cPLano.c - 10 Not€
Thl"a aDDllcation noaLtorE 10 Diano keys via 6 I/O Dina anal Dlaya th€ aDprolrliale note aB IoDg aa lhe k€y La pleEsea[ for 50 ps incr€meata. Th€ PRU outDut ia u6ed for the nolea !,rith a 4x Drescale!.
fsl 152
Ez Hz vz Hz Hz Hz Hz Hz
- RAo/RAl - RAo
G* A
-
L,662 1,750
-
955 902 852 8O2 758 715 675 638
ps ps p,e p,a pB rlE pB Es
- P P = 2 4 0
-
602 pa 558 ps '
PP = 150 PP = 1{2
Nolea: PIC15F58{ Rutrning at { uEz with Iut€rnal oEcLllalor RC5/P]-A - Pw!{ RC2:RCo - Soulal InDut BilE Notetl Ab<w€ RA2:RAo - Souril Input Bils Noteil Abov€
rvke Dreflko 05.0L.22
-CONFIG ( INTIO & WD4IDIS & PWRTETI & MCIJR.DIS & I'}IPROTECT \ & ITNPROTECT& BORDIS & IESODIS & FCMDIS) t
int jt char Ke!ryaluei char Freqoutst tnain ( )
t
rrhil€(1
(
== 1)
NoPO r lor (f = ui NOPO,
ll // ll ll
rI\En
//
Loop
//
50nE D€lay
(0 == (K€Walue Lf (0 != (Kewalu€ = 1{2r Fleqout €1ae
Freqout
oft CdE)aratora truln off AIrc r|/ ,F.,2 ',aa 4r. Preacal€r E,nable PDU Oulput Forever
7 < 4555i 7++)i
= ( (PORTC & 7)
Ketrvalu€ if
- P P = 2 0 0 - P P = 1 8 8 - P P = 1 8 0
rrz Hz
garalware
C!'ICONo = 7t iNSEI = 0t E2CON = 0b00000101r CCP1CON - 0b00001100t
"Piano"
The Keya are alefineal as: !'liild].€ C - RC2 - 1,0{5 - RC1/RC2 - 1,108 C* - RC1 - L,L74 D - RCo/RC1 - 7-,248 D* - Rco - 1,318 E - RA2 - 1,395 F - R-e1/RA2 - 1,d60 F* - RAI - 1,558 G
Figure 7-lt{ Backsideof PIC16F684-based piano showinghow the diodesare wired underneqththe buttons
<< 3)
+ (PORTA & 7);
& (1 << 0))) & (1 << 1) ) ) // A
= 150,
t/ e*
(0 == (Ket^Ialu€ & (1 << 1))) elae if (0 != (Kewalu€ & (1 << 2))) if
l , e 3 P I C @l l C U E x p e n i m e n t s f o r
the EviI
Genius
= 150r F!€qoul // els€ , Fleqout = 158i // F* else if, (0 == (K€]|value & (1 << 2l)l = 180r Fleqout // (0 == (Keyvalu€ << 3) ) ) else if & (0 t= (Kefltalue & (1 if 4))) Freqout - 188i ll F eqout = 200r // (0 == (Ket4/alue elEe if & (0 l= (Kewalue if & (1 F!€qouts = 212, // elEe FreqOuE = 225, // (0 == (Keyvalue & elBe if Fr€qoul = 240r // elBe / / Er€qouts = 0,
D* (1 << 4)))
(0 == Freqout) tf TRISC - 0x3F, elEe
Nothing Presaetl Tuln OFF Output setup PwM
ltRISCs = 0r // fi ) // €lihw ) // Enal cPiano
D
(1 << 5) ) ) Presaeal
{ PR2 - F!€qout t CCPR1L-F!€qOu!/2t
Ouqntt 50% Dtrty Pwu sigrnal
Signal
'iJ
I shouldpoint out that this circuit is not limited to only 10pins.For my application,the limiting criterion wasspacefor buttonson the prototypingPCB.Using this method,if I had usedall 11 availablepins on the PIC16F684,Icouldhavesupportedup to 22 keys.This is a goodmethodto rememberwhenyou havea fair numberof input buttonsto poll but don't want to go throughthe hassleof the switchmatrix code.Generally,this schemerequiresone-halfthe buttonsasI/O pins,andit canbe extendedfar beyondthe 10 buttons presentedin this experiment.As a point of reference,it seemsthat 20 is the numberof buttonswherea switch matrix keypadis more efficient(in termsof I/O pins) than the methodDresented here.
s )) )
Nothing
Output
//
j
5-l t,:t .al
i-f
i ?i!
I
Cycle
Experiment 55-Model Flailurag Suritchfontrol ',AJ
1 PrcL 6F68 4 1 14-pin
'i.r;
socket
fRIACs (Radio Shack 276-1000 reconmended) 1 5.1V,
1 Anp Zene! diode
1 lN9l4
silicon
0 . 0 1 / u , Fc a p a c i t o r tYpe)
Osci lloscope
Soldeling
1 2204, p Iie!s
NeedIe-nose
wire
1 Two-position block
HO scaLe remote tlain switch
Thlee-position block
flain
Prototyping
supply
(any
a"
resistor
;
1
poi.e!
i.,"*4
les istor
iron
SoIder Wire-wrap
1 l0k
!-watt
g'
diode
1 330 pF electrotytic capacitot DMM
*",i,
telminal
td
terminal PCB
r.{ Comparedto other hobbies,model trainshave changedvery little sinceI wasa kid.When I go to a local train store,I'm alwaysdepressedto seethat powersuppliesare still basedon a Variac(variable transformer)train Dowercontrol and a transformerfor
S e c t i o nS e v e n
18-VoltsAC accessory power.I realizethat the DCC systemdoesbdng the hobby into the twenty-firstcentury,but thesecontrolunits aswell asthe remoteunits are very expensive. What is neededis a low-costway of providingcomputerizedcontrol of trains and the
S a m p1 e C l ' li c r o c o n t r o I 1 e r A p p l i c a t i o n s
L53
ra . , fi
I
r!
*P
J'l
tu r-{
iq
& , t!
IJJ
layoutsso that hobbyistsof moderatemeanscan experimentwith computercontrol of their layouts.In this experiment,I will showhow a PIC microcontroller canbe usedto control a switchusingthe accessory power from the standardtrain power supply. Before goingfurther,I want to note that this ctcuit is powered by a/renrating current (AC). The AC usedin power this experimentis the benign18-VACaccessory available from a hobby train power supply.The circuit'spower supplyis not designedfor usewith household AC (110or 220volts dependingon whereyou live),which canbum or electrocuteyou.Although the methodsusedto designthe power supplyare the same, and I show how I calculatedthe valuesfor this experiment,the componentvaluesare not valid for household AC. If you want to interface your application with householdAC power (or anyAC voltagesother than the 18volts usedin this experiment),makesureyou consultwith an engineeror electricianbeforeconnecting the circuit to the power supply.Be sure you have selectedcorrectvaluesandhavewired the circuit accordingto your local code. The controlcircuitis quite simple(seeFigure7-15), and I was able to wire it on a small prototyping PCB (seeFigure7-16).ThePIC deviceis poweredby a 5.1volt Zener diodewith a 220Oresistorand standard resistorto rectify and regulatethe current.The 330pF capacitorensuresthat the voltageis smooth.ThePIC MCU continuouslypolls the SPSTswitch,and if it changesstate,one of the two TRIACS is drivenfor a few millisecondsto changethe solenoidin the track switch.If you are wondering,the applicationcould be easilyexpandedto handlemultiple switches. Although dueto someof the issuesthat I had.there are some considerations that you shouldbe awareof that I will sharewith you at the endoI theexperiment. To calculatethe valuefor the components, I assumedI would run the PIC16F684at 5 volts,so I useda 5.l-volt Zener diode (whichhasa constant5.1 volts acrossit) and a silicondiode and resistorto rectify and limit the curent flowing through the circuit. The RadioShackTRIACs I usedrequire25 mA of current to operate,so I wantedto havea maximumof 50 mA (25 mA for the TRIAC and25 mA for the PIC MCU and other components). To find the correctresistor value,I usedKirchoffs and Ohm'sLaws:
= 12.2 volts
/ 50 nA
= 244Q
I useda 220.0resistorin the circuit becauseit is a standardvalue.For its power rating,if 50 mA is passing throughthe resistor,0.55wattsof power is beingdissipated.Toensurethat therewouldn't be any power issues, I useda 1-watt-ratedresistor. With the powersupplycircuitryselected,I built the cfucuiton a prototyping PCB using small terminal blocksto connectthe c cuit to the 18-voltpower supply and to the train switchusingthe wiresthat come with the train switch. (For this, I bought an ATL RemoteRight-HandSwitch,item number851.)Before burninga PIC MCU with code,I testedits operation by shorthg pins RC4 and RC5 to ground to make sure the TRIACs (which are simply AC switcheqcontrolled by current)would changethe switchsolenoid'sstate. In my application,I kept the I/O pins driving the TRIACs in input modeuntil the solenoidwasto be driven. When I tried the PIC16F684in circuit,I found that the circuit worked fine to changemy switch to one state,but had problemswith the other state.In this state,the switchwould start chattering,and the soleprobe on noid got very hot.When I put an oscilloscope the I/O pins,I discoveredthat both of them were becomingactive.Further investigationrevealedthat the solenoidstateseemedto require so much power that the 18 volts ofAC wasreducedto zero.After consideringthe problem,I decidedthe simplestsolutionto the problemwasto usethe PIC16F684'S EEPROM datamemoryto savethe stateof the switchin casethe PIC MCU wasreset.Thiswasa fairly minor modification to the originalcode,and I calledit ci[rainz.c: #incluale cTraln 2.c - controL /*
Ac Dliv€n
Train
control
This Drogram ia a modlif,ication of "clrain" Eo take adlvanlag€ of, the EEPROM Data lilemory !o recoral the laal aelting of the PIC Elritch RA3 - Button CoDnectioa RC4 - Train 1!RIAC1 RC5 - Train TRIAC2 ntzke Drealko 04.12.30
!tr VAc = V-{zener}
+ Voi"a" + Vn."*.". (J
H !d-.!
;€
= 5.1 volts
18 volts
+ 0.7 volts
+
I
V"""r".". Vnesistor= 12.2 volts R = V / I
154
AC Common
Figure 7-'15 Train
1 e 3 P I C @l l C U E x p e n i m e n t s f o n t h e E v i I
6enius
( ( i < 1100) && (0 == RA3)) while ( 0 r = P"A3) if Bounce // switch else Debounce // Increment = 0t Bstale EEPROM WRITE (4, f o r ( i = 0 t i < TRISC4 = 0i f o ! ( i = 0 i i < TRISC4 = 1t
] else
if
((0
Active state // rnalieale 0)r // a.ecofil in EEPROM 5555r i++) r // 100 ns // Enable RC4 as Output 5565r i++), // 70O ne Dliwins Solenoid // Finished
!= RA3) && (Bstate != 1)) // Sttr'ilch chaflge
{ Fiqure 7-16 Sintplehobby train switchcontrol ctrcuit thot replacesstandardmechanicalswitchblock
& WMDIS & PIIIRTEN -CONFIG(IIIIIO UNPROTECT \ & T'NPROTECT & BORDIS & IESODIS
Bs€ate
int
& IICI,RDIS
Debounce Count€r i = i + 1t // Itteremen! state Active Bstate - Lt // halicatse irr EEPRoM | / 'tecord, EEPROM_WRITE ( 4 , 5666r i++)r // 100 ns f , o ! ( i = 0 t i < TRISCs = 0t // Elable Rc5 as Output 5666r i++)r // 100 ns f o r ( i - 0 t i < solenoid TRISCs = 1t // Finished Dliving // fr J // el-ihw ) 2 I / E']A cTrain J
&
& FCMDIS ) i
= 2t
tnain ( )
{ PORTC = 0t CltlCONo = ? t ANSEL = 0;
Output BitB are ].ow turn off Conll)alatol.s Turn off aDC No output6 {Yet) i++) // 250 ms Initial f o r ( i = 0 t i < Delay ( (EEPROM-READ( 0 ) == 91 ag if (EEPROT''READ(1) == oxFF) && (EEPROM-READ( 2 ) == 0x55) && (EEPROM-READ( 3 ) == 0tAA)) = EEPROM_REiAD( 4 ) t Bstate the Slate // rnitiaLize // // // // 18000r
t EEPROM_WRITE(0, EEPROM_$RITE ( 1, EEPROM_I{RITE( 2, EEPROM,WRITE( 3, EEPROM-VTRITE( 4, // fi , while(1
t if
((0
== L)
O) '
//
Put
oxFF) t O'.55) ' O:.AA)' 2) t
//
Nolhing
ll
in
Check
set
Loop Forever
== RA3) && (Bstate
I= 0))
//
$titch
wbile (( i < 1100) && (0 != RA3)) ( 0 = = R A 3) if Bounce // switch
Y€t
When you build this application,you may find that you do not needto savethe stateof the solenoidin EEPROM datamemory.I havetried this application on only one train switch.As the sayinggoes:YMMV (1tourmileagemay vary).You may find that you requirethe EEPROM for both solenoidstatesor you might find that you don't requireit all. This applicationcanbe easilyextendedto multiple switches(usinga singlePIC16F684,you could control four switches),althoughI suspectthat you will find a certainamountof variationbetweenthe switches, which could leadto someproblems.Tominimizethe chanceof power problemqmake sureyou engageonly one solenoidat a time;if four switchesare activeat the sametime,you shouldsequencethroughthem with somedelaybetweeneachsolenoidactivation.To ensurethere are no power problems,you may want to passthe Vdd voltagesupplythrougha diode and then havea largecapacitor(47 pF to 100pF) provide a temporarypower supplyif a solenoidreducesthe voltaseto zero. accessota
S e c t i o nS e v e n S a m p1 e C l l i c r o c o n t r o l l e n
Applications
155
Experiment55-PC 0peratingStatus Displag
1PrC16F684 I
I4-pin
socket
? 1N914 silicon
diodes
1 1o-LED bargraph
disp lay
10 4700 resistors text )
(see
47 g,F electrolytic caPac].tor DMM NeedLe-nose pIiers
0.01 pF capacitor tYpe )
Soldering
iron
PrototYping
wire
DB-25M solder nector
SoIder Wile-wrap
(any
PCB cup con-
Weldbond adhes ive
One PC peripheralthat hasalwaysfascinatedme is the remotestatusmonitor that providesyou with an alternativeform of feedbackregardingthe operationof your computerin the form of an LCD display,a glowing ball,or a seriesof LEDs. In thisexperiment,Ihave createda simple10-LED operationsdisplaycontrolled by the parallelport that canbe addedto a WindowsPC in just a few hours.It's importantto note that although the PIC MCU sideof the experimentis fairly simpleto build (and is very similarto the other experimentsin thissection),the PC software,despitenol requidnga specialized devicedriver,is fairly sophisticated and plobatrlycannotbe replicatedor modifiedeasily. The circuit (seeFigure7-17)consistsof a PIC16F684connectingto a PC'sparallelport and has
the ability to turn on a singleLED becauseit's poweredby the PC'sparallelport. Poweris providedby sevenof the parallelport's eight output pins.These pins are pulled up intemally by the parallelport and source1 mA of current.which shouldbe sufficientfor runningthe PIC MCU and a singleLED. The remaining I/O pin is used,alongwith the printer strobebit, to latchin a bit of data.When I built my application(see Figure7-18),I useda 470OSIP and a 470Oresistorfor limiting the LED current.You canuseeither this solution or 10individual470f) resistors. The applicationcode(cPerfMon.c)waitsfor eight bits to be sentto it and then XORS the first four bits againstthe secondfour bits,and,if the resultis all bits set,the specifiedLED tums on. *incluale - Display cPerfllon.c /*
Performalrce
Value
from
por! This program conneets to the paralle1 of a Pc and u'i11 receiw€ eight bits of, alata on RA3 (Clock) and RA4 (Data) anal compare the first fou! bits $rith the second antt if they are conpl.ementary, will alisplay the BCD value ort a 10 LED bargraph alispLay. Thia
Figurc 7-17 PerfMon circuit
L56
prograrn
was wlilten
to
r'rork erith
Hardlnrare Not€s: PIC16F581I Runtring at 4 MHz AA3 - Printer Polt CLock RA4 - Printe! Polt Data RC5:RCo - ]Jow 6 Bits of the Display RA2:RA0 - Bits 8:5 of the Display
l , e 3 P I C @I ' l C UE x p e r i m e n t s f o r
the EviI
6enius
RA5 - Bit
9 of
the
DiBplay
llyke prealko 05.oL.22
& WIXTDIS & PWRTEN & ITCLRDTS & -CONFIG(INTIO UNPROTECTr \ & I'NPRC"IECT & BORDIS & IESODIS & FCUDIS),
char char char
BltcounE, = 0t Bitvalue = 0t Bitcotnp
natn( ) t PORTA - 0x3Ft PORTC = 0x3Ft CMCONo = 7, .ANSEI, = 0 t TRISC = 0t rRISA = 0b011000t
/ / Diar,lay
Active
Conrparatsora / / T11r'r off // Turn off aDC // A1l 5 Bi.ta outDuLa // RiA{:8i43 lry)uts
osccoN = osccoN | (1 << {), ( 1 == 1)
rphile
Negative
//
Run Prc ltcu at g !|Itz
/ / l2ooE Eotevet
{ (Bltcounl
= 0r
< {t Bilcount++) Bitcount { Bils // Get First (RA3) t f,or Bit lrhiLe // Igail = (Bitvalue >> 1) + (RA{ * 8)t Bitvalu€ (lRA3)r while // Make Sure Bit ia sish // zof l
for
(
(r
< 8, BiEcount++) // Get Seconal { Bita (RA3 ) t while // wait for Eit = (Bitconp >> 1) + (aA{ * 8)t Bitcoq) (tRA3), while iB trigh // ltak€ gure ait ll rof ,
fo!
Bitcount
{
^ Bilcdll)) t= 0x0F) // No Match, wait fo! Low // wait fo! Hish // wait
( (Bitvalue
t
q'hile(nA3), while ( !RA3) t
) €Lse
//
(BitvaLu€
{
1 Bit
Data oK - r,ight LgD Agpropriale
< 5)
PORTC = 0x3F ^ PORTA = 0n3Ft
// o Eo 50% (1 << Bitvalue), // Eisrh LEDE Off
) etse
if
(Bitval.ue
< 9)
{ PORTC = 0x3Ft PoRTA = 0x3F ^
(1 << (Bitvalu€
-
6))t
) elEe
//
9O%+
{ PORTC = 0x3F, PORTA = 0x1F, /l fi , Bitvalue BttConP ) )
= 0t
//
Reaet valu€a
= 0,
// elihw // Enal cPerf!4on
S e c t i o n5 e v e n
th€
corq)ali€od
cPerfMon.chasa simple,but quite effectivemethodof error detection;if after eightbitE the XOR'd resultis not 0x0F(all bits set),it then waitspastthe next bit andrepeatsthe processwith the next eightbits until the XOR'd resultis 0x0F.With the PC softwaresending data onceeverytenth of a second,it will take up to three-quartersof a secondfor the PIC circuit to becomesynchronizedwith the PC output. Although the PICC Lite compilercodefor the PIC16F684is quite simple,the PC codeto producethe dialogbox shownin Figure7-19andmonitor the amountof main memorythat hasbeenallocatedby the differentapplicationsrunningin the PC will be very complexthe first time you look at it. An important attributeof this applicationis that it doesnot requireany specialprinter devicedrivers.If you have enoughexperiencewith the PC,you will know that mostpdntersrequirespecializeddevicedriversto provide bidirectionalcommunications or evenstatusmonitoring to suspendsendingdatauntil the current buffereddatahasbeenprinted.In this application,I simplyopenthe LPT file deviceand sendthe eightbits of data asonebit of a byte (the other sevenbits are high to ensurethe hardwareis poweredby the parallel port).This is possiblebecausethe parallelport is wired asLoopbackport.As such,it appearsto the basic printer softwareasa "dumb" ASCII printer andwill havedata sentto it at full speed(roughlyone byte every50 ps). The applicationcodeis written to be built under Cygwinand run under GCC,and it consistsof five modulesthat are compiledandlinked together.To debugthe application,I usedDDD, alsorunningunder Cygwin.Theapplicationand filesshouldbe buildable underVisualStudio.Using the open-sourcetoolsfor developmentmeansthat you canreplicatethe application and avoidthe costsof usingVisualC+ + or Visual BASIC. If termslike GNU ProjectGCC C compiler, DDD debugger,and CygwinWindowsinterfaceare Greek to you, don't worry;asyou leam more about programmingPCsand gainunderstandingof how to createand build Windowsapplicationqtheseterms (and tools) will becomemore familiar to you. The basicapplicationitself waswritten in C (for GCC), is calledPerfMon.c,and is listedbelow.This application can accesseither LPT1 or LPT2 or neither, and it rememberswhich onewasactiveby usingthe PC'sregistryfor storingthe lastusedport. I originally wantedthe applicationto displaythe PC'scurrent load,but this turned out to be problematicbecause eachversionof Windowsusesa differentmethodof computingthe currentload.Instead,I displaythe current memoryusage,which can alsobe a usefulload indicatorin a PC if it startsrunningvery slowly.Along with the sourcecode,".rc" files are requiredthat can
S a m p l e C l ' li c r o c o n t r o I I e r
Appl ications
15?
ir.g :.!',i
is i{
ir, i!"{
tn l"1i
i:fga l,p j N
*rt 1,"{ - :
ft? ! :
;.-;
r11 !i'l
LJ ?"J, tA {-} g-."3 !\r
Memorl' Usage: 75% LFT$elect:LPT2 SelectLPT1 elect
ry!!f] i . q Figufe 7-i9 Figufe 7-lB The PerfMon applicotion'scircui.t connectsto and is poweredby a PC'sparalleLport. be found on the PICkit I StarterKit's CD-ROM or at http://www.myke.conr. Thc applicationiconswele createdusingPaintbrush and then convefiedinto ico format.To build the entire applicationand be ableto debugit usingDDD,I used the following statementsin the CygwinX-Windows box: winalr€s %l.rc gcc -mwinalows %1.res -tgdi32
-O coff -o -nno-cyg$rin -l.user32
%1.!es -g -o
%L.exe
eo1.c
Due to the untimelydemiseof my PC on which I normallyuseto createPC and PIC MCU softwarc,I had to breakup the PC and PIC MCU softwaredevelopmenttbr this experimentonto two PCs.Amazingly enough,when the two piecesof softwarewerc brought backtogether,the appllcationworked quite well, althoughoccasionallythe lit LED would changeto an
158
PerfMon operati.ng
unexpectedvalue.Thesolutionto this problemwasto run the PIC MCU at 8 MHz, rather than at the standard 4 MHz, usingthe theory that the incomingdata and changingbit valuesweretoo tast for the 4 MHz device.Thischangeeliminatedthe problcm with the errantLED, and the applicationhasbeenrunningperfectly eversince. Twicein this section,I encounteredsituationswhere the applicationworked well,but neededto be spedup to work perfectly.I want to makesurethat you understandthat in both cases, the problemwasreasonably well definedand the clock doublingwasusedto addresstheseissues. I mentionthis becauseI do not want you to think that by increasingthe clock speed you canfix the problemevely time you havean appli cation that occasionallyruns errantly.Befbre attempting any fix, you shouldhavea theory behindthe cause of the problemand what you expectto gainby the fix. If you don't,chancesare you will not fix the problem or you'll end up with an entirelynew problemrequiring its own fix.
l , a 3 P I C o l ' l C UE x p e r i m e n t s f o n t h e E v i l
6enius
Section
Eight
Introdutrtion to PIE@ MfU Hssemblg LanguageProgramming
PICkit-l
Starter
Kit
Prc16F684
So far in this book,I haveshownyou the highlevel C programminglanguageand how to useit to programa PIC16F684to perform varioustasks.You shouldnow be reasonablycomfortablewith programmingthe chip and comingup with applicationsthat perform useful functions.You shouldalsohaveusedthe simulatorthat is built into MPLAB@IDE to help you verify the operation of your programbeforeyou programa chip or to help you debugyour programonceyou discovered your programdoesn'lwork exactlyasyou thoughtit might.You are now readyfor the next stepon your journey:learningassembly language programming. The computerprogramthat convertsan assernbly languageprograminto the .hexfile andis then programmedinto the PIC@microcontrollerchip is known asan assembler.'fhe assembleris analogousto the compilerprogramthat convertshigh-levellanguage statementsinto a .hexfile.Unlike the PICC@Lite compiler,the PIC MCU assembler(known asMPASM@ assembler)is built into the MPLAB IDE and is loaded automaticallywhenyou insrallMPLAB IDE. Assemblylanguageprogrammingis usuallylooked upon with a greatdeal of trepidation;it is perceivedto be more difficult to learn than a highJevellanguage like C for programmingapplicationsand debugging failingapplications. Another perceptionis that code written in assemblylanguageis more efficientthan codewritten in a highJevellanguage.I would disagree with all of thesestatements. Assemblylanguageprogrammingis not more difficult to learn than a highlevel language; it is merelydifferent. The differenceis in the basicstatementsand in understanding how they are usedto createapplica-
tions.Onceyou are comfortablewriting codein assemyou will find that it is just asmuch mental bly language, work aswriting an applicationin a high-levellanguage. You may find that an assemblylanguageprogram takesmore physicalwork (keying)than a high-level program,but this is due to the increasedgranularityof the assemblylanguageinstructions;eachone performs a muchsmallertaskthan a highlevel languagestatement.Additionally,I would saythat debuggingin assemblylanguageis a lot easierthan in a high-level language, becausethereis muchlessambiguityabout what the programis doing.You probablyappreciate this statementknowingsomeof the strangethingsthat canhappenin C statements. Finally,an applicationthat is poorly written in assemblylanguagewill not outperform an applicationthat is poorly written in a highlevel language. The mostimportantparametersof any programare its readabilityand the efficiencyof the algorithmsthat are usedto implementthe requiredfunctions.If the programcannotbe easilyread,you will haveproblems completingit, gettingit running,and debuggingit. If no thoughtis put into the operationof the application, then it will not run appreciablyfaster.Regardlessof the programminglanguage, theseparametersmust alwaysbe consideredwhen designingan application. An excellentanalogyto the differencesbetweena highJevellanguage(like C) and assemblercanbe illustratedby the commandsneededto explainhow to walk acrossthe room and pick up an object.In a highJevellanguage, the commandstatementswill look somethinglike the following:Turnright, Stepforward six times,Bend over."Assemblylanguage
159
instructionsfor the sametaskwould look like this: "shift weight on left leg, lift right leg two centimeterg move right leg 10 centimetersto the right, lower right leg."Both will get the job done,but the assemblylanguageinstructionswork at a muchlower level. In this introduction,I haveusedthe term instruc,ions to descdbethe assemblylanguagestatements.At its most basiclevel, an instruction is a collection of bits that commandthe processorto carry out a simpletask. For arithmeticoperationqthesebits specifythe task,
€', .{
'".1 lel
whereinput parameter(s)comefrom, and wherethe resultis stored.If multiple arithmeticoperationsare required to carry out a task,then multiple instructions are required.In additionto arithmeticinstructions,a variety of other t)?es of instructions exist that control the operationof the processor, the microcontrollerin which it is built, andspecifywhereand how the codeis to execute.I will explaintheseinstructionsin this section.As I saidpreviously,theseinstructionsperform the sameoperationsperformedby the high-levelstatementEjust in much smallersteps.
w {d
Experiment 57-The asmTemplate.asm File and
0, .tJ ff
Basic Directives
F{
p{
o $"t H E} tu
Beforestartingan assemblylanguageprogram,I generallybeginwith a templatesimilarto the one I introducedyou to earlyin the book for C programming. This template is usedto remind me of the basicinformationrequiredin a programand the basicprogrammingheadinginformationneededto get a basic programrunning.The asmTemplate.asm file that I used for the programspresentedin this book looks like: "asmT€nlrlate title Tet[)Ia!efl E:rplaiD
fll
"c"
tla
//
h
the
Ogeration
Equivalent P1.rt "C"
-
AsselibLy
of
the
Language
Coaling
program.
cofle:
Equivalent
zunction
Eele
Autshor Date
i I
IJIST R=DEC I}{CLUDE',p15f 684. inc"
lJ'
-CO}TFIG -cpD_oFF wDI_oFF
& _BOD OI'F & _FC!'EN_OEF & _IESO-OFF & cP_olr & _!!C!RE_ON & _P!{RTE_ON & & INI,OSCIO
Valiabl€s CBIOCK 0x20 Put Variabl€ Names Here t If Variable lJonger thsr! 1 Bt te, t EIIDC PAGE org aop
" !*{
r
Mainline
160
P.EGE SubroutineE
€nd
Let's go throughthe lines of this file to help you understandthe differentfeaturesof the templatefile. Thiswill alsoserveto introduceyou to someof the information that you will need to carry out assembly languageprogramming. The first line contains the /il/e directive and will place the string in quotes on the first line of every listing pageasa header.Directivesare commandsto the assemblerthat are usedto control the assemblyof the program.Thetitle line that I useconsistsof the name of the file and a brief descriptionof what it does;this helps me find a program with a specific function aswell asidentify the file in which it is contained. The next seriesof lines are commentsand usethe semicolon(;) characterto indicatethat everythingto the right is a commentand can be ignored.Theseare similarto C's doubleslash(i/) comments. They explain the following: .
i
n!
;
r Plrt in
".*B!rtses"
. 0 t Coale
NoP Requiretl
for
The operationof the program AnalogousC code(if appropdate)to explain how the highJevelfunction is to be implemented The author ofthe program and the date that it is written
Debugg€r
The /isr directive is used to specily different assembly andlistingcommandsto the assemblerprogram, which then converts the assemblylanguageprogram into the hex file of instructions to be programmed into the PIC MCU. If you look at the list directive parameters (shownat the end of this section),you will
l , e 3 P I C @l " l C UE x p e ri m e n t s f o n t h e E v i I
6enius
discoverthat thereare quite a few,and many will seem like you shouldusethem.However,the singleparameter that I havespecifiedasa list directivesetsthe defaultnumberbaseto 10 (decimal).(I feel that rhis is the only parameterthat shouldbe specified.)Adding additionallist directiveparameterscan affectthe operation of the final application,how it is programmed, and the difficultyto port the codeto anotherPIC microcontrollerpart number. T}:.einclutledtective loadsan informationfile that addsadditionaldirectivesand instructionsto the programfile.The pic16f684.inc file is found in the folders loadedduringMPLAB IDE installation.Thesefolders are usedto definethe variousregistersand functions of the PIC16F684, relievingyou of the responsibilityof havingto do this (exactlyasthe "#include" directivedid in the C programs).Whenyou are developing rnorecomplexapplications, you may find it useful to put commondefinitionsand codein .incfiles to avoidhavingto key repeatedlyin the sameinformation and providea centralrepositoryof definitions and codesfor all applicationsin your working curent proJect. The _CONFIG directiveis usedto specifythe configurationword bitqjust asthe _config( directivedid in C programming.Like the C version,eachparameter is ANDed togetherto specifywhich bits are resetand which are set.Note that _CONFIG hastwo underscoresandcannotstart in the leftmostcolumn.Also note that whenthe directiveis listedhere in the book, the parametersare generallyprinted on two or three lines,but they shouldall be in the sameline.I have avoidedputtingthis directivein applicationsthat will not actuallybe programmedinto a physicalchip, becausethe double-lineformattingcanmake it difficult to readand key coffectlyinto the experiment's programif it is not necessary.
accomplished and,later in this section,I will note the pointsto take under considerationwhen declaring variables. Next,the resetaddress(address0x000)is specified usingthe drg directive,and the applicationcodestarts after it.The assemblerinitializesits programcounter to zero beforestartingto convertinstructionsinto bit patterns,but it is customaryto specifyzero to ensure the memorylocationstartsat the resetaddress. The nop (pronounced"no-op") stringis actuallyan instruction, which commandsthe processorto do nothing ovel one instructioncycle.The valueof this instruction will be explainedlater in the book;it is a lot more useful than you might imagine.Placingthe nop at the resetaddressis necessary for usingthe MPLAB ICD2 debugger,and,althoughyou may not havean MPLAB ICD2 debugger,it is a goodideato put this simpleprovisionin for whenit is needed(i.e..when the MPLAB ICD2 debuggeris available). Finally,the assemblylanguageprogramcanbe written out in the file.Unlike in C programs,in assembly languageI put subroutinesaJ?er the mainlineprogram. The assemblerreadsthroughthe assemblylanguage sourcefile beforestafiingto createthe .hexfile so that the addressof labels(includingsubroutinelabels)are identifiedand availablewhenthe .hexfile is beingcreated.Thisis differentfrom a C compiler,which doesn't identify subroutineand functionheadersafter they are used.I couldplacesubroutinesat the start of the program,but this would necessitate making the mainline which of the programjump over the subroutines, makesthe programmore difficult to read and follow I realizethat in this assignment, I still havenot givenyou enoughinformationto start programming your own assemblylanguageapplication.In the next you will be able to start programming few experiments, on your own.
T\e CBLOCK andENDC directivesare usedto declareprogramvariables.I will explainhow this is
ExFeriment58-5pecifging ProgramMemorg Fddresses When I am programmingin assemblylanguage,I really don't carewherethe instructionsare beingplacedin the PIC MCU's programmemory.The MPASM assembler that is part of the MPLAB IDE doesa very good job of managingprogrammemoryaddresses and relievesthe programmerof the responsibilityfor calculating the addresses themselves. By following a few simpleconventions, you canwrite assemblylanguage programwithout ever beingconcernedwith the actual addressof an instruction.
S e c t i o nE i g h t P I C o l l C U A s s e m b l y L a n g u a g e P r o g r a m m i n g
161
New Program Counter Addfess (Goto/Call)
DalaBus
PC lncrement Program Memory Read Address
Figufe 8-l
B Element Program Counter Slack
Programcounter
The programcounteris a fairly sophisticated counterthat keepstrack of whichinstructionis to be executednext (seeFigure8-1).In normal operation, after an instructionis readin for decoding,the program counteris incrementedcausingthe addressoutput to point to the next instructionin the program.The valuein the programcountercanbe changedfour different ways: .
. .
.
A new addresscanbe imbeddedin some instruction,and this addresscan be loadedinto the programcounter. The programcountercan be changedalgorithmically by the executingprogram. Cefiain instructionswill incrementthe program counterwhen specificconditionsare encountered. The plogram counter can be updatedvia a last in-first out (LIFO) stack.
As you becomefamiliar with assemblylanguage programming,you will becomecomfortablewith using all four methods,but right now you shouldjust concern yourselfwith changingthe programcounterusinga valuein an instruction. The instructionsthat changethe programcounterto explicitvaluesare the aptly namedgrn andcall instructions, which changeexecutionto the specified addressor invoke the subroutineat the specified address, respectively. Looking at the goto instructionin its mostbasicform, its executioncouldbe summarized asfollows: golo
0x????
t
Ptoglam
count'ef
= 0x0????
The value0x0????is known asan lmrzediate, or lit eral,valueor number.It is part of the programmemory and cannotbe changedduringprogramexecution. When peoplefirst startedprogramming,this valuewas literally a number.Before entry into the computer system,the programwould be written out on a sheetof
L62
paperwith eachaddress, and actualjump addresses would be enteredmanuallyinto the program.Thecode snippetbelow,which togglesan output pin seventimes, is written out with the addresses for eachinstructionto showhow this is done: 0x01234 0x01235 0:.01236 0x01237
Inovlltr' bsf bcf addlw
0x07 0*05, 0x05, oxFF
0 0
i i i i
0x01238
btfss
0x03, 2
i
0r{01239
goto
0x1235
i
Loop 7* PORTA,Pin0=1 PORTA,Pin0=0 subtract 1 fron Loop Counter If Zero Bit Set Skip Over Next Else, R€pea! Bit Pulse
This methodof programmingwasvery tediousand had the potentialfor many errors. As time progressed, the ability to specifycharacter stringsfor specificaddresses wasaddedto assemblers. By placingthe labelin the first columnof the plogram file and endingit with a colon (:), the assemblercould recognizeit asa label and assignthe addressvalueto it.Then,whenthe label wasencounteredagain,the assemblerwould substitutethe addressvaluefor the Iabeland avoidthe needfor the programmerto keep track of the addressmanually.Thelabel alsomakesthe programsubstantiallyeasierto read.Using this ability, the snippetabovebecomes: 0x07 Loop: bsf aaLllw btfss goto
; ; r ;
0 x 0 5 , 0 , 0x05,0 ; oxFF r Ot
Loop 7* - At AaLlless O*OL234 Label halicatiltg llthele to Return Execution P O R T A . P i n 0 = L PORTA,Pin0=0 S.rbtraet 1 frcm ]"oop Counler If Zelo Bit Set Skip Over Next Replace hstruction with Aildresa ( 0x01235 ) $'hen value program assefiibling
Labelsare stringsofASCII alphanumericcharactersthatstartwith ato z,A Io Z,or andcanhave0 to 9 , a t o z , A t o Z , o r f o r a n yo f t h e r e m a i n i ncgh a r a c ters.Labelscan be up to 255charactersin length(the maximumwidth of an MPASM assemblersourcefile) and canoptionallyend in a colon.A labelcan be either on the sameline asan instructionor on its own line.I recommendthat labelsare on their own line and alwaysendedwith a colon (asI havedonewith loop in the previoussnippet).This will help you recognize labelsin the programand not confusethem with instructions,directives,macros,or variableswhenyou first read throughan application. This one simpleability to keep track of the address valuefor a label hasbeenexpandedto the three different methodsshownin the following program:
l,el PfC@ CU Experiments for
the Evil
6enius
,'asrnAddresE title specifying Addrerses"
-
Different
ways
of
Demonslrate the 3 methoalB of speeifying program menory addresses in the PIc rllcu uaing MPASlil assenbl.er. Hardware Noles: PIC16F684 running
at
4 Msz in
SinuLator
Mtake Prealko 04.09.10 LIST R=DEC rNcr,uDE "p15f 584. inc " PAGE ofg nop goto
org
0
Mainline 1st Methott: Jump to i sp€cified Address r
Progranmer
47 r
User
specifieal
t
2nd Method:
r
3!d
Adalress with
ra.be1
MainIi.ne: solo
t+1 Use Relative
AdLIreBs
Loop: goco
Method:
,funq) to
Label
,ratalress
tJoop ,
Plovideal
by MPASM assetnbler
end
Wren you oeate the projectfor an assemblylanguageprogram,you are goingto do it in the sameway you do it in a C languageproject.Betoreyou attemptto link the assembly languagesourcefile to your project usingAdd File,click on "Project"andthen on "Select LanguageTool."Youcanthen select"MPASM Assembler,"followedby "OK" to specifythat the project involvesan assemblylanguageprograminsteadol a C program.PressCtrl+F10to build the assemblylanguage programjust asyou would build a C languageprogram. The first methodinvolvesspecifyinga locationfor executionto jump to, putting in a labelthat is automatically giventhe address, and then executinga goto the label.The new addressis specifiedby the org directive. This directiveforcesall subsequentinstructionsto br: placedin programmemorystartingat this address. Insteadof usingthe org directive,I could haveset the goto addressasa constantvalueor I couldhavejust put the desiredaddressin the instruction(e.9.,goto 47).Although both of thesemethodsseemsimpler, thereis the increasedpotentialfor either an incorrect addressto be enteredinto the goto instructionand for the instructionsat the addressto be incorrect.By using the org directiveto set the start of subsequentinstructions at the label,the goto addresswill alwaysbe the instructionto start at the desiredaddress, and the
instructionsthemselveswill start at the desired address. The needfor explicitlysettingthe startingaddress for a block of instructionsis ra[e.The only situationI can think of wherethis is importantfor the PIC MCU is whenyou are settingthe addressof codethat is used to implementthe interrupt handler.The code addresses shouldbe explicitlyset if the application goesbeyondthe fint codepagein memory.Somepeople like to moveblocksof codeto specificareasof programmemoryto make debuggingsimpler.Because you will not be working with interruptsin the PIC MCU, and becausethe PIC16F684doesnot havemore than one pageof programmemory,thereis no need for explicitlysettingcodeaddresses. The availabilityof the MPLAB IDE with the sourcecodesimulatoreliminatesany advantages of putting blocksof codein specific locations.You will find that i1is fasterto wdte an applicationwith the differentpartsof the codebutted, or concatenated, together. The $ symbolin MPASM assemblerretumsthe addressof the instructionin which it is used.Jumpingto the $ symbolturns the instructioninto an endlessloop. By addingo[ subtfactingconstantvaluesto the $ symbol,goingto addresses relativeto the currentaddress canbe donequickly andeasily,without the bother oI trying to comeup with a meaningful,uniquelabel. The third methodis to usea uniquelabel and goto it. This is generallythe prefered methodof most new programmers.The problemcomeswith trying to come up with uniquelabelsfor complexprograms(the point I madepreviously).TheconventionsI tend to usefor labelsare asfollows: r .
.
There can only be one Loop and one Done label,andthey arein the mainlinc. Within subroutines,Itry to keep to one Loop, one Skip,one Done,and oneEnd labelsuffix, with the labelprelix beingthe nameof the subroutine. Labelsshouldbe reasonably descriptive. Singleletterlabelslike a,n, andso on.makea program more difficult to read than if they describetheir purpose.
If you havebeendoing someresearchabout the PIC MCU, you would havediscoveredthat the programmemorypageslzeis 2,04f1 instructions.Jumping betweenpagesrequiresupdatinga registerknown as PCLATH beforeexecutingthe goto instruction.This is not an issuewhenyou areworkingwith the PIC16 F684,which hasa total of 2,048instructions,but is somethingthat you will haveto undentandif you were working with a PIC MCU, which hasmore than 2,048 instructions.
S e c t i o nE i g h t P I C o l l C U A s s e m b l y L a n g u a g e P r o g r a m m i n g
L63
Experiment59-Loading the I-UHEE and Saving
Its Contents
Unlike a highJevellanguagein which data canflow throughanyvariable,all the data in a PIC MCU assemblylanguageprogramwill alwayspassthrough the working register,which is known as WREG. In other microprocessors, this registeris known asthe accumulatorandis the midwaypoint whendata is beingtransferredfrom one locationto another,aswell asone of the sourcepoints and a possibledestination for mathematicaloperations.Despitethe WREG'S responsibility in assembly language programming. whenyou look at it, only threethingscanbe done with it. . -
. . . .
.
'
The first thing that can be donewith the WREG is to load an eight-bitnumericvalue (known asa literal or immediatevalue)into it. This is typicallydone using the movlw valueinstruction,which storesvalue(or the leastsignificanteightbits of the instruction)directly into the WREG (seeFigure8-2).This instructionexecuteswithout affectingany other resourcesin the PIC MCU. Regbtersare lhe namegivento a group (or a bank) of 128addressable bytes,someof which can be usedas variablesin your applicationand othersof which can accessbuilt-in hardwarefunctionsof the PIC MCU. The variablebytesarecalledfle regisrers. andlhe hardwarecontrolfunctionbytesare known asspeclal registerscanbe movedinto function registers.These the WREG usingthe "movf Register,d" instruction (seeFigure8-3). The leastsevenbits of the mod instructionare the addressof the resisterin the bank that is to be
accessed.The valuein this registeris passedthrougha zerocheckmoduleandthen either passedback to the registeror storedin the WREG This actionhascaused me in the pastto characterizethe movf instructionas havinga primary responsibilityof testingwhetheror not the valueof a registeris equalto zero and a secondaryresponsibilityof loadingWREG with the contentsof the register. I think of the zero testmodule asa dottedAND bus (seeFigure8-4)with eachbit beinga control input to one of the pull-downtransistorswitches,and the bus output beingthe zero bit (calledsimplyZ) of the STATUS register.If any of the bits are set,the line (and the Z bit in the STATUSregisterafter the instructionexecutes)will be low. In the descriptionof the instruction,I noted that the contentsof a registercouldbe optionallystored into WREG or storedbackinto the register.The determinationof wherethe registercontentsgoesis made by the d or destination-bitparameterof the movf instruction.Thedestination-bitparameteris usedby all instructionsthat movethe contentsof a register throughWREG; it will becomeclearerasyou work throughthe section. In somereferences, you will seethat if d is 1,the destinationis the register,and if d is 0, the destination is WREG. In all of my code,and I adamantlysuggest that you follow this convention,the letter/is usedas the registerdestinationand lr is usedasthe WREG destination.In all of the Microchip files includedhere,f is equatedto 1,and w is equatedto 0, so the valuesare the same.But by usingthe letter codes,you shouldsimplify the effort in rememberingwhich numberis used to initiate which action.
"14-Bit lnstruction
Specified
Figure 8-2
Immecl.iate load (movlw) instruction
164
l,A3 PICo llCUExoeninents for
Figure 8-3
Dtrect load (movf) instruction
the EviI
6enius
titl€ Saving
oao Bit7l
Bito ] Figure B-q
DottedAND BusOuiput "1"if all lnputs=: 0
Zero testmodule
,,asmwREG -
IJoatlilg
anal
$REG
This progran dlenonstrates ',ckwnr 'movfn aaal n$ovwf" o9eration WREG to
inEbruction alal bow they ale useal crith move alata withia bhe PIc !,lcu.
Eardlrdare Notes: PIC15F584 runnins
at
{ MHz in
simulato!
Myke Prealko 04.11.17
The final instruction,movwf Register,savesthe contentsof WREG into a register(seeFigure8-5).While the movlw usesliteral addressingto storea specific valuein WREG, the movf and"movwf" usedirect addressingto transferthe contentsof a registerto or from WREG. asmWREGasmdemonstrates the operationof the threeinstructionsdiscussed in this experimentalong with the clrw instruction.Theclrw instructionperforms the sameoperationasthe movlw 0 instructionbut also setsthe zero flag (Z) of the STATUSregister:
LIST R=DEC rNcr,uDE "p15f 684. inc n
PAGE org noD novlw
0
f23
cLrw
t
R6quireiI
i
Load
for
MPLAA 1CD2
WRSG nrith
$REG rrith
Clear/I,oaal
novlw
55
rnovlw
0x55
novLw
b'00110111'
novlw
rU'
FSR
cLrw novf
FSR,
f,
movf,
FSR,
W
t iteral 0
Loaal WREG ldith Decinal IJi.t6ra1 I-oad WREGnitsh Eex I,iteral, Binary loaal WREG lrith !iteral IJoaal WREG wi.th ASCII chalactse! stor€
WREC ilr
clear
WBEG
a Registe!
: _'
set zero Elag Accoraling co cont€nts of Regiater Iroatl VIREG with Register
.:' goEo
FiqureB-5
Directsave
Fini€hed, Okay
Everythins
enal
E x per im ent5U -D e fi n i n gVa ri a b l e s
One of the mostdifficult conceptsfor programmersto understandwhenthey are programmingthe PIC microcontrollerin assemblylanguageis that variables
are not declared.To me.the lerm variabledeclaration meansthat memoryis set asidefor the variablesused in the applicationand is kept separatefrom the application'scode.In additionto specifyingthe memory usedby the variables,often the applicationhex file will includeinitial valuesthat are storedin the variables whenthe hex file is loaded.Whenyou are specifying addresses for variablesin the PIC MCU. that'sall you're doing;you are not settingasidememory,and thereis no ability to initializethe variablesfor specific purposes. In this experiment,Iwill presentyou with a way to specifyvariableaddresses in the PIC MCU that
S e c t i o nE i g h t P I C @l l C U A s s e m b l y L a n g u a g e P r o g r a n m i n g
165
is both efficientand resistantto userdeclaration EITOIS.
The idea that PIC MCU assemblylanguagevariablesare not declaredasin a traditionalsystem,with memoryset asidefor the variablesin the hex file,may be confusing.You might ffy ro specifythe variable addresses manuallyusingan equate(equ) directive. The equdirectiveis usedto associatea labelwith a numericvalue,and it could be usedto declarevariablesin the following manner: j.
equ 0x020 l equ 0x021 k equ 0x022 equ 0x024
t t r
Decla!€
8-Bi!
D€clale Declare
16-Bit Counter Eollowing 8-Bit
Labe13 endlc
-
Defining
variables
This coale demonstrat€s how variablea usiflg aleclareal in PIC l,Icu Assenibler "cb1oek" alirective. Hardware Notes: PIC15F584 running
at
4 MEz in
in
PIc
are the
Simulator
Myke Prealko 04.09.04
counter
IIST R-DEC rp16f684. rNctuDE
t
ine"
variables CBLOCK 0x20
i j, k Datastring:s ENDC
8-Bit variabLe Single rwo 8-Bi! variabLes rtrulli-Byte string variable
i r r
Al"lernalive_i i
EQU 0x21 "ALternative_i
",
sane
ailalress
aa rrjn
PAGE
org
movlw
O trin
47
;
Load
33
r
Loadl "j'
with
Literal
value
with
T,iteral
value
) novlw movwf
22 ; Alternative
Ovenr'rite i
"j'
r
Firisheal,
I,oop
goto
Loop
Foreve!
Adalressj Bttesl
r First variable r Seconal. multi-byte , variabLe i Thirat variabLe
In the previousexample,if lStartAddresslwas 0x020.Labell would be associated with the constant value0x021,Label2with 0x022,and Label3,which followsthe 16-bitvariableLabel2,will havethe value 0x024.Thesevaluesare assignedto the labelsat assembly,or build,time without requiringany effort on the part of the programmer-includingif you were to add or deletesomevaluesbetweenbuilds. To demonstratethe cblockdirectiveaswell asthe equ directivemethodsof declaringvariablesin PIC MCU assemblylanguageprograms,I createdasmDeclare.asm. In this program,I havecreatedthreesingle byte vadables(the latter two on the sameline and separatedby a comma)and a multibytevariable.Theequ
t66
"asnDeclare title MCU Assenbler"
Coulltels
The biggestproblemwith this methodshouldbe immediatelyobvious-it's a lot of work! Not only is it work to write out eachvariableand makesureit hasa uniqueaddress, but insertingor deletingvariables requiresupdatingaddresses to make suretherearen't any holes.Another issueis how multibytevariablesare declaredand maintained.In the exampledeclaration of the four variablesabove,it is easyto forget that k is 16 bits and takesup two bytes,and the next variablein sequencemuststart at an addresstwo higherthan the l6-bit variable. In the mid-1990s, when I fint startedprogramming the PIC MCU, this wasthe acceptedmethodof declaring PIC MCU assemblylanguagevariables.It certainly wasn'tperfectand it wasresponsiblefor a lot of difficult-tolocate errors.A few yearsago,Microchipadded the cblock dtectr\e (with the endcdirectiveending)to MPASM assemblerto make it easierto create sequences of numbersfor a seriesof labels.Theformat for the cblockdirectivefor declaringvariablesis: cblock lstart Label1 Label.2 Size in
declared variable is at the same address as one of the cblock-declared variables O and, when written to, will overwrite the cblock-declared variable j.
enal
The body statementsof the programare initialization statementsfor the variables,and the valuesthat get storedin them canbe displayedin the Watchwindow of the simulator.Theseare the samestatements that werepresentedin the previousexperiment,but appliedto variables. you will disWhen you simulateasmDeclare.asm, coverthat the vafiablej is overwrittenwhenAlternative_iis written to.The reasonfor this is simple:Both variablesare at the sameaddressand a wdte to one variablewill affectthe other.Thiswould not be the caseif variablesweretruly declaredin PIC MCU assemblylanguage. An obviousconclusionto this experimentis that you shouldnevermix cblock declaredvariableswith equ declaredvariables.I would go further and saythat variablesshouldbe declared usingcblockonly.
l , e 3 P I C @l ' l ( U E x o e r i m e n t s f o r
the Evil
Genius
Along with declaringvariables,the cblockdirective canbe usedfor declaringdatastructuresand for enumeratinglabelsfor applicationssuchasState Machines.Usingcblockdefinedlabelvaluesin these caseswill allow simplercodingaswell aseliminate
much of the maintenancerequiredof individualequ directivedefinedlabels.The dynamicnatureof the cblockdirective(it is updatedeverybuild cycle)makes it idealfor useanywherethat changingnuneric label valuesis reouired.
61-Bitt-uiselnstructionE Experiment
Bitwisebooleanoperatorsare the mostbasicdata processinginstructionsthat canbe performedin a processor.Theseinstructionscanbe built out of standard gatesquite easilyand do not havethe sameoperational issuesthat are presentin additionand subtracTheseinstructionspedorm the basic tion instructions. Iogicfunctionsover all eightbits of two parameters, onebeingWREG and the other beinga parameter specifiedin the instruction. Two-parameterbitwiseinstruction(i.e.,AND, OR, and XOR) executionfor direct addressing(thosethat end in wf) is shownin Figure8-6.In this case,the contentsof a registerare operatedon with the contentsof WREG usingone of the threeBooleanoperations.The destinationof the resultcanbe either in the WREG or backin the registerusingthe d parameterof the instruction.The ability to return the valueto the regis-
but, asI will showin ter may seemto be unnecessary, handy. it can be extremely the next two sections, The dataflow of bitwiseBooleanoperationsthat canbe performedagainstthe contentsof WREG and a Iiteral value(causingthe instructionsto end in lw) are shownin Figure8-7.Theseinstructionsbehavesimilarly to thosewith a direct addressexceptthat they haveonly one possibledestination,WREG.Inboth cases, if the resultof the operationis zero,then the zero (Z) STATUSbit is set,otherwiseit is reset. bitwiseinstruction, Thereis alsoa single-parameter calledcomf Register,d. This instructioncomplements (i.e.,doesnot negate)eachbit of the specifiedregister andreturnsthe resultin eitherWREG or the source register.If you wantedto complementthe contentsof the WREG, you could usethe followingliteral XOR instruction: xorlw
oxEE
t
complement
each
bit
of
WREG
the operdemonstrates In this case,asmBitwise.asm lanMCU assembly ation of the differentbitwisePIC guageinstructions.
14-Bitlnstruction
Figure 8-6
Two-parameter direcr
Figure B-7
literal Two-parameter
S e c t i o nE i g h t P I C @1 1 C UA s s e n b l y L a n g u a g e P r o g r a m m i n g
167
'asmBitrdise litle Inatructi.ons"
u)
-
Demonstrale
Bitwise
r.f
r t t i
^ or.FF i=t = 0x3B ^ oxFr = o:rc{ 'IREG ltnchangeal
r t t , t t t t t
=wREc ^ i = oxt.B ^ oxc4 = 0t<3F WREG= WREG ^ i = oxFE ^ 0x3F = 0xc4 i =WREG ^ = 0 x 3 B ' 0xc4 = O*FB
r
Finished,
This Dlogram al€nonBtrat€s the oD€ratioD of !b€ Bitwia€ instructions on $rREc anal a Fi16 Regisler incluiling !h€ oDeration of the zeto Status F1ag.
xorwf
t.f
Ilaralware No!€a: PIC15F6g4 ru$ing
xorwf
i,w
,ror$tf
i,t
goto
S
al
4 MHz ia
Simrlator
Myk€ Pleilho 04. LL.!7
L.
n .-l .lJ
U |ill
r.l {J
gt
k
l-t
s
IJIST R=DEC INCIITDE n915f 58{.incrl CBI.OCK 0x20
Declaration
PAGE org nop
0
novlw mor rf movllc movDrf
0x3F i 0xF3 j
movhr analwf
L23 i, w
rlovlw anahflf
L23 i, t
.rl
'd j,w
1d
4
r
Requiredl
r
hltialize
fo!
UPIllB
Ev€rything
Okay
enal
ENDC
(.,
.r{
VallaltL€
t
i
ICD2
Varl.abLes
r , i r t
Initialize WREG = = = Z=0,
, r i t i
Initialize WREG i = = W R E G & i = 0t<7B & 0x0F = 0x3B Z = O, WREG Uachangeal
r t t t
wREc=wREclj = 0x7B + 0r.E3 = oxFB j lrnchaDgeal Z=O,
WREG WREG & i 0!r7B & 0:.3F 0x3B i Unchang€al
Beforegoingon,I would like you to considerthe threeXORS at the end of the program.I didn't explicitly summarizewhat they are doing. However, if you were to look through them, you would discoverthat they not only demonstratethe operation of the xorff statementwith differentoptionqthey alsoare a code snippet that you should keep handy.The following three instructions swap the contents of WREG with the contentsof a register,and they are much more efficient than coming up with the equivalent assemblylanguagestatementsfor the traditionalregisterswap: //
EltaD
"i 'r aud
i = i; J = i;
Whenyou perform traditionalhighlevel programming,therearen't a lot of opportunitiesto usethe bitwise instructions,but in assemblylanguageprogramming,they are critical to your ability to create very efficient applications.
!!
Experiment 5a-Fddition Instrutrtions
{\
back into either the WREG or a sourcefile register. What makes this instruction different from the bitwise instructionsis the productionof two carryvaluesthat can be usedastest valuesfor controllins the execution path of the program.
t'l
du "p4 t . fit !.,.{ f,.d f -'l
The PIC microcontroller's addition instructions are very similarto the bitwiseinstructionsof the previous experiment:Data is set up in the WREG it is arithmeticallycombinedin someway,and the resultis put
168
T\e carry and digil carry STATUS register bits are just as normallyreferredto asC and DC, respectively, the zero bit is referred to as Z. Theseabbreviationsare usedin PIC MCU assemblylanguageprogramming to indicatethesebits and shouldneverbe usedfor variableor labelnames After passingthe s]omto the Operation Result,the carrybit of the additionoperationis savedasbit 0 of
l , e 3 p I C o l l C L JE x p e n i m e n t s f o n t h e E v i l
6enius
the STATUS register and is usedto indicate if the resultof the additionoperationis greaterthan 0x0FR This bit is often usedasan indicatorfor 16-bit(and greater)operationsto indicatethe resultsthat addition to lower byteshason the higherbytes. The digit carry bit (bit 1 of the STATUS register) performs a similar operation but for the least significantfour bits of the result.Digit carry is not the same asbit 4 of the sum.Thedigit carry is the carryresultof bit 3 of the sum;it is difficult to illustratethis in diagrams(seeFigure8-8),but its operationcan be illustrated clearlyusinga testprogramlike asmAdd.asm. When you simulateasmAdd.asm, I suggestthat you displaythe contentsof the STATUSregister(and WREG) in a Watchwindow.The contentsof the STATUS registershouldalwaysbe displayedasbinary rather than the defaulthex.I realizethat the stateof the carry,digit carry,and zero bits, along with the contentsof WREG are displayedat the bottom of the MPLAB IDE desktop,but still I find it usefulto have them in the sameWatchwindow asthe other registers andvariablesusedin the application. "aamAaLl tille Ins!ruc!Lons" Thia Drogram the aatalition oDeration of Statsua Elags.
Adtlitsion
alenonstlates tshe operaEion of iEst'rucliona inclualing the tlre Zero, Carry arral Digit Calry
Haralware Notea: PIC15F58{ running
al
4 !,ItIz in
Slmulalor
Mtzke Plealko 04.09 .27 LIST R=DEC INCLI'DE'rD16f 684. inctr CBLOCK 0x20
,
Variabl€
Declaralion
ENDC PACiE or9
fiovLw {rovwf
0
0x0F
r
Requireal
r
Iniliallze
for
MPLAB ICD2
variabLes
0xF0
clrvt
i ,
cLear WREG z = L
i , ; i
WREG = = = Z = O,
WREG + i 0 + 0r<0F 0x0F C = 0, DC =
t i i ,
VIREG = = = z = O,
WREG + i 0x0F + 0t0E 0x1E C = 0, Dc =
t
rlt
ICREG = WREG
0 x L E + 0x0F O*2D
9"i:
t?q w
t i t t
WREG=WA.EG+k = 0tr2D + 0xF0 = 0x( 1) 1D = 0x1D
, i r , ,
WREG= = = = Z = !,
;
Eini6heat,
f l
&:i
goto
$
I{BEG + 0xE3 0x1D + 0xE3 0 x ( 1 )0 0 0x00 C = 1, DC = 1 Everyuhing
tr-h Okay
entl
f\3
The first addition operation (zero plus 0x0F) has a nonzeroresult,and the threeSTATUSflagsindicating the resultof an additioninstructionare all reset.I then add 0x0F to the value in WREG again and, as expected,the resultis 0x1E.Thissecondadditionhasa lower four-bit sum and a (digit) carry to the next larger four bits,so the DC STATUSbit is set.I shouldpoint out that coincidentallybit 4 of the sumis alsoset. To prove that bit 4 being set is a coincidence,I repeatedthe additionof 0x00Fto 0x1Ein the WREG In this case,the sumis 0x2D,but you will seethat the digit carryflag is still set eventhoughbit 4 of the sumis reset.The digit carry can be confounding and difficult to predictits value.For your initial PIC MCU assembly programming,I suggestthat you ignoreit andjust focus on the carry and zero STATUS register bits for retuming addition instruction information. The final addition operations causethe sum in WREG to be greater than OXFRcausingthe carry flag to be set.Note that up to theseinstructions,the carry flag is reset becausethe results are alwayslessthan 0xFEThe first additionproducesa result of 0x11D,and the mostsignificantbit is usedasthe carry This canbe donebecause, unlike the digit carry,no other bits are part of the final sum. The lastadditionvaluewaschosento producea zero result,but whenyou simulatethe program,you will notice that all three STATUS register bits will be set.Not only is the carrybit setbecausethe sumis greaterthan 0x0100,but the zero bit is set (becausethe savedeightbits are all reset)azd the digit carry bit is set (becausethe sumof the leastsignificantfour bits are greaterthan Ox00F).This may not seemimportant for addition,but this resultwill be very importantin caffyingout subtraction,asI will discussin the next exDerrment.
5 e c t i o nE i g h t P I C @n C U A s s e m b l y L a n g u a g e P r o g r a m m i ng
L69
: *
b,
&r" 9.3 '
rr h
6*d trn r*
q.{ tr!
q rA
Experiment63-HddLibs: Strange5imulator FleEults WREG = I'|REG + i
140 + 140 2ao b , ( 1 )0 0 0 1 1 0 0 0 , b,000L1000, 0x18 24
Before goingon, I want to showyou how the simulator will seeminglyfail and producean incorrectresultfor an arithmeticoperation.Thecodefor this experiment wastakenfrom a high schoolquiz.Thebasecodewas givenin the test,and the studentswereaskedto verify what it did usingthe MPLAB IDE simulator.When the studentsenteredthe codethe simulatedresultwas totally unexpected. I would like to askyou to load the followingcode, asmAdd2.asm.into the MPLAB IDE and enablethe simulator. titl"e
"a€'lAaLl
2 -
Simulatot
This program Shows how the Sinnrfator apparently alispLay t'he wrong re€u1t atldition o!'eration. llarflware Notes: PIC16F584 running
can to an
at
4 MEz in
Simulator
r
variable
DecLaratiolr
r
Requir€al
for
r
Inilial.ize
Myke Pletlko 04.1,2.09 LIST R=DEC INCLUDE "p16f,584.i!rc" CBLOCK 0x20 ENDC PAGE org nop movlw movwf,
1zo
0
140 i
ltPLAr
Variabl€
ICD2
After buildingthe code,single-stepthroughthe codeto the addwfinstruction.After executingit, the simulatorstopswith a valueof 0xB5 in WREG (my result),but asshownin the code'scomments,the expectedresultsare 0x018or 24 (decimal). What happened?The answeris no instructionis givenafter the addwfwherethe simulatorcan stopat, and thereforeit executesa numberof instructionsin the simulatedchip programmemorybeforestopping. You canbetter seewhat is happeningby clickingon "View" and then "Program on Memory."The instructionsfor the start of the applicationmatchthe asmAdd 2.asmcode,but the instructionsafterwardare all "addlw 0xf!" and so it appearsthat the simulalorhas executedfor 256(0x100)instructionsafter executing the "addwf I, w" instructionbeforestopping. This is actuallya good exampleof how smallprogramswork in a PIC MCU Even thoughthey take up a smallfractionof the programmemoryavailablein the chip,the programmemoryis still presentand they executeasaddlw0xFFinstructions. To avoidthis issue,Itend to usean endlessloop (goto $) althoughmany otherslike to usea nop.Any instructionwill do.I like the endlessloop asit will keepthe simulatorfrom executingadditionalinstructions,which canchangethe contentsof registersor bit flags.These instructionswill give the simulatoran instructionto stopat rather than havingthe ambiguous situationof this application. I realizethat I haveindicatedthe needfor the instructionwhich endsthe application,but the kids in the high schoolcourseweretold this aswell.It's easy to forget unlessyou haveto work throughit and try to understandwhat is happening,asI havein this experiment.
l , E 3 P I C o l l C l JE x p e r i m e n t s f o r
the Evi I
6enius
ff
Experiment6l-l-5ubtracti on InstructionE A _ B = A +
X
U
( - B )
tv but when working with digital logic, this is not quite true. To negate a binary value (convert it to its complement in base2), you complementthe bits and increment the result:
._{
- g = ( B ^ o x F F ) + 1
Subtractionin PIC MCU assemblylanguagewill probably be the most consistentlydifficult thing you will have to work with. This is due to the nonintuitive way the instructions execute.You'll find that the data is handled backwardsand the carry and digit carry flags will not work asyou would expect.Many PIC MCU assemblerprogrammerstry to avoid working with the subtractinstructionsall together,insteadcreatingsimilar capabilitieswith other instructionsIn this experiment,I will showyou how the PIC MCU subtraction instructionscanbe usedin differentsituations. The first point to rememberabout the subtract instructions is that they alwaysadd the negative contentsof WREG to the instruction'sparameter.The actual subtractingcircuitry is really a modification to the addition circuitry with either the negative value of WREG or the unchangedvalueaddedto the second parameter(seeFigure8-8). In gradeschool,you wereprobablytold that subtractionwasthe sameasaddingthe negative,that is:
When this 2's complementvalueis addedto the second parameter,the eight-bit result is the sameasyou would expectfor subtraction (again remembering that it is WREG taken awayftom the parameter).But the carry (C) and digit carry (DC) STAIUS flags are not what you might expect.To simplify, don't worry about DC, but focus on predicting the state of the zero and carryflagsbasedon differentvalues(seeTable8-1). The carry flag after subtraction is often referred to as the negativeborrow flag,because, whenit is reset,the subtractionresultis negativeand a one shouldbe borrowedfrom the next highestbyte. Further confusingthe operationof subtractionis the apparent reversal of the instruction from what seemsintuitive. In other processorassemblylanguages, whenyou seesomeinstructionslike the following: nov Eub
Acc, Velue]. Loaal Accunulator r Acc, va1u62 Subtract Value2 ;
with
the
Subtractenal
*;l
i ! {*
ry t*
n
t*"
o
f,rom Va].uel
Ft
you expectit to executelike this: Acc = Valuel-Value2;
Direct Valle
e :
H
But, in PIC MCU assemblylanguage, the analogous instructions:
:
l
I,\
Lite€l Value
movf,
va1ue1, w loail Accrurulalor lritb lhe Subtractor i subwf value2, !t Perform the Sublraclion O9elalion i
Add/Sub
Table8-1. Zerc and EarrusTFTU5Bits Ffte. subtraction
l{
t , ,r+
OBeration
WBEG Parameter Flesullsof Parcmeter+ |-WEEGI
Figure B-B
Subtraction
W R E G : 0 x F F ( - 1 ) , C= 0 , 2 = 0
0x02
0x01
0x02
0x02
WREG=0,C-1,2-1
0x02
0x03
WREG:0x01,C:1,2:0
S e c t i o nE i g h t P I C o t l C U A s s e m b1 y L a n g u a g e P n o g n a m m i n S
H V'
L77-
producethe actualoperation:
cBIrocK
t variable
0x20
DoclaratLon
ElIDC
WREG=Value2-Value1; PAGE
{0 L; L' .Fl
v rl
This can be both confusing and frustrating when you are new to PIC MCU assemblylanguageprogramming.There are a number of things that you can do to make the operations simpler.The first is to add the negative.Instead of trying to figure out how to use the sublw (subtract WREG from literal), you can add the negative.That is: -47
aalill$
H
t)
i
wREc = I|REG -
0 nop
movwf novf, subrf
t Requirotl 0x01 i 0x02 J i, j,
\r rd
4?
Another method is to only use the subtraction instruction the sameway,all the time. You could start with the basicsubtractionstatement: novf aulntrf
A = l l - c
j , w i,w
H and you can convert it to PIC MCU assemblylanguageusingthe instructionsequence:
o .F{
P
d H i l
*{
3
?n I
t
s
c, w B, w a
novf sulrff
In this sequence,if B or C is a literal value,then insert sublw and movlw in their placeq respectively.If B is the sameasA, the last insftuction (mov*f) could be eliminatedand the subwfinstructionchangedto subwf B, f. Finally,the methodI recommendis to add the subtract instructions to your application asyou think they will work, but write out what you expectthe operations to do asI havein asmsubtract.asm. Then,when you are simulating the application,you can compare the actualresults(both in WREG or the file register and in the STATUS register) to the expectedvalues you marked in the application and on which you have basedthe application'soperation. tra$rlsubtracl title InBtructsi.onEn
$ 6 .rl l{
ql P{
X 14
hitlalize
i,w i, !r
-
ale th€
a bi! rBore atlalition
j - i r Stsarts with rWREC=j-l{REc = O,iO2 + (WREG ^ orcF) , = 0x02 + (0x01 ^ oxF!') r = O'tO2 + oxEE+ 1 t = 0x02 + oxFF t = 0x(1) 01 , t WREG = 0x01, C = 1, DC = L,
!&rke P!€flko 0{.11.19 LIST R=DEC INCIjIDE trD16f 58{. inc "
Lt2
at
{
+ 1 + 1
Z = O
r N € x t i - j tVlRECl=i-WREG = 0x01 + (wREc ^ o:
tNo!r, i -i TVIREO=i-WREG = 0:101 + (WREG ^ oxFF) + 1 = 0x01 + (0x01 ^ orlFF) + 1 = 0!101 + o:.FE + 1
ovlw aub1rd
0x01 0x10
6ub1tt
0x10 0x0
r WREGE 0x10 - 0x01 r WREG- 0x10 - $REe = 0x10 + (WREG^ onFF) + 1 r = 0x10 + (0x01 ^ oxFa) + 1 ; = 0x10 + oraFE + 1 t = 0x10 + otcF t = 0x(1) 0F ; ; WBEG= 0x0F, C = 1, DC = O, z - O , WREG = 0 x 0 1 r I{REG = 0x01 0x01 0x01 0x01 0x01 0xF1
+ + + +
0x10 WREG (WREG ^ oxFF) + 1 (0x10 ^ oxFF) +1 oxEF+ 1 0xF0
waEC = 0:€1, C = 0, DC = L, z = 0 goto
$
;
AlniEhett,
Ev6rylhing
Okay
€ntl
RBIEMBER, tshe Negatlv€ Contetts of, WREG are Add€il lo thg instsruetsion algl'ment, Halt\rare Notses: PIC15F664 runninq
ICD2
= 0x01 + 0:{rT , = 0x(1) 00 r t WREG= 0x00, C - 1, DC = a, Z = 0
Subtract
fhe Subtract Instsructions codE)lex in operalion tha! inalructions:
UPLAI
varj.6b1€s
, WREG= otFF. trovf aubwf movwf
rn
11
t
for
MHz itt
SlfiuLator
Hopefully,I have not made the two subtract instructions scarier than they actually are.You might want to createan applicationlike asmSubtract.asm and put in different values.But the best way to learn the subtract instructions is to use them in your own application and confirm they are working by using the simulator. By doing this you will be farniliarizing yourself with the subtraction instructions work and becoming more proficient with the MPLAB IDE simulator.
l , P 3 P I C @l l C U E x p e r i m e n t s f o n t h e E v i l
Genius
Experiment 65-Bank Fddressing Prekir* 1
So far, you havebeenintroducedto how programsare structured,the MicrochipPIC MCU includefile,execution changes(gotos),register/variable declaration, and dataprocessing. By all rights,you shouldbe ready to start creatingcodefor actualhardwareapplications. Unfortunately,the next topicsdon't build on each other aseasilyasthe previousonesdid, and to be able to codesoftwareto run in a physicalchip you needthe informationin all the topics.To try and breakthis deadlock,I want to skip to what is normallyone of the lasttopics,the PIC microcontrollerregisterbanks,and showyou hoq with the instructionsand information you havebeengivenso far, you cancreateyour own applications. Earlier in the section.Isaidthat there are sevenbits set asidein eachinstructionto accesses a register.They are the register'saddress.This meansthat eachinstruction canaccessup to 128differentbyte-sizeregisters. This isn't a bad amountof memory but the PIC MCU designerswantedto be able to providemore,so they d.ecrded Io bank the registersand provideup to four banksin the midrangePIC MCUs.Eachbank consists of a numberof commonand uniquespecialfunction registers(processorand hardwarecontrol and interfaceregisters)and generalpurpose,or file,registers. Theseregistersmay or may not be shadowedbetween the PIC MCU's registerbanks,and therewill always be the needto accessregistersin more than one bank in your application.Theconceptof registerbankscan be difficult to understand,but you mustif you are to createPIC MCU applications. The mostvivid exampleI cangive of the PIC MCU's banksis a spicerack;whenI wasa kid, a friend'smom had a spicerack her husbandhad made her.Thisrack stoodon her kitchencounterand was ableto hold manyspicebottles.It wasbuilt to hold the spiceson eithersideand wasmountedon a small turntable.When a particularspicewasrequired,the rack would be tumed to exposethe sidethat held that bottle of spice.Thisarangementseemedto work well,
althoughthe rack had to be turned repeatedlyduring the preparationof a mealbecausetherewasno way to prearrangethe bottlesso that a singledishwould use spicesfrom only one sideof the rack. The banksol registersin the PIC MCU are very similarin conceptto this spicerack (seeFigure8-9). The differentregistersare arrangedin sucha way asto providemostof the usefulfunctionson one bank (one sideof the spicerack),but you may haveto changethe sidethat that is exposedduringan application.The control for which sideis exposed(or executefrom) is the RPObit (bit 5) of the STATUSregister.When this bit is reset,bank 0 is accessible;when this bank is set, bank 1 is accessible. As can be seenin Figure8-9,STATUSand a number of other registerscan be accessed from eitherbank (like therewasa hole cut in the spicerack so a bottle couldbe reachedfrom either side).For transferring data betweenthe two banks,the file registersin the addressrangeof 0x70to 0x7Fare commonbetween the two banks.Along with thesecorzrnon, or shadowed,registers, a numberof other registersexist (both specialfunctionandfile registers)that are uniqueto eachbank.For most of your initial applications, you will be ableto run almostexclusivelyout of bank 0. The only registersyou will haveto accessare the TRIS registersand the ANSEL registers. Changingthe currentbank canbe accomplished by usingthe followingcode: novf iontrf movwf
STATUS, w 1 << 5 r sTATus
Set
RPo - Change
to
Bank
1
RPO=0 RP1
ShadedRegisters AreShared BetweenBanks Figure8-S
PIC16F684banks
S e c t i o nE i g h t P I C @t l C U A s s e m b l y L a n g u a g e P r o g r a m m i n g
L73
anal novf, analwf firovwf
STATUS, w oxrF ^ (1 << 5)
r ,
R€set RPo - Change to Bank 0
sTArus
T\e leJtshijl operaror(<<) in the statements above,shifts1 to the left by the specifiednumberof bits.I usethis methodof specifyingbit constantsrather than usingdecimal,hex,or binary constantsbecauseit is very difficult to screwup.With constantvalues,you mustalwaysrememberwhich digit,column,or value eachbit valuehas.By usingthe left shift operator, rememberingthesevaluesis not required.When setting or resettingindividualbits,I recommendusingthis format for constantvalues,becauseit avoidsthe need to verity the valueusedfor the specificbit. When you are changingSTATUSregisterbits,you cannottake advantageof the ability of the andwf and iorwf instructionsto changeall the bits of the STATUS registerusingcodesuchasthefollowing: movlw iorwf
1 << 5 STATUS.
; f
Set
RPo -
Change
to
Bank
TRISA.
titLe
,,asnFlash.Naala
-
This Plogram FlaEhe6 betvreen AA4 (Positiv€) appro*imatsely 2x De! any aalvanceal control Ilaralwale Not€s: PIC15F684 running clock Intelna1 Reset is B,A4 - LED Posicive BjAs - LED Negative
at
prc15F584
Elashing
rJEDn
tshe PICKit D0 I,ED anal R.A5 (negative) secondt without u€ing instructions.
4 MHz Using
at
hterlral
lhe
usedl
llyke Predko 0{.11.19 LIST R=DEC INCIUDE trp15f584.inc" FCMEN OFF & _IESO_OFF & _BOD_OF!' & -CONFIG ,CPD OFF & CP OEE & _!{CIJRE_ON & _PWRTE_ON & WDT Or'F & IN:IOSCIO
w
"Message[302] you would get the assemblermessage C: {Filename/LineNumber}:Registerin operandnot in bank 0.Ensurethat bankbits are correct."because the addressspecifiedin the PIC MCU includefile givesTRISA the address0x85.Thenumber0x85is 133 decimaland useseightbits,not the seventhat is requiredfor addressingthe contentsof the bank. The simplesolutionto this problemwould be to changethe TRISA definition to 0x05,which seems correctbecausethe TRISA registeris at address0x05 in bank 1.But I am goingto suggestthat the label is Ieft asis and havethe constantvalueXORed with 0x80,which will resetbit 7 of the address.The first is the indexregisterusesit to differentiatebetweenregis-
Llq
With the informationyou now have,you cancreate a completePIC MCU applicationand to demonstrate this.I createdasmFlashNada.asm, which will flash "D0" in a PICKiITM1 starterkit:
1
The STATUSregister'sC, DC, and Z bits are affectedby bitwiseand arithmeticoperations,so the PIC MCU designersdecidedto not allow statements that canchangetheseflagsto alsowrite to the STATUS registersimultaneously. The reasonis simple: After the instruction.it is difficult to definewhich bit is valid.By forcingthe userto readfrom and write to the STATUSregisterexplicitly,thereis no ambiguityin determiningwhich valuefor which bit is to be usedby the applicationcode. After changingto bank 1,if you were to accessregistersin that bank directlyasyou would in bank 0, say: movf
tersin bank 0 and bank 1 (it is an eight-bitvalueand can accesseachbyte of the two 128-bytebanks).This canbe usedin your applicationsto effectivelyoptimize somecodefunctionsaswell asto provide arraysin both banksthat canbe accessed easily.Thesecondreasonis that XORing everyeight-bitaddresswhile executingin bank 1 will serveasa reminderto you to makesurethe correctbank is executing.If the message comesup and you are in bank 0, then you shouldlook over your codeand add the corect bank switchcommands.Similarly,if you are accessing a bank 0 register while in bank 1,by XORing the addresswith 0x80,you will get a warningmessagestatingthat bit 7 is set (tellingyou that you are accessing a bank 0 register while executingin bank 1).
Variables CBITOCK 0r.2 0 Dlay:2 EIIDC ,
r
PAGE Mainline org
0
no9
r For
c]rf,
PORTA
movnf novf ior10 nov$rf clrf
CMCONo STATUS, w 1 << 5 STATUS ANSEL ^ 0x80
r Initsialize r Tuln
l,e3 PIColl(U Exoeriments fon the EviI
ICD Debug
off
I/O
Bits
to
Coq)araCora
(Bit 5) r s€t the RPo Bit in Page 1 r to Execut€ r Al1
Bits
are
6enius
Disital
ttlovlw Output s movlrf novf anallw novwf
b'001-111'
RA4/RAs
TRISA ^ 0x80 STATUS, vt oxFF ^ (1 << STATUS
Clear
IJooP: clrf clrf Dlayloop: movld
Dlay Dlay 1
Dlay, f nt sTArus, | << 2 PCL, f
goto nop
DlayIJooD
nop noD novlw Bubrdf movf analLv aatallrf goto trop
RPo
Decrenent IJoop
the
Inside
Zelo Elag Set? check Bit 2 AaLl to the Program Counte! Zero, loop Arounfl space change in Address due Zero Flag Being Set
1 Dlay + 1, f sTATUg. w ! << 2 PCIJ, f DlaylJoolt
Decremenl loop
the
Check
Zero
for
Oulgiale
r Space change in aaldress i dlu€ i Z e r o Flag Being Set
nop nop movlw xorwf
DiqitaL
Return llere aft'el. D0 Toggle sigh 8 Bits for Delay Irow 8 Bits for DeLay
+ 1
subvrf movf andlnr adarlrf
are
L << 4 PoRTA, f
Tossle
i
RA4 (D0)
Repea!
€nd
Thereare really no new instructionsin this application, at leastnone that you haven'tbeenshownprevi-
ously.Thereis howeverone pafi of the applicationthat will requirea bit of instruction.This is the ideaof conditionaljumps.No if, for, or while statementsexistin PIC MCU assemblylanguage, and so,to implement jumps that are conditionalto the statusof the previous instruction,I take advantageof one of the mostwonderful featuresof the PIC MCU, its ability to access any registerdirectlyin the applicationcode.Toimplement the conditionaljump,I add the STATUSregister'szero bit (bit 2) to the lower four bits of the programcounter(the PCL register).The codeworks asfollows: = Program Program Counter ( S T A T U S& ( 1 < < 2 ) )
Counter
+ 1 +
If the zero flag is reset(the previousinstructiondid not resultin a zero),this codewill simplycontinueon at the next instruction.If the zero flag is set,then the programcounterwill be loadedwith the cuffent instructionplus four (becausebit 2 hasa constant valueof 4). I addedthe three nops,or no-operation, instructionsto spaceout the codeand make sureexecution,when the zero flag of the STATUSregisteris set,takesplaceat the correctaddress. In the following experiments,Iwill showhow conditionalexecutionis implementedin a more conventionalmanner. Tiicks like the conditionaljump usingdata movement and arithmeticoperatorsare one of the reasons why I really like working with the PIC MCU The PIC MCU, more than any other smallprocessorarchitecture that I know hasbeendesignedwith the flexibility requiredto perfom someamazingtricks that will help makeyour applicationsmore efficientand help you to think throughproblemsin differentways.
Experiment 56-Bit InEtructions
In the previousexperiment,I discussed the conceptof banksand the ability of the assemblylanguageprogramsto accessany registerdirectly.I alsoshowed
how bankswerechangedand how bank 1 registers (including,mostimportantly,the TRIS registers)were addressed in an instructionso no messagewasproducedby the assembler. Finally,the operationand accessof the STATUSregisterwaspresented,and then a methodof changingthe programcounterconditionallywaspresented.In short,I dumpeda lot of new informationon you. The bit set (bsf) and bit reset(bcf) instructionspresentedin this experimentare somewhatlessdemanding but will be usedasmuch in your assembly
S e c t i o nE i g h t P I C @l l C l J A s s e m b l y L a n g u a g e P r o g r a m m i n g
125
languageprogramming.Thesetwo instructions will allow you to changethe stateof a register'sbit in one instruction,without the needfor ANDing or ORing the contentsof the register.bsf and bcf are incredibly useful instructions and will reduce the sizeof your applicationcodeaswell asmake it easierto read. In the previousexperiment,when I discussed how to set andresetthe RPObit of the STATUSregister,Iwas also describinghow the bsf and bcf instructions worked.Here are the bsf and bcf instructions: ,
bsf R€giater, Ail Oporatlo! trovf Regisl€r, nr iorwf 1 << Bit r movlrf Regist€r
rl[cLIrDE
"D15f 584. incn
_coNFIG _FC!{EN_OFF & _IESO_OFF & _BOD_OFF & CPD OlF & _CP_OEF & _!{CLRE_ON & _PWRTE_ON & ICDT_OFF & _IMIOSCIO varLableE CBLOCK 0x20 DLay:2 ENDC t
,
PAGE Mainline
nol) Set
Bit
r For
ICD D€bug
clrf
PORTA
, InitLallze
novlw novwf bef
7 C!|CONo STATus,
i Turn
cllf bcf
ANSEL ^ 0:100 tRIsA ^ 0x00,
bcf bcf
I'RISa ^ 0x00, STATUS, RPo
r/o
Bitss to
off
s) t.} '-{
+r
U
; ).{
m t4
tsd a !
,-t ar.4 t I
r
bcf Reg1ster, Bit oDelelion movf R€gLBter, w andbtf onEl ^ (1 << Bit) movwf Register
qJ ,;-g
Reset
Bil
This descriptionmay be surprising,but this is exactlyhow they work.They do not, asyou might expect,only setor resetthe singleappropriatebit, but they readin the entireregister,modify the appropriate bit, and retum the value to the register.I am pointing this out becausetherewill be caseswhere.if someof a port register'sbits alreadyhavethe desiredvalueand you want to changejust one bit, the bcf andbsf instructionsmay not be the bestinstructionsfor the job.To get aroundthis case,you shouldneverusebsf or bcf in the port registersor other registersthat canbe written both by softwareand hardware. To demonstratethe operationof the bsf andbcf instructions, I modified asmFlashNada.asm by replacing the instructionsthat couldusebsf and bcf with them.It is not a major changeto the application,but it doesshortenit a bit. Like the previousexperiment, asmFlashBit.asm can be run on a PIC16F684in the PICKit 1 starrerkit. title
r \
r
nasmFtashBit
-
Prc15F684
Flashing
rJED"
Thls Program Flashes the PICKit D0 IJED b€tw€en RA{ (Posilive) a'ral RA5 (a€gative) at approxinatseLy 2x pe! secondl vrith o[ly uaing the Bit Set anal Reael InEtructiona Earalware Notes: PIC15E58{ ruDning clock Intselnal Reset is RAll - IJED Poaitive RA5 - LED Negative
at
{ MHz Uaing
the
Int€rnal
Loop: Toggle cllf c1!f Dlaylroolr: rnovlw Eulfff novf antlLw aitdwf
RPo
6d.N
Ccdq)aratorg
Replaces: novf, SIATUS, !t iorlw 1 << 5 rEv$'f, EIAAITS A1L Bils are Digital Replacea: novllr b'001111' rEvwf TIiISA ^ 0x080 Replacea: novf STA1'I St, rt .tld.I!r o:aFF ^ (1 << 5) rlrovrrf SIATUS
t Retsurn Dlay Dlay
+ 1
H€re
1
; Decr€ql€nl t looD
DLay, f sTAqrs, w L << 2 PCI., f,
goto Dlal'Lop nop Addreaa alu€ nop nop bovlrd 1 IJoop aubrf Dlay + 1. f gTATuS, w novf atrdLw L << 2 aaLlwf PCIJ, f goto DlayrJoop nqD Atlflr€aa tlue nqp nqD
t t r t t t
the
nrovlw xorwf
1 << { PORTA,
Z€lo FIag Set? 2 Check Bit Add to the Prograf,r Counter Zero, Lop Alounal Spac€ Cbarlgo in
r z€ro
FIag
tlr€
; Ch€ck for
zero
i
gpace
i
Z€ro
get
Being
t D€clenent
outsiale
Cbanqe Flag
t Toggl.e
RA{
f i
R€Peat
IJIST R=DEC
f'rt
a{l
l , e 3 P I C @I I C I JE x o e n i m e n t s f o r
D0
Inside
ia
Being
Useal
!61'ke Pr€dlko 0{.11.19
Lt6
afte!
for Delay , Itlgh 8 Blts for D€lay r IJow 8 Bile
IJoop
!.1,3
i t t t , i r , i r r ,
off
the Evil
6enius
(D0)
S€t
tn
Experiment 67-Bit 5kip lnstructions
}d 8-!ij
an tsitLe
raamFlaEh
-
PrC15A584
FLashing
rj
LEDiI
llhia Program la the equivalent !o "cFlaah.c" but !,,!itt€n Ln aaE€dibLy lan$rage, laking aalvanlage of AlIr the featureE of PIC UCU aB8dibly langnrage - bit instsrucEion6, bit skiD in8truclions anal dlecredrent anat Ekip inEtructlona.
When you first look throughthe PIC16F684instruction set,you will find executionaddresschangegoto instructionsaswell assubroutinecall instructions.But nowherewill you find conditionalgotos,branches, or other conditionalexecutionaddresschangeinstructions that you traditionallyfind in microprocessorand microcontrollerarchitectures.What the PIC16F684 (and indeedall PIC MCU family microcontrollers)has insteadis the ability to skip the next instructionbased on whetheror not a registerbit is set or reset.The skippedinstructioncouldbe a goto addressor it could be a singleinstructionthat executeswhenthe condition is false(andis not skippedover).\\ese bit skip instructions,althoughbeing somewhatdifficult to understandand applywhenyou are first learningto programthe PIC MCU, are very powerfulinstructions that providean amazingamountof programmingflexibility and single-instruction capabilitiesrarely matched in other processors. And all this canhappenin less than threeinstructions.In this experimentand the next,I will introduceyou to the bit skip instructions and giveyou somepointerson how to implement them in traditionalprogrammingmethodologies. The two-bit skip instructionsare: btfac
btfas
Regial€r,
RegiE!€r,
Blt
Bit
, r r r r r
Skip the 'Bit" if is Reaet skip the "Bil" if S€t (nln)
No:
In asmFlash.asm, I havechangedthe jumps based on addingthe zero flag of the STATUSregisterto "btfss STATUS.Z" instructions.which will executethe next instruction if the zero flag is reset or the one followingit if the zero flag is set.By doing this,I have reducedthe numberof instructionsto changethe execution from sevento two, basedon the zero flag.
Hartbrale Not€a: PIC16E584 running at 4 MHz UEing clock InternaL Reae! ia Uaefl RAll - IJED Positive aA5 - IJED Negative
i.i ;..3
f? the
InternaL
i"r'i
..-.1
1
llyke Preilko 04.11.17 IJIST R=DEC INCIITDE np15f 5811.incn
l:.i; ,t_'
_coNFIq _FCMEN,OFF & _IESO_OEF & _BOD_OFE & _CPD_OFF & _CP_OTF & IICIJRE ON & PWRTE ON & _!iIDIT_OFF & _INTOSCIO
r
f{*
Valia.bleB cBloCK 0x20
!,t J
D]'all:2 ENDC
i
v'. 1,1,,
PAGE ltainline olg
r:*l:l
0
nop
t For
clrf
mRTA
i
irovllr nov$f bsf cL].f bcf
7 cllcoNo STATUS, RPo ANSEL ^ 0x090 TRI61A ^ 0x090,
i Turn
bcf bcf
TRI61A ^ 0x080, STATUS, RPo
I|oop: cllf cllf DLaYIJooP: goto nqp novlw subwf btfss
Dlay Dlay
r r 4 r r 5 r r r
ICD Debug
Inilialize off
I/O
Blt6
to
CdrEraratols
Execute ou! of Bank 1 AIL Bits a!€ Digital BeDlac€s: movLw b'0011L1' rnovwf TRISA ^ 0x080 Retsurn E €culion to Bard! 0
Here aft€! D0 i R€lurn Toggl€ i High 8 Bl.ts for DeLay i I.ow 8 Bitsa fo! Delay
+ 1
$+1
i Th!€e
1-
, D€clement IJoop
Dlay, f STArqS,
i.'a
z
r Skip t Set
c:zcle
if
D€lay the
Zero
InBial€
FIag
S e c t i o nE i g h t P I C @t l C U A s s e m bI y L a n g u a g e P r o g r a . m m i n S
ia
L77
a4
,:? !1 'r='
ril
ir. F.: t1
i,r
golo
ti
Dlaf&oop
al€cf
Dlay + 1,
btfEE
sTATtts, z DLetiloop
goro
"|J
t l
f.€
t'"t
RA{Reaet baf
-l
RMSet: bcf goEo
{u 14
PORTA, 4 RAISets
btfac golo
r t t r r t t t r t t t i t t i t , i , t t
EIse, IJoop llgain ReDlaces: tnovf S!!AT['S, w andllw L << 2 aaLlwf PCI,, f, golo DIayI/ooE, nop nop nqp Decrqlent th€ Higb Blte ltnttl Il EqualB Zelo Replacea: novlw 1 aublrf Dlay + 1. f gTAT{rg, w novf ! << 2 andll1w addlrf rc!, f DIarrIJooD llotso nop nop noD
r loggLe
, RA{ i6
qr,
lb€n
in two instructionslike this: btfsc
PoRTA,
rl
bef
PoRTA,
{
Skip Ove! if, RA{ Reaet Uake RAI i Else, Reset
t
ia
insteadof thesefour: ltrrn
il
On
PORTA, 4 ]Joop PORTA, 4 I,ooI)
(1 == aA{) RA{ = 0t
if
aiA{
, AA{ iE Off,
!
At the end of the application,when I toggleRA4 to turn the LED on or ofl I test its current state.I do so using the btfsc instruction to illustrate that the btfsc and btfssinstructionscanbe usedon any bit in any registerand not just on the statusbits.This ability to testindividualbits allowsyou to implementcodelike this:
Tura
it
Of,f
i Repeat
novf andlLw
PORTA, L << 4
w
btfEs
STAmS,
z
bcf,
PORTA,
4
t Reaal in PORTA t Tesl RA4 to see if il is high or low therr t If zero aet, nel.t akip
which perform the sametask.But the btfscsolutionis obviouslymore efficient(asit is implementedin fewer instructionsand executesfaster)and is much easierto read.
€nfl
"r.N ,-f"{
Experiment 68-tonditional Execution
l*l g 1
r
also be afraid of the amount of work it will take to implement the function. You will likely be surprisedto discoverthat thereis a four-instructiontemplatethat you can use to implement this function for comparing two eight-bitvalues.
,
The four-instruction template that implements the "if Conditionthen Label" decisionstructureare: t"*
}-r
After working through the previous experiment,you may be wonderinghow to implementthe first decision structure that you were ever introduced to-the if statement.If you haveworked throughthe subtraction instructions and the bit skip instructions experiments, then you probablyrealizethey canbe usedtogetherto implementcodethat will jump on condition.Youmay
novf sulrwf btf,B* goto
w Subtsraclor, rd Subtrac!€ntl, STATUS, F].ag Label
where Table 8-2 lists the different valuesfor the optionalSubtractor,Subtractend,#, andFlag.For the less-thanand greater-thancomparisons,the subtraction is arrangedso the expectedlower valueis the subtractend,and if it is lessthan the subtractor,the carry
:& L&.{ 178
l , a 3 P I C @l l C U E x p e ni me n t s f o n t h e E v i I
6enius
Table 8-2 EifferentValuesfor ComparisonTemplate "lf Statement
Subtractor
SubtBEtend
ifA > B then goto Label
# Flag
s
It
C
ifA >: B then goto Label
c
ifA < B then goto Label
s
C
ifA <: B then goto Label
c
C
C
r4
!&'ke Pledlko 04.O9.2L
, ,
tq h?$
IJIST R=DEC INCIjTDE,tp16f 684. inc.
I lt
CBIJOCK 0x20 D€claration
VariabLe
,
*d
l".
ENI'C PAEE
ifA == B then goto Label ifA !: B then goto Label
s
1g i,{
Z r R€quireil
flag is reset(zero).Thiscodetemplatemay seemlike an advancedusageof the carryflag,but you shouldbe able to figure out operationslike this by reading throughthe PIC16F684datasheetand experimenting with the subx{ instruction.Do your experimenting with differentvaluespreviouslyloadedinto WREG and check the results (both the numeric result of the subtraction operation aswell ashow the STATUS bits are set). When using this template,remember that the WREG's contentsaswell asthe stateof the C. Z. and DC STATUSflagshavebeenchanged. The asmCondition.asm programdemonstrates how thesefour statementsare usedto implementdifferent decisionstructuresusingthe informationin Table8-2 (and embeddedin the sourcecode):
novhr novwf novlw movwf
L2 i 34 j
,
novf subwf btfs6 goto
i, n j, w sTATus, c ErlorlJoop
;
movf subwf btfsc golo
j, w i, !t STATUS, C Errorl,oop
,
if
novf, aubnf blfac
i, w j, w STATttg,
,
Lf
DemonEtrate
rif,
Initialize
MPLAB ICD2
Teats Variable8
if
> j
i
f)0
tshenErrorlooD
I
t i
>= j
!he!
Efror].oop
i
== j
lhea
ElroltooD
Z
H, goto
r Finish€il,
$
Evertrthing
r ComDare Operation i wolk correctly
Okay ilidn'l
rlovf, subwf btfB* gotso
iDstluctsion6
a!e:
Subtractor, w SubElactendl. w sTATus, FLag Labe1
i Ithere the nsublraclortr, andl nFlagn ale DefLneA as:
nsublractenAn,
i r
lleldlware !ilote6: PIC15F584 running
at
4 UEz
Looking at the four-instruction template and the code for this experiment,you can probably understand how to apply the four instructions,but, you may be unsure how to apply it when one of the condition parametersis a constant.In thesecases, the literal instructions movlw and sublw replace movf and subv{, respectively.For example,to implement the highlevel if statement:
in
CI ni H
EI X {D i J
r*tr if
r "if Statdlant" lsulrtractor lS\rbtractenal t --- ---- --- ----- --+-- --- --- --+---rif l|>B then !ab€1 B A rif JD=B rif A
l.J.
s
ElrorlrooD
eaal
The fou!
r-{
,*
goEo
:ghls exD€rim€nt il€tnonEtrates a silE)Le se! of four iastructions that simulates tbe oDeration (conititioD) goEo IJab€Ln high 1evel of a .if langnrage slat€ments.
rf
s'\
Errorloop: "aamconaition litle OgeraEioDs ia Assenbler"
f,or
l * lELas lsl lcl lsl lcl lcl lBl
Sfumrlator
c c c c z z
(1
> 47)
th€n
goto
Lab€l
hr.
o
you would usethe code: llovf Bublw btf6s goto
i, w 47 STA!!US, C label
,
if
i
> 47 thea
Label
Using the four-instruction template for the "if Condition then goto Label" decisionstructure,I suggest
S e c t i o nE i g h t P I C @1 1 C l JA s s e m b t y L a n g u a g e P n o g n a m m i n g
L7g
that you try to come up with ways of implementing highlevel statementssuchas: ((A
if
< B)
&& (A > C))
then
Ranse].ab€I
soto
or:
in PIC MCU assemblylanguage.It is actuallyeasier than you might imagine,althoughbeforeyou start looking at differentprogrammingstructures,you shouldassumethey canall be implementedusingthe if statement(presentedin this experiment)alongwith the goto instruction.
(A < 4?)
wbile
ExFeriment69-decfsz Looplng )
//
lthil.e
.r{
ta t llt
sl/
I I
!. z-i
{T
After the previous experimentsshowing how conditional execution and decision structuresare implemented in the PIC MCU, the simple if, while, and for statementsof C probablysoundgood.Although these statementsare not built into the PIC MCU assembly language, thereis one instructionthat makesrepeated loopingquite a bit easier.Itis the basisofjust about everyPIC MCU assemblylanguageprogramever written. The decfsz(or decrementfile register and skip on zero result)canbe usedto executea loop a setnumber of timesasdemonstratedin this experiment'sprogram. This instruction decrementsa file in a similar manner to the decfinstruction,which decrementsthe contents of the registerby one and storesthe resulteitherback into the file registeror the WREG. But the decfszdoes not changeany of the STATUS register bits. Instead if the resultof the decrementis zero,then the program counteris incrementedbeforethe next instructionis fetched.When this instructionis usedin a loop,it will count down and causeexecutionto fall out of the looo after a setnumberof iterations.
ci3
rraamDecfaz -
litle
,;-j { . F-i
//
at
Finishett,
4 MHz in
Loop
Forev€r
Simulator
Ityke Pr€tlko 04.04.14
iJ.i
b{
(1 == 1),
Hartlware NotseE: PIC15F684 ru ring
u|l
U
elihw
Domonatrate Lnstruction
lhe for
,,Cn Equlvalent
rohile
(i
180
Operation r,ooDing.
of
LooD',
ualecfsz"
the
Coale 3 //
LooD Arountt
// //
Do nothing Declenenl
7x
!= 0)
t = i - 1t
i v t
alecfEz
in the Loop loo9 Counler
LISI R=DEC rNcr,uDE "p15f 684. inc" t
varLablea CBLOCK 0x20
j'
ENDC PAGE olg nop movLw nowrf
0
7 i i loop h€re t Do nothing
nop alecf,az goto goco
i,
f,
7x in
LooD
; i = i - 1 , i f r € s u l t = = 0 , i akip
IJooP
r Finiaheal,
just
loop arounal
enal
Along with the "decfsz"inshuction there is the "incfsz" (incrementfile registerand skip on zero result),but this instructiondoesnot have a "standard" uselike decfsz.As I familiarizeyou with how the PIC MCU works and how you can optimizeyour applicationsin very surprisingways,you will find that both the decfszand incfszinstructionscan be usedto make your applicationsvery efficient.Until then, as you first start working with the PIC MCU and write your first applications,I recommendthat you remember to usedecfszasjust a way to executea loop reDeatedlv
l , e 3 P I C o l ' l C UE x o e n i m e n t s f o r
the Evil
Genius
(-J \.
Experiment 70-5ubroutines
/t\
9ub1: cal.L
Sub2
sub2: call
Sub3
caLt
When you are leamingto programthe PIC MCU in assembler, it may seemlike everyinstructionhassome speciallittle trick to be awareof Fortunately,this is really not the casefor addingsubroutinesto your program.They canbe addedquite easily,and the issues that you haveto be awareof are quite standardfor smallprocessors. The operationand differentaspects of subroutinesare demonstratedin the asmSubr.asm program,which canbe simulatedin MPLAB IDE. 'raar6ubr tltsL€ ODeration,l
-
subroutsine
This program Ehows holr Subloutsines th€ PIC UCU. llaldkoaie Notes: PIC16F68{ rultding
al
{ t{Uz in
work
SimulaEor
PAGE 0 for
MPIAB ICD2 "rer1w"
nlovlw caU
0x55 SubRetLw
t Ca1l
lrcvlw caLl
0x7B StlReturn
i Trt agai4 with i With',raturn"
calL
Subl
r see if you can trest ; Subroutiaea
golo
$
; When &aecutiqr i Loop Eorever
Returzrs
r subloutines Subnetlw: lellw 0nAA
i Retuh
in
SubR€tun:
t Stanalaltl
Subroutine
a value
i DeDlh
Check,
Ca11 Next
F,
Next
L-t
&
r{ D€I)th
Check,
Ca1l
Next
r*"
sub5
t Depth
Check,
Call
N$
*"1
Subs: call
s\rb5
t D€pth
Check,
CaII
Ner€
sub6: call
subT
i D€Irth
Clr€ck,
caU
Ner(!
SubT: cal.L
SubB
i DeDth
Clteck,
CaIl
N€xts
SuIt8: ceLl
Subg
t D€pth
Check,
Ca11 Next
, FiniBhed,
!!
tr?} Fq
IieEurn...
**
eaal
LIST R=DEC INCT,IIDE trDl5f 68{. inc"
t R€qui!6al
Call
in
!lyk6 Pr€atko 0{.11.20
olg aoD
Check,
Sub{
sub{! call
subg:
i Ir€Dth
with
a Subloutsine
Subloutirre
10
Uere,
$REG
ttetuh
Data is t'?ically passedto the subroutineeither by usingglobalvariablesor loadingWREG (and,optionally,FSR) with the input data.Returningdata canbe passedusingeither one of thesetwo methods,by setting STATUSflag (carry,digit carry,or zero)values,or by returninga constantin WREG. The first subroutine in asmSubr.asm returnsdatausingthe retlw,which loadsWREG with a constantvaluebeforeretuming. This methodprobablyseemssomewhatredundantand evenuselesEbut it is criticalto implementingread-only arraysin the PIC MCU. It is alsothe methodusedto return from a subroutinein the low-ransePIC MCUs. so it doesn'thurt to be awareof it. The programcounterstackin the PIC MCU is only eight-valuesdeep.Callingrnorethan eight nestedsubroutines(asI do in this experiment)will resultin the codebecominglost in the subroutinesand continually runningthJougheachof them.You may havediscoveredthis when you simulatedasmsubr.asm, but you will neverapproachthis limit in normal programming.The only time I would expectyou to havesome problemswith losingexecutionreturn for a subroutine is when implementinga recursivesubroutine(or a subroutine that callsitself).
S e c t i o nE i g h t P I C @t l C l JA s s e m b l y L a n g u a g e P n o g r a m m i n g
181
F.
ry in
ExF er im ent 7l- Def i n i n g a n d l mp l e m e n ti n gR rra g s cbLock Array:
0x20
6
enalc
The lastoperationthat you shouldbe awareof is that of initializingarrayelements.Thesimplestway of accomplishing this is to write directly to eachaddress of the variable.For example,if Array wasto havethe first six prime numberqit could be initializedas: The lastmajor assemblylanguageprogrammingconceptto learn is declaringand accessing the datawithin arrays.Like other smallprocessors, the PIC16F684 microcontrollerprocessorprovidesa singleirulexregister (calledFSR in the PIC MCU). which can accessall the registers,both variablememoryand the special functionregisters.The conceptof indexedaddressingis simplyusingan indexregisterto accessarrayelements. The PIC MCU implementsindexedaddressinga bit differentlyfrom other chips,asthe registerspointedto by the indexregisterare accessed via the useof a shadowregistercalledINDF. In practicalterms, indexedaddressingis not any more difficult to implement in the PIC MCU than in other processors:The only issueis rememberingto specifyINDF whenreading from or writing to the registerpointed to by FSR. Therefore,to read a byte from an arrayat position n, you would usethe code: firovf aaLllw
n, w tlfiay
rnovwf tnovf
FSR INDF,
t r i r w r
Get offset of A.fiay Ele!$ent Adal stalling atLlless of the Arlay Stole in FSR (Inalex Regdster) n}.rraylnl n TJoaal WREG with
Similarly, to wdte the contents of WREG into an arrav element n. vou would use the code: movwf
Tenrp
adau.\r
Array
novwf novf, movwf
!'SR Tenp, IIIDF
rd
t r r ; r i t r
Tefiporarily atore the value G€t Of,f€et of, the Al.ray EL€ments Afltl starting address of, the Brray Store A.rlay ELenent Addless Retrieve saveil vaLue Save value.
Declaringarrayvariablesis very easyto do with the CBLOCK directive,asis the ability to specifythe differenceto the next label.For example,for the previous readingand writing examplecode,if the Array variable wassix bytesin sizeand you wantedto make surethe next variabledid not occupythe samespace,you would Dutin the followins statement:
t82
mowlw novwf novlw novwf itrov1w monnf movlw nowrf movlsr rnovwf novl\d novwf
L Array 2 Affay 3 array 5 array 7 array 11 Array
First
i
Element
i
Seconal Ef,ement
i
lhird
El€n€nt
i
Forth
El€ment
i
Fifth
ELem€nt
t
Sixth
E1ement
+ 1 + 2 + 3 + 4 + 5
When doingthis type of initialization(or even alray elements),rememberthat the directlyaccessing first elementhasan offset(and index) of zero,and eachelementhasan inderoffset that is one lessthan the elementnumber. This is really all thereis to working with indexed for byte arrays. addressing asmPCKLED3.asmis a demonstrationapplication in which rhe LEDs on the PICKit 1 starterkit flash from D0 to D7, andit waswdtten usingarraysfor the PORIA andTRISA values. title
"asnPKI.ED
3 -
PIcKit
Running
LED"
This program copi€s th€ op€ration of CPKLED.e and Flashes the 8 LEDg on the PICKit J. PCB in the vaLues fo! the IJEDa Sequence by Storing in Arlays anal lhe TRIS registers Haralware Notes: PIC15F68{ running at 4 MHz Using InternaL cLock circuit Run6 on PrcKit 1 PcB Orisinal
code:
int i, j, k, cha! r,Efrya1uel6]
char
the
TRrsvalue
= (0b010000, 0b100000.
[8]
0b010000, 0b000100, obL00000. 0b000100. 0b000100. 0b000010 )t = t0b001111. 0b001111, 0b101011, 0 b 1 0 1 0 1 1 , 0b011011, 0b011011, o b x 1 1 0 0 t , 0 b 1 1 1 0 0 1 t)
l , e 3 P I C @l ' l C UE x o e r i m e n t s f o n t h e E v i I
6enius
r main( ) i { , , ,
PORTA = 0t CMCONo - 7t ANSEL = 0t
;
whil.e(1
,
{
== 1)
// //
T1u,tii off Cdq)arators Turn off, ADc
//
Start
//
loop
(i = 0r i < 255i i++) // for tor (j = o, j < 729t i++li
r r
at
I,ED 0
Forever Snqple
Delay
toop
PORTA = TJED\ral.u€ [k] r i // slecify LED Outpur TRISA = TRISvalue [k] r r i k = (k + a) ea A, i // Increnenr k within range of 0-7 i , j i // eTi}lw , } // E!r'I CPKLED t t i lil]ke Predko r 04.11.07 ; t I,rST R=DEC INCLUDE "p15f684, inc" FCIIEN-OEI' & -IESO OFF & _BOD_OFF & -CONFTG _CPD OFF & _CP_OFF & I4CLRE ON & _PWRTE ON & _WDT OFF & _INTOSCIO variables cBr,ocK 0x20 LEDvalu€:8. TRISValue:8 Dlay k ENDC r
PAGE Dlaj.nline r olg
of
movh, E*plicitly nrovwf novwf Inovlltr' novwf novr,rf novlvr rnovwf movwf movlw movwf novwf
b,001111,
i lJoaal TRISvatue
TRISVaLue TRISValue b'101011, rRlsvalu€ Tlllgvalue b,011011, TRISVaIUe TRISVaLue b,11X001, rRrsvalue TRISValue
+ 1 ; NO[E:
DLay
btf,ss soto ilecf,€z goto
SAATUS, z S-4 D1ay, f S - 5
+ G + 7 after ' Return r RBO Toggle r Eigh I Bits
r D€crenrent , WREG ? 256;{ t Repeat
i PoRTA = LEDValue lkl novf k, rnr IJEDvalue
novt^'f
FSR
novf mowrf
INDE, w poRTA
r TRISA = TRrsvalue rnovf k, w
nop
r For
ICD Detrug
cllf
PoRTA
novLw Inovwf bsf clrf bcf
7 OTCONo STATUS, RPo ANSEIJ ^ 0x80 STATUS, RFo
clrf
k
, Start
novl.\r novwf novLw novwf novl.\r no\rwf novln novwf movlxr movwf nrovlw nolr!!-f novlw nol'$rf novl$ rno\rwf
b,010000, IiEDValue b'100000, LEf,ivalue b'010000, IJEf,iVaIu€ b'000100, LEDValue b,100000, LEDVal.ue b,000100, IJEDValue b,000100, IiEDVal.ue b,000010, lEDVaIue
r Load I,EDvalue
i Initialize i to Off off i turn
r/o
Cdpar.ators
r A11 Bits
are
Bits
aaldtut rnovnf
T&ISValu€ FSR
rnovf O"t irovwf bcf
INDE, w STAIUS, RPo TRISA ^ 0x80 STATUS, RpO
incf anallw novwf
k. 7 k
goto
Loop
w
Delay for
the
arlal
Delay
conlents
of
255x
r ; r r r r r ,
lJoad the Offset for IJEDvalue AtLl to Start of I;EDvalue Array Store AaiitresB in hdlex Register cet rJllDvalue [k] save in poRTA Register
r ; r r r r r
c€t lhe Offset for Trrsvalue AtLt to the Start of Array Slore Adalress in Index Register Get TRrSValue [k] Save in TRIS:A Register
[k]
asrnPKJ,ED
O
Pairs
+ 4 + 5
$ + 1 s+1 -1
addl"w
in
+ 2 + 3
r6op: cltf clrw goto gloto aattlLw
LEDS are
the Active , rncrefi€nt lange of i Keep Withia
,
LED O-7
Repeat
Digital end
+ 1 + 2 + 3 + 4 + 5 + 6 + 7
with
D0 E>E,l.icitly
For ConEideration In this chapter,I havereviewedthe basicassemblylanguageinstructionsand givenyou a basicprogramming templateto work from.Along with this,you haveexperiencewith the MPLAB IDE and with programming in C.You shouldbe readyto start programminga PIC MCU in assembler, only you may not feel that confident in your abilitiesto do so from scratch.Chances are if you havea programmingassignment, you will be
S e c t i o nE i g h t P f C @i l C U A s s e m b l y L a n g u a g e P r o g r a m m i n g
L83
able to copy asmTemplate.asm into a specific subdirectory for your application,renameit to the application name,loadit into MPLAB IDE, and then just stareat it becauseyou don't know whereto begin.Before going on to more complex programming assignments,I would like to giveyou someguidancein structuring andwdting PIC MCU assemblylanguageprograms. The basicpartsand sequenceof the assembly languageprogramare asfollows: 1.
2.
fr "r"{
s
t{
rU .F{
u) .'\
Use nop as the first instructionso an MPLAB IDE incircuit debugger(MPLAB ICD) module can be usedto help you debugyour application in circuit.Although you may not havean ICD (or ICD 2) that you can usefor debugging,it's a good idea to alwaysput this instructionin so you are in the habit of being ready to debug your codewith the ICD.
Perform the necessarybank 0 initializations.I like to put in the variableinitializationsfirst, followed by the hardwareinitializations. Rememberthat variablesshouldalwaysbe initialized(evento zero) usinga clrf instruction. 3. Perform the necessarybank 1 initializations. Theseshouldjust be hardwareinitializations; you shouldnot put any variablesin bank 1 until you are very familiar with PIC MCU assembly languageprogramming.Rememberto XOR the registeraddresses with 0x080to ensureyou do not get a messageindicatingthat you are accessing a registerin the wrong bank.When you work with other PIC MCUs that have hardware(and variable)registersin banks2 and 3, you will haveto repeatthis stepfor each one of the registers. 4. Virtually all microcontrollerapplicationswill executeforever,taking in input, processingit, and then passingit back out.After the initializations,the codeshouldstart executingthe loop code. 5. Next, read your inputs.This can be simply polling the I/O pins or readinghardwareregister values. 6. The inputs are then processed. This processing can includecomparisonsto expectedvaluesor arithmeticcomputations. 7. Onceyou haveprocessedthe inputs and understandwhat shouldcome out of the application, you can output them.Just aswhen you read your inputs,outputting could consistof writing directly to I/O pins or to hardwareregisters.
If somedelayis requiredin the prograrn,it shouldbe done here.Creatingdelayswill be explainedin the next section. 9. The loop codeis complete.Jump to the start of the loop and begin again. 10. Define the variablesto be usedin the program. I like to definethem last becausechancesare I addedone or two when I createdmy program, and this way I can go back and make sure everythingis definedusingMPASM assembler (when the programassemblescleanly,then all the variablesare defined). 8.
To illustrate how a program is created using this methodology,I createdasmButton.asm. In this program,I haveput in commentlinesthat startwith #### to indicatewhich of the 10 stepsis beingimplemented in that and the followinglinesof code. "asnButton
!181€ IJED
- prc15r58{/prcKit
Butstotr
ONN
i t
Thia lrheu
Program luras the Button at
i t t t t t t
Haralwale Notea I PIC16F58{ run'riag a! { MHz UaiDg Internal Clock External Rea€l ia U6etl RA3 - PICKit Button RA4 - LED Poailive RA5 - IJED N6ga!iv6
i r ,
Uyk€ P!€tlko 04.LL.O7 IJIST R=DEC I!|CLUDE "p16f68{.
ou tlr€ RA3 is
PrcKit,s Dreaseal.
the
inc.
& _rEso_oFF & _BoD_oFF & _coNrrc _EcltEN_oFF _CPD_OFF & _CP_OEF & _IICIJRE_OFE & _PWRTE_O!{ & _IIIDIT_OFF & _INTOSCIO valiablea CBIOCK 0x20 - 10. *lt** r Tetlp ENDC t
t
PAGE l,lainliae or9
of
Put
in
(if
Ehe valiab16a
0
r #### - 1.
Put
ia
nq9
nnoD" inatructsion r ror
r **#* - 2. Prrt ia trbvltr oriFF novwf PORTA
r€quir€al
"Bsnlr 0 rnitializalions" ; !'lake AU PORTA Bits
the EviI
for
ICD Detnrg
k{ l , e l P I C @l l C U E x p e ri m e n ts f o r
requir€tl)
cButton
l"l
184
D0 rrED
6enius
High
rcvhr 7 i Iovwf CIICINO .BaDk 3. Pul iu r #**# bsf ATAttlS, RPo clrf .NISEI. ^ 0xg0 , novlw orroFF ^ ((1 << t rcvwf IRISA ^ 0x80 bcf sTAnts, Rpo , **** IJoolr I t ##** rcvf,
- {.
LoD
Ertry
- 5. R€ad ln PORIA, w
Tuln t
off
Cclq)arators
InLtializalionsn
A11 Bits ar€ Digltal 4) | (1 << 5)) RA{/RAs a!€ Digita]' OutDuta
bovwf , #*** e'vbr btf,sc novlw t **** rdvtrf r **#* r lt#lt* golo
TdE) for , Store 5. Proc€ss rqrutss 8,011111' r DO G? Tetqr. 3 t If, RA3 ls 8,111111' t No, Off 7. Outpur proc6s6edl rDput PORTA (tf Required) 8. D6tay 9, Relu!'r to the start of IJooD , Rerr€ats
qt
RA3 Check
g6t
tb3n
th€
L.oolr
trYesi
o p
end chech
rt
o
Poiat
Intrirls t Want to
o
0t
R.tr3
f",
g
o
Fl
t,
ct h..
o 5
S e c t i o nE i g h t P I C @f l C l J A s s e m b l y L a n g u a g e P n o g r a m m i n g
185
Nine
Section
PIE@ Microcontroller HEsemblg LanguageFleEource Floutines
1 Prc16F684 Red LEDS 1 Yellow
LED
1 0.01 /rF capacitor tYpe)
(any
100O resistors 1 I
Breadboard
1 3-cel1 DMM
AAA battery
pack
AA batteries
Needle-nose pl iers Wiring
kit
If you wereto askme whetherusingC or assembler languageis the most efficientmethodof creatingcomplex PIC MCU applications, I would answerthat the bestapplicationsare written usingbotlzprogramming languages. C is excellentfor high-levelprogramflow wherecomplexconditionaland adthmeticstatements are normallyused.Assemblylanguage programming is necessary whenyou havea preciselytimed interface requirementor logic/arithmeticoperationsthat must be very efficientlyimplemented.Although in the rest of the book, I concentrateon assemblylanguageprogramming,I want to point out that you havethe opportunityto add assemblylanguagecodeto your PICC LiterMcompilerapplications. Thereare a number of thingsyou will haveto be awareof beforeyou stafi addingassemblylanguagecodeto your PICC Lite compilerapplication. The first issueto be addressedis whetheror not your applicationcodewill consistof a mix of C statementsand assemblylanguageinstructionsor if the applicationcodewill haveonly one of the two programminglanguages. Even without looking at how the PICC Lite compiler'sbuilt-in assemblerworks (which is requiredfor an applicationthat hasboth C state-
mentsand assemblylanguageinstructions),I would tend to go towardshavingseparatefiles for assembly languageand C sourcefiles.The two codesources would be individuallycompiledinto .obj files (often calledobjectfiles),which would then be linked together.MPLAB@IDE handlesthe compiling,linking,and source-codeJevel debuggingchoresvery efficiently,with eachsourcecodefile displayable. An importantadvantageof usingmultiple sourcecode files is that subroutinefiles canbe sharedvery easily, especiallyassourcecode,which would eliminatethe possibilityof a developerchangingcodethat is already runmng. The problemwith linking multiple files into an applicationis the additionallearningand work that is required.For the applicationsin this book, I don't feel that it is appropriateto attemptlinking multiple files together.Instead,the examplesof mixed codesources will primarily usePICC Lite compilerC sourcecode with inline assemblerstatements.The assemblylanguageinstructionscanbe addedindividuallyusingthe directive: asm(,'PIC UCU Instruction"
't87
)t
..::: " r1i : l .i{
:*-'i 11 .!.i
r,{a a'i '.-'j
i"r;; a'\ l-:i t::ii
i 1'r
i.t') f',,,.,
..-t
or they canbe addedasa predefinedfunctionstatement.Earlier in the book, I usedthe NOPQ;builfin function in a number of applications.This function insertsa singlenop insffuctionin the codeand allows me to set simulatorbreakpointsin the application wherethe statementsor operationseitherdo not seem to skip randomlyto other instructionsor to setbreakpointsresultsin an MPLAB IDE simulatormessage. Along with the nop instruction,the cleartheWatchdog Trmer(clrwdt) instructioncan alsobe addedto a PICC Lite compilerapplicationin this manner. If you havea nurnberof assemblylanguageinstructions,you shouldindicateto the compilerthat assembly languageinstructionswill follow by usingthe #asm directive, and that you are finished by using the #endasmdirective.These directivesand instructions are bestplacedin uniquesubroutineslike the followrng one: int Aaaenibl:rDomo ( Lnt SqvaLue) ( lhe Squale of // Calculate
nvaluen
= SqVaIue, to Squar€ in Mesrory lJocation // save value caa access uniquely // aaa€lible! *aam movf w // Get uulliDlicand _al, clrf _gquale + 1 clrf _gquare ASt ooD: Loop Back to Iler€ until ai
atLkcf blfac incf alecfaz
t'i
gquale, Etatus, _gquare f _ai,
f
i 0 i + 1, i
Afldl Value to sguale ou€rflow? f Decrement Rep€atedl Aalalit'ion Counter
golo *entlaBm !€turn //
,
ASIrooP
t Retura
lo
Trl.
agaitr
Squalei wrd
AaaeniblyD€mo
Thereare five thingsyou shouldnote about the codein this function: . .
The addition of the leadingunderscoreto variable namesin the in-line assemblercode. The needto declaremost variablesas"char unsigned"variables.This isn't readily apparent in the code,but eachbyte variableshouldbe declaredas"char unsigned"to avoid negation issueswhen executioncrossesbetweenC and assembler.
.
The lack ofbit labelsfor statusor any other registers.
. .
Declaredregistersare all lowercase. You do not havethe $ operator to help you avoid comingup with your own labels.You will haveto put in labelsfor every for loop.
For the mostpart,thesedifferencesdo not make writing inJine assemblermore difficult,just different. This is why I recommendthat you add inline assembler instructionsonly whenyou haveto.The PICC Lite compiJer is a remarkably efficientcompiler.andthere will be only limited situationswhereit is bestto combine C statementsand assemblylanguageinstructions together.
i--: f -l .
Experiment72-LoSic 5imulationUsing the PlEl6F6Btl a:\! |*
1 P rcr.6F58 4 Red LEDS
+]
I
i']
YelIow
LED
Ji1
1 0. 01 pF capacito! tYPe)
,*
2 100O !esistors
(any
1
,,,{ ! t
DMM NeedIe-nose pliers ttiring
ir**
I
Breadboard
I
3-ce11
AAA battery
AAA batteries
kit
il:*a ri,l
i.1
188
l , e 3 P I C @l " l C l E J xperiments for
the Evil
6enius
pack
I hope that I haveimpressedyou with the power and capabilitiesof the PIC MCU. Now I'm goingto try to you andshowyou the minimumthatthey underwhelm canbe programmedto do.Thisis a good time to go back and showyou how truly good the PICC Lite con.rpileris and showyou a little trick tbr creatingyour own PIC MCU applications. In thisapplication,Iam goingwe will createa two-inputAND gatefrom a PIC16F684. The circuit that I havecomeup wlth is very simple(seeFigure9-1)andcanbe wiredon a breadboald(seeFigure9-2)in iust a coupleof minutes.I wantedthe LEDSto be lit when the input wasa 1 andoff whenan inputis 0.Todo this,I takeadvantageof the halfVdd voltagethresholdon the PIC MCU pins.Red LEDs havea voltagedrop of 2.0volts, whichis greatcrthanthe 1.5-volt thresholdof thc PIC MCU input pins whenthe PIC MCU is poweredby 3 v o l t sW . i l h a I { l { l Qc u r r e n t - l i m i l i rnegs i s t oi rn s e r i e s . the LED can eitherbe shortedto ground(and turned ofl) for a 0 or left on in circuit to passa 2.O-voltinput to the PIC MCtl. I\n pointingthis out becausethis circuit will /rol work with a 5-volt power supply.
Here is the first experimentlor you to try out. Find the voltagelevel at which the PIC devicetransitions from a 0 to a 1,and whenthe red LEDs are wired asin this circuit.As part of this exercise,make a guessat what thrstranslationvoltagewrllbe beforeyou add the variablevoltagesupply. The assemblylanguagecodefor the application, asmlogiccate.asm,is very simpleasyou would expect.It makesall the input pins digital I/O and then polls the two input pins (RC3 and RC4).Thenwhen the inputsare both high,the output of RC2 is driven high,and the LED connectedto it is lit. rrasnlogiccate titsle sinulationrt r This r like
program a Eingle
-
Losic
causea lhe Prc15F684 2 hput a.ND Gate.
i garalxrare Noles: PIC16F584 rurlniflg , Clock
at
4 !I$z Uairg
to
behave
the
hEernal
Eardlware Notes RCA:RC3 - hpul - Output RC2 llyke Predko 04.11. 19
PIC16F6B4
LIST R=DEC INCLUDE'rp16f684.incrl -CONFIG -FCI,IEN-OFF & _rEso_oFF & _BoD_oFr CPD OFF & CP OFF & I]IICLRE ON & .PWRTE_ON & WDT OFF & Ir\ITOSCIO t
variables CBLOCK 0x20 ENDC
PAGE t Mainline
Fisure9-l
PIC microcontrollarAND gute
org nop
r For
clrf
Initial.ize to Off Turn off
nov$rf bsf clrf nov1n
CMCONo STATUS. RPo AlilSEL ^ 0*80 b'111011'
rnonr,rf bcf
TRISC ^ 0x80 STATUS, RPo
IJoop: btf,ss goto btfss goto noP bsf goto
Fiqure9-a Breodboard AN D gate circuit
ICD Debug
PORTC. { NoMatch{ PORTC. 3 NoMatch3 PORTC, 2 ],oop
I/o
Bits
comparators
Al.L Bits are Digilal RC4:RC3 hputs, RC2 Output
Relurn llere af€er Delay 'f€st Input Bits
Match cycles Both are set
S e c t i o nN i n e A s s e m b l y L a n g u a g e Re s o u r c e R o u t i n e s
to
se!
r.89
Nouatch4
!
goto NoMatch3: bcf goto
t 1\ro Cycles Noltatch3
Past
t ReEeE the
OttDuts
PORTC, 2 Loop
end
To comparethe operationof my assemblylanguage codeto what the PICC Lite compilerproduceqI created a similarapplication,clogiccate.c.This program polls RC3 and RC4 and outputsa 1 on RC2 whenboth inputsare 1,just like in asrnlogicGate.asm. Sincluile clogiccate.c /* Prc15F5g4
J|3 t !
Plogram
outputg
Sinulate
a "f
an AND cate
if
Two Inputs
on a
ar€
u
,
& ICDTDIS & PWRTEN & !4CLRDIS & -CONFIG(INTIO UNPROEECT \ & I'ITPROTrECT& BORDIS & IESODIS & FCMDIS ) ,
nain( )
t PORTC = 0, CMCOIiIo = 7t ANSEIJ = 0, TRISC2 = 0i
(
== 1)
// // //
Turn off CdnDarators Turn off aDC Make RC2 Output
//
Loop
Forever
( (1 == Rc4 ) && (1 == Rc3)) Rc2 = 1, OutDut Eigh // Both High, else RC2 = 0, // E1s€, Low output if
| ,
;'d
ll
/ / er|tu" Endl closiccate
As a follow-upto the introductionof this chapter,I want to showyou the efficiencyof the assembler instructionsgeneratedby the compiler.After I tested the operationof both applications,Itook a look at the codegeneratedby the PICC Lite compilerby clicking on "View" and then on "DisassemblyListing."The followingcodewasdisplayedin a new window on the MPLAB IDE desktoo:
lJ"6 --C:\wriling\Prc Geniua\Cotle\cT,ogiccate 1r *inclual€
190
Program
outputs
a "1"
if
rlro
In!,uta
a?e
1 0 : myke pretlko 11: 04.11.19 L2. 13: L4l CONFTG(TNTIO & W!||IDIS & PYIRTEN & IICIJRDIS UNPROTE & TTNPROTECT & BORDIS & IESODIS & ECMDIS) t
(
231 24: PORTC = 0t 0003F3 1283 BCE 0x3, 0x5 00038{ 187 CLRF 0x7 25: CllCONo = 7r // 000315 3007 !4OvLw 0x7 0003F5 099 uovuF 0x19 26: iNSEL = 0r // 000387 1683 BsE 0*3, 0'r5 0003F8 191 CLRF 0x11 = Oi 27t a&lsc2 // 0003F9 L10? BCF 0x7, 0x2
29: 30:
w h i L e ( 1 -= 1) (
//
rurn
off
coltll)ara
Ilurn
of,f
,rDC
Make RC2 Oulput
Loop
Forever
== Rc{ ) e& (1 == Rc3)) BCF 0x3, 0x5 BrFSC 0x7, 0r.4 BrFSS 0x7, 0x3 GOTO 0x3f9 ll Both Hlgh, BSF 0x7, 0x2
j;
while(l
8:
RCA - Iq)ut RC3 - Iry)ut RC2 - o|rtput
a
!,-!l
i,
This
1 9 : ints i, j, 20l 2 L l rnain ( )
RC{ - Input RC3 - rnput RC2 - Output
int
{:
L7z -
ml'k€ grealko 04,11.19
L t_:
an AllD Ciate on
Simulate
Nolrlatch3
tti
Thia
c -
2, /+ cLogj.ac ale. PIC15F6
Evil \cIJogiccate.
c
0003FA 1283 0003F8 1A07 0003Fc 1D87 OOO3FD 2BF9 32t RC2 = a, 0003F8 1507
OutsDut
You can make a couple of conclusionsfrom the resultingassemblylanguagecode.Thefirst being,the disassemblylbting is not complete.The closingbrace for the "while(1 - - 1)" statementand a"goto 0x3fa" instruction.which returnsexecutionto the start of the comparison,are both missing.Tosimulatethis applica"pin stimulus"featureof tion, I usedthe asynchronous the debuggerto changethe statesof the input pins. The secondconclusionyou canmake is that the PICC Lite compilerisn't stupid.It wasableto convert the two-termif statementinto just three assemblylanguageinstructions. And at the sametime,it wasableto note that resettingthe TRIS bit RC2 in bank 1 is the sameasresettingpin RCZ in bank 0. Later in this section, I will provideyou with a set of macrosthat will allow you to virtually write your own highJevelcode in PIC MCU assemblylanguagewithout havingto understandhow the differentinstructionsoperate.But the codeproducedby thesemacroswill in no way be asefficientasthe previoussnippetof code.
l , a 3 P I C @l ' l C UE x o e r i m e n t s f o r
the Evil
Genius
how The three-instructioncodedemonstrates in the PIC operationscan be created sophisticated just MCU using a few instructions. Two-bitinput AND statementsand OR statementscanbe producedusing the following templates: i
AND Code 3 Instruclion btfsc Regislerl, bitl
btf,ss goto
Register2,
biL2
SlitDNotTrue
r Coale E:.ecutedl Both Bits are
ANDTrue:
;
3 Instruction OR Coale btfss Registerl, bitl btfsc goto
oRNot True:
Bit Input r If First is 0, Jump to not True lnput i rf Seconil Bit iB 1, .runp to True r One or Both Bit hpurs is 0, nnotn
Register2. oRTrue:
bil2
if 1
Bit ia 1, r If First iIump to "True" r If seconal Bit is 0, Jrrnp to "Fafse" are t one or Bolh Bits
I r coale Execut€al if Both Bits are 0
Thesetwo snippetsassumethat Tiue is high.They canbe easilymodifiedifTiue is low for one or both bits;simplychangethe btfssto btlic, and visaversa.
If you are a student,I shouldremind you that it is not a good ideato w te your applicationin C and then usethe PICC Lite compilerto generateassemblylanguagecodefor your applicationfor a numberof reasons.First,the displaydoesnot labelregistenlif you window wereto hand in the codefrom the disassembly I suspectthat eventhe mostdim-witted unchanged, teacherwould noticethat somethingwasamiss.Second,the codedisplayedin the DisassemblyListing window doesnot haveany goto labels,and you will find it to be a significantchallengeto correctlymove the locationof the codeproducedby the PICC Lite compilerto the locationsrequiredfor your application. Chancesare it will take more time and effort than if wereto do it yoursell Finally,the worst thing that couldhappenis that you correctlylabel the registers and addcorrectgoto labels,and then your teacheris so impressedby your work that you are askedto explain to the whole classhow the codeworks.If you're having createa problemssolvingan applicationin assembler, program the PICC Lite compiler C and lun it through to seehow a professionalwould codethe application. But remember,it's in your bestinterestto take what you learnfrom the DisassemblyListing and applyit to your application,rather than trying to usethe code that'sdisDlaved.
" 5 u ri tc h " ExFer im ent 73- lm pl e m e n ti n gth e f S t at em entin H s s e m b l gL a n g u a g e In this experiment,I would like to showhow the C switchstatementcanbe implementedin assembler: ( (variable) switch // value lo be testeal case 2: nvaliable == 2n to E.ecute if // Statenents the "switeh" Statenent breakr // Exit cas€ 23: == 23 if, 'variable to Execule // statenents br€akt
If askedwhen I first learnedto program,I like to reply that it hasbeengoingon for 25 yearsnow.Theimplication is not that I am somewhatdim, but insteadthat thereare so many differentwaysto solveprogramming problems.I bring this up becausethe codefor this expedment,which waswdtten after the codefor the followingexperiment,is a lot mole efficient(i.e., smaller)than the codein the following experiment. Logically,the programsshouldbecomemore sophisticatedandefficientasyou progressthroughthe book.I wantedto illustratea particularpoint, so I placedthis more efficientprogrambeforethe lessefficientone that followsit.
//
//
Statenenls b!eaki default: statenents "variabl€ ]
//
Uo Execute
if
nvariable
== 47
l= 0 oi 47 // "variabl€" != 0" and to Execute if, "variable t= 47" hctiws
There are several ways in which the switch and case statementscould be implemented in this block of code to execute specific code if the contents of a variable match a specific value, but for this experiment, I will focus on the general casecode. One way to implement this function is with multiple comparisons.lf this were to be written in a language
S e c t i o nN i n e A s s e m bI y L a n g u a g e R e s o u r c e R o u t i n e s
191
with an "if then goto" statement,the switchstatement could be implemented as: (2 == Variabl€) if th€n == ?LraE gwitch CaEe StaEenelts to tlr.ecute lf goto gwitcbDone
{J
// //
ct
Not2: (23 == Vrriabl€) if th€! // == s€coaal Snitch Case // Staldl€rta to Execute if goto swilchlrone Not2 3: ({7 == Variable) tf th€n // == Thirit S:nitch Caa€ // gtaldlellta to Execute if goto switclDone Not{7: - Stat€arenlB // trD€faulli to rrvari.rbl€ != 2' anal
c
E o
.p
(s
.tJ
q
"q ()
{J ''.1
B
q
U
c,
rrvariabl€
!= 23'
nvariable
!= 47tr
gotso Nots2 "Variable
goto
| I
golo
c
trvariabl€
Executse
movf, r.or1!r
variab1e, 2
9{
X
rd
{t
if
,
"tf
(2 == variable) goto Not2r
btfaa sTAlt'os, z gtoto Not2 'varia.b16 ^ 2n equal to Ex€cute // Staletrents tf z€lo switchDone "o"o Not2: xorlrc 23^2 , W R E G= ( W R E G ^ 2 l ^ ( 2 3
^ 2)
t = W R E G ^ 2 3 ^ 2 ^ 2
t gTATUg, Z btfaa goto Not23 // gtelen€nts to tir.ecute
goto switchDon€ Not23: r.orLlr 47 ^ 23
L9z
l-
23n atd
^ Hnoi
23 (B€cauae2
"Valiabl€
if
-=
23
, wREc = (WREG ^ 23) ^ lA7 ^ 23) , = W R E G ^ 4 7 ^ 2 3 ^ 2 3 , = vlR.EG ^ 47 (Becatnae 23 ^ 2 3 = 0 )
bbfa8 STATUS, Z golo !bt{? // Stalen€nla to E lecule grditclrDone goto No!{t: - Stsatenenls // "Defaultrr "Vari.rbl€ t= 2" aDil "valiable
{?tr
naamPKIJED 2 LED"
PICkit
1 starEer
Lf
lo
"variabf,e
Execute
== {7
if,
hit
copies r This program allrectly the op€ratio! CPKLED.c antl Elaaheg the I LEDa oa the PICkil , 1 alarter LLt in Sequenco. i Hartlwar€ llotses: PIC16F68{ rutlDing at 4 llllz Usltrg t Clock Exterttal Resel ia Ua€fl t Circuit Runa oa PICkit 1 Etart€r r
!t
.Fl (,
=-
!=
This method of implementing the switch statement in assembleris quite efficient and easyto code,asI show in the code for this experiment, asmPKLED Z.asm.In this codeI havetried, asmuch aspossible,to dfuectlyconvert the highJevel statementsof cPKLEN.c to assemblylanguagestatements: lit].e Ruaning
Not{?
This isn't a terrible baseto work from, but we can do better.The secretto doingbetter is to load the vari, able into the WREG and then compare its contents usingthe xorlw instruction repeatedly.Take advantage of the MPASMTMassemblerbuilt-in calculatorand XOR the valueto be testedwith the Dreviousvalue.Bv doingthis.the previousXORed valui in theWREG is returned to the original state and then XORed with the new value.To showyou what I mean,I canconsider the if equivalent to the switch statement as:
c
t{
23
SwitchDoE€:
t-
c,
-=
anat
1Y1
1J
No!23
,'variable
thea
IJ
== 2'
rvaliabl€ SwitchDone:
t Original r inl
i,
the
rnternal
Lits
Coale: J, kt
r nain ( ) t t r
t PORTA
= 0t
t
ANSEIJ
,
k -
=
0i
0;
// //
Turn Tufi
//
starts
t //
== 1) wbile(l IrooD Eorever
r //
sirnDle
, ll t t t t t r r i i i t t i r , t
(k) t alritch geLecL Whicb LED to DieDlay caae 0: PORTA = 0b010000, TRISA = 0b001111, breah, caa€ 13 PORTA = 0b100000t TRrgA - 0b001111t breakt caae 2r PORTA = 0b010000t TRISA = 0b101011t braakt caae 3: PORTA = 0b000100t TRISA - 0b101011, breaki
t t r t r r i i
PORIA = TRISA = breakt case 5: PORTA = TRISA = breekt cese 5:
off off a!
Cdrlraratoig A.Dc LED 0
f,or (i = 0r t < 255r i++) Etelay IJooD for (j - 0r j < 129r j++)t
0b100000, 0b011011;
0b000100; 0b011011t
l , e 3 P I C @l l C U E x p e n i m e n t s f o n t h e E v i l
6enius
of
= 0b000100t = 0b111001t
r r i ; i , i r
PORTA TRISA br€aki caa6 7t PORTA TRISA breelr // l
, //
k E ( k + 1 ) ? 8 t IDcr@ent k lrithi!
, ,
l )
//
= 0b000010, = 0b111001,
of
& -INTOSCIO
Varlabl€g CBI,oCK 0:.2 0 Dlay Actj.veBj.t E![DC r
r Recoril
Bil
tsb6 Activ€
Turrr
,
SetuD TRIS for Nd.t Disglay
mov$f goto
II{DF LEDIron€
o
EoD
For
t
Cl.lCONo gTAfUS, RPo tt{SEL ^ 0x80 srATus, RPo
t All
I/O
Blts
to
Trr/D2: xorl$ btfss
2 ^ L gTAtgg,
golo movltp novfif rnovlw
Trt'D3 8'010000, PORTA 8,101011,
rtrovwf goto
INDF IJEDltole
BitB
Digital
a!€
AcElv€BLt
r gtalt
novlw
TRISA
novl "f
FSR
r PoLnl FgR to TRISA fo! raat TRrsa try)alating t
Loo93
i
D].ay
btfss goto tlecfaz goto clrf
sT ms, S-2 Dlay, t S-{ Dlay
, Dlsplay
i i
i
-1
rdith
Returl Delay High
8 Bits
D€cr€eeat conlenta 256'* t i
z
clrr' edld].w
-1
btfaa goto al€cfaz groto
sTATus, z $-2 Dley, f. S-4
Dovf
ActivcBit,
t R€Deal i
o
th€
Ft F.
Rep€at
Tuln
on D1
getuD
fnIS for Dj.aDlay
, R€D€a!
for
D6Lay
tlre of VIREG
R€p6al Again 400 ms total
f,or Delay
255x
Bit
movlrf grolo T4fD5: xorlv btfa8 golo lrovlrd lrovwf movlw movwf goto
th€ of WREG
t Loadl the
FiniEhed,
t DisDlay
i
the
tr.|
R€9eat
(^,
D2?
Turn
I
on D2
t S€luD TRIS for Next Dis9Lay
8'000100' PORIIA 8'101011'
r DIaDIay
r Tuln t
getup
MDF LEDDone
the
4
ro
ReDeet
r Finiahedl,
3 ^ 2 Sf[lTUg, z Trl'D{
{ ^ 3 grATItg,
5 rt
Z
NdrE
TryD{: ,ror1w btfaa goto novlw ovnf rovltr
3 o
Dl?
D3?
o
on D3 IRIS f,or Dl.aDlay
t Finishedl, i
DigPlay
i
Turn
,
getuD
th€
Q
ReDeat
{
D{?
F.
rf
z
TrtDs B'100O00' PORTA 8'011011' INDF IiEDDoue
o
on D{
TRIS for NexE Diaplay
t Finlahetl,
the
Rep€at
efter
255x
r Decra€nl coDt€rrta , 256x
rr
D0
ll6re
t
Off lovwf goto
clrf
clrf clrrl' aaLllw
8'100000' PORITA 8,001111, MDF IiEDDoa€
lrov1w movrrf, lrovlw
ICD Delntg
r hitialize , Turn off
PORTI 7
16
on D0
, Einisb€al,
1 ^ 0 STATUS, z TrfrD2
movlrf goto
Tr,yD3 ! xorlw btsfaa goto
PAGE uailline
clrf novlv coqraralors novn"f baf clrf bcf
i
Next
_cowrrc _ltllEN_oFF & *IEgo_oFF & _BoD_oFF & _CPD_OF! & _CP-O!F & -!|CLRE_ON & _PIIRTE_ON &
or9
8'010000' PORTA 8,001111,
novlw rovlrf, movlw
'IST R=DEC INCLI'DE nD15f 58{. iDc"
t
movlw novwf fiovlw
TryDl: r
// €lihw Enal CPKLED
liEfke P..tlko 0i1.11.28
_WDI*OFF
, Start
0-7
t t t
E4 X
D0
0 slATUg, z EryD].
hctL$3
reig€
r'ith
*o!lw btfBs goto
Nlrmber
Trl'D5 3 xollw blfBs goto movl$ novlr'f, movlw movlrf goto
5 ^ 4 z sfATlrs, TryD6 8'000100' PORTA B,01101f INDtr rrEDDone
t DisDlay
d
i
Turn
i
getuD !'Rrg for N€trts DiEI'laY
MDF LEDDone
p, ct
on D5
t Finisheil, r DIaDIay
5^5 z Sf!l!!gs, llryDT 8'000100' PORIIA B'11100f
CN
D5?
lhe
o 3 o p
R€96a1 D6?
a+
on D5
i
fuln
i
S€EuD TRIS f,o! Next Dlat)lay
t
FiniEheal,
lhe
RsD€al
S e c t i oN n i n e A s s e m b l yL a n g u a g eR e s o u r c e R o u t i n e s
193
TryDT : xorL$ btsfaa goEo ovht monwf novl$ novwf goro
,
7 ^ 5 STAllrUS, IJEDDone
PORTA B' 111001'
t Turn
Finiahetl,
IJEDI'ON€:
andlw
7
movwf
Acliv6Bits
qoro
LooP
on D7
r geluD TRIS fo! N€xl DiaDlay
I![DF LEDDon€
AcliveEiE,
D7?
Z
B'000010,
Ldcf
DisDIay
the
ReDeat
FiniEh€d DisDlayingr LED Inclelent the Active IED Ke€p witshin rang€ of
o-7 i
RepeaE
end
Thereis one lastpoint I would like to make about aSmPKLED2.asm,andthat is how I wasable to quickly changethe valuesof the TRISA register.In the code,you seethat I loadedthe FSR registerwith the addressof TRISA, and when I had to changethe value of TRISA, I simplywrite to the registerpointedto by the FsR.Another way of implementingthis code would be to changethe bank and write directly to TRISA (without involving the FSR register), using the following code: lrovlw
NewPORTAValue
r WrLte value
nrovwf nrovlw
PoR!!A NevrTRISAValue
,
bsf noverf
STATUS, RPo rRISA ^ 0x080
i i
bcf
SfATuS,
i
RPo
the
nevr PORTA
SetuD TRISA f,or tshe Nexts DispIBy Ex€culs in Page 1 Sto:.e lhe New TRISA VaLue Return E:.eculion to Page 2
Experiment 7U-Defines and it behavessimilarlyto the C languagedefine.That "String" is substituted is,when"Label" is encountered, in with and any argumentsput into the string.The stringsubstitutionprovidedby the #definedirective differsfrom the operationof a macroin the scopeof the substitution.The #definesubstitutesa stdng on a line of assemblylanguagecode,whereasa macrosubstitutesthe entire line (andmaybeaddsadditional lines).
{t
c
,t{
{+.{ 0,
n I, qr f* {J
fr
0l H
. r-! ( r
CI g-. t\,
n
If you haveworked throughall the experimentsin the previoussection,you will havenoticedthat accessing UO pins in assemblylanguagecan be somewhatawkward due to the needto specifyboth the port and the bit numberof the pin in the bit inshuctions.As you start programming your o\an applications,you will discovercaseswhereyou mix up which port is usedwith which pin; the program will not work and the problem will not be easilyfound by readingthroughthe program.You will be able to find the problem by carefully sirnulatingthe applicationand watchingits operation, but there is an easierway to avoid the problem all together.Insteadof associating a pin with an IiO port register for the bit operations,you can declare them together using the #define directive. The format of the #define directive is: +alefine
Label[
(argullenl
[,...1)
]
Strins
The most common use of the #define directive in PIC miuocontroller applicationsis for the combining the port and bit numberfor a specificpin. For example,if you wantedto declareRA3 asan LCD's clock (E) pin, you couldusethe statement: *dlefine
LCDE PORTA, 3
Now,whenthe label LCDE is encountered,asin the bit statement: baf
IJCDE
the string"PORTA,3" will be substitutedinto the instruction. To demonstratethe useof the #definefor port pins, I createdthe asmPKLED.asm, which is a "port" (or languagetranslation)of cPKLED.cand cyclesthrough the eisht LEDS of the PICkit 1 starterkit.
kl L9s
l , 2 l P I C @l l C U E x p e ri m e n t s f o r
the Evil
6enius
litl€ I,EDN
"asnPKLED
-
PICkil
1 atarter
kit
r r i
This program cogi€s th6 anfl Fla6hea the 8 IiEDa 1 start€r on the PICkit
i , i i ,
Hartlware Notea: ruDains PIC15r58{ al 4 Mlz Using In!6rna1 Clock Ext€rnal Reaot ia Usefl 1 start6! Clrcult Runa oD PICkit
IJED DEfi'tEA: ; DoAnotl€ *alefin€ *al€fLne Docathoalo DlAnoA€ #al€fln€ *alefi.ne Dlcatshotle D2Anoal€ #a16fitre D2catbode *al6fLne D3Anoal€ *defin6 D3cathode *alefin6 D4anoale #alefin6 D4cathoale *alefin€ D5anod6 *ilefine Dscathodle *alefine D6anod€ *alefia€ D6cethoale *d€fine DTAnoale *il€fine DTcelbod€ *ilefine i t t
functioa kit
of
cPKrrED. e
g€qu€nce.
ln
kit
lilyke Pretlko 04.10.0'l LIST R=DEC INCLUDE "p15f,58{,
inc"
& _BOD_OrE & _colIFIG _FCUEN_OFF & _rEgO_OlF _CPD_OFI'& _CP_OFF & _!!cIrRE_O!{ & _PIIRTE_ON & _!itDT_oPt' & _rNToscro valiableB CBI,oCK 0x20 Dlay Activ€Bit EiNDC
,
the
Activ€
TryDl: aaltlln btfBa goto bsf
-1 STAfUS, z TryDz STATUS, RPo
bsf
Doaloale
bBf bcf bcf bcf bsf bcf goto
Docathoale DlAnode Dlcathotla STATUS, RPo Dlt'loil€ Dlcatboal€ IJEDDIay
!!zr/D2, aaLllw btf56 gotso bsf bsf
-1 STATug, z Trl'D3 STATUS, RPo DlA.aoale
baf bcf, bcf, bcf baf bcf goto
Dlcethod€ D2nnoale D2calhodle SfATUS, RPo D2}Ilodle D2calhoal6 I.EDDlay
baf bcf bcf bcf bsf bcf goto
0
DOD
,
clrf
PORTA
rnovhr rtovwf b6f cLrf bcf
7 C!{CONo STATUS, RPo ANSEL ^ 0x80 sTATuS, RPo
clrf
lcliveBit
Eor
Loop !
CoaE)araEorB
r A11 Bits
ar€
iacf
Actlv€Dit,
rd
aaLlfuc blfaa golo bsf bEf
-1 STAqrS, z TrJ'D1 STATUS, RPo DTAnod€
lrlth
I/O
Bita
D0
i i
Stalt
t tur!
tql
X
D0 IrEDa
b r rlaiahefl,
o
r-l
Repeat
; DiaDlay
i
D1?
t!ur! olF DisDlayeal
r EnabLe
D2cathotle D3Anotle D3cathotle STATUS, RPO D3Anoal€ D3cathod€ IJEDDI8y
3 o p
rt
D0 IJEDa
--l t Finisheal,
|'F
R€Deat D2?
U
OFF Previously t furE LED DiEDlayeal r Enable
o
D0 I.EDg
Hh
t-r. r-t
i
D3?
Turn orF Dis91alreal
t Enable
r0 m
Repeal
r rlaiab€al, r DIapIay
-1 STATUS, z rrylx STATUS. RPO D2t'lode
F.
Previoualy LED
, Diaplay
P!€vioualy r,ED
D0 IrEDa
t fidiah€il,
with
r DiaDlay
TryD{ ! aalillw btfsE golo baf bsf
ReDeat
STAITUS. Z ErfzDs sTATug, RPo D3Anod€
bsf bcf bsf bcf baf bct goto
D3celboale D{Anoale D{Calhodle RPo STlrUS, D{Anofle D4cathotle TJEDDIay
D0
OFF Pr€viously
TryD5: aalallrd btfaa goto bsf
D4?
-1
Digital
Retura llere aft€r D6lay Loail the Bit Ni'mbe!
i
LED
ICD D6bug
r hitialize to off , TurD off
r glarts
r E[ab1€
Bit
PAGE Malnlin€ org
DTcalhodle DoAnoile Docalhod€ RPo STlrUS, Dohodl€ Docathodle l,EDDlay
TryD3 | ailtlllr btfsa golo baf baf
t
r Recoral
baf bef bcf bcf, b8f bcf, goto
the
4 5 5 { 4 2 2 1l 5 2 2 5 2 1 1 2
PORTA. PoRTA, PoRTA, PoRTA. PORTA, PoRTA, PORIA, PoRTA, PORTA, PORTA, PORTA, PoRTA, PORTA, PoRfA, IORTA, PORTA,
DisDlay€dl
Rutralng
-1 STAfI'S, z TryDS
r |IurD OFF Pr€vi.oual.y DiaDlayetl LED r Enabl€
i
Finish€dl,
i
Display
D0 LEDg
R€Deat D5?
STATUS, RPo
S e c t i o nN i n e A s s e n b l y L a n g u a g e R e s o u r c e R o u t i n e s
195
bsf
D{$rotle
bgf bcf bcf
D4Catshoale D5Anode D5Calbotle STATUS, RPO DsAnoale D5CaEhoale IJEDDIay
bsf bcf goto
Tura OfE Pr€viouBly Diaplayeal LED Enabl€
incf
ActiveBl.t,
enalfto
7
novwf
ActiveBil
gotso
LooD
!t
D0 IiEDs
Flnlshedl,
, i
IncrerneD! lh€ Active IJED Keeg Within range of o-7
; ReDeal
Repeat €Dit
TryDS: aaldlftt btf,aa groEo baf, baf, baf bcf bcf bsf bcf golo TryDT: atlalllt btfaa groEo bsf b6f bsf bcf bcf
ul () .Fl
t+{
o
o I
I
qr
t-
bsf goto IJEDDIay: clrf cl!!t atlillw btfEa goco dl€cf6z goro clrf
Dlsplay STATUS, Z Tt!'D1 STATUS, RPo D5Anodl6
ENAbIE DO IJEDA
Eioiahetl,
R€peat
Display STATUS, IJEDDIay STATUS, D6Arode
RPO luan OFF Pr€viouBly DiEDlayeat IjED Enable
t
D0 IEDE
Finlah€al,
Dlay
Eigh
-1
Declqrenl contenta 256r.
Dlay,
D7?
Z
DScathod€ DTenoale DTCatbode STATUS, RPO D7Alodle DTCathoAe IJEDDIay
sTATtts,
z f
I
Repeat
Re9€a!
Bita
for
lr€Iay
the of WRIG
255x
s - 4 DIay
Re9eat AgaLa 400 ma De].ay
fo!
STATUS, Z
Decremenl th6 contenta of, WREC 255x
DIay,
ReDeal
f
Chancesare that if you were to codethis application (with six I/O port register writes for eachof the eight LEDs) without the use of the #define directive for the different port bits, you would make several mistakes.The #define directive simplifies tedious code operations such asthe onesrequired for this application.
Turn OFF Plevioualy Dl.aDlay€al IIED
D5Cathodle D6Aaod6 DSCatlrod€ sTlIus, RPo D5AIlodl€ DSCalbofle LEDDlry
c1let aaltllrt b!faa goto alecfez go!o
D5?
255r.
-
I don't want to leaveyou with the impressionthat the #define directive is only for simplifying I/O pin accesses; like the C languagedefine, it can be used asa shorthand way of adding constant arithmetic operations to the application without having to type them repeatedly.Addirionally, bit-flag variables can be declaredusing #define directiveg in the sameway the I/O port bits are declaredin this application. Remember that like rnacros,#define substitutions take place belore the assemblystep.As far asthe assembleris concemed,the strings are constant valueswhen it executes.#definescan also be usedfor defining strings that are usedto control the operation of the code build (This will be discussedin more detail in the next experiment). But the most common define is created by the MPLAB IDE to specifywhich PIC MCU part number information is to be usedby the assembler. As a final point, you'll seethat I implemented the C switch equivalent code in a different manner than in the previous experiment.In this experiment,I knew that the valuesto turn on eachLED are arranged sequentially.So rather than implementing a generalcasesolution 1othe problern, I took advantageof being able to decrementthe value by one for eachLED and finally stopping and displaying the LED when the result is zero. Remember that there is alwaysmore than one way to skin a cat.
.tJ
0,
d 'rl
f{ (,
O{
X
kr 196
l , e 3 P I C @l l C U E x p e r i m e n t s f o r
the Evil
Genius
14 LJ
Experiment 75-EonditionalHssemblg *atefine novf €Ise nov].w €ratif
The exampleapplicationshownin the previousexperiment wasa pretty clumsypieceof code.The task of lightingeachof the eightLEDS on the PICkit 1 starter kit is not somethingthat lendsitself to algorithmicprogramming.Although the codefor eachLED is the same,but there is no consistency betweenpairs,which necessitateswriting code for eachLED. The final result is an applicationthat is quite long and cumbersome. What is neededis a way to minimizethe development effort.The taskof lightingeachLED in sequenceis not a problemthat is easilyaddressed by usinga single previous LED and turning data table.Tuming off the on the next one,asI havedonehere,is not a terribly inefficientway of implementingthe application. The problem rather is how to efficiently code the applicatlon. A potentialsolutionto the problemis to usethe conditional assemblydirectives built into MPASM assembler.These directivesallow you to selectwhich codeis to be assembled or evento createcodealgorithmicallythat canbe assembled into the application. In the interestof clarity,I mustpoint out that these directivesexecutebeforethe codeis assembledand are usedto selectwhichcodeis and isn't part of the assembly. Although conditionalassemblyis not a critical concept,it is somethingthat canmakeyour life quite a bit easierand allow you to producehigherquality code. The basicconditional assemblydirectives are ifdef, ifndef. else.and endif.The ifdef and ifndef directives passany statementsthat follow them if the specified #definedlabel is present.Theelsedirectiveprovides alternativecode,and the endif directiveindicatesthat the ifdeflifndef test is complete.I commonly use these directiveswith the Debug #defineto avoidcodethat will not operateproperlyin the MPLAB IDE simulator. For examDle:
D€bug D€bug ADREgH, Ttr 0x088
4V r IJoatl in ADC ResuLts r In Simulator Readl r sillulaleal
ffi
will return 0x088in WREG if Debug hasbeen #defined,skippingover an invalid registeraccess. When usingifdef and"ifndef' to add and take away instructions to avoid problems simulating the application, you shouldmake surethat both pathshavethe samenumberof instructionsand executein the same number of instruction cycles.This will ensurethe appli cation will executethe sameway in the simulator and onceit is bumed into a chip. As I indicatedin the previousexperimenta common declared#defineby MPLAB IDE is the PIC MCU part number, which consistsof two underscore charactersfollowedby the part number.For example, the PIC16F684usedin this book would havethe #define_16F684.In your applicationyou can testfor this define using the ifdef or ifndef directives.This capability is useful in caseswhere different PIC microcontrollers might be usedin the sameapplication.For example,whenyou are designinga product,you may want to usea part that hasFlashand can be easily reprogrammed(like the PIC16F684), but there may be programmable (OTP) part that can a cheaperone-time perform the samefunctions at a fraction of the costs.A conditionalassernblystatementwill allow you to use the samesourcecodefor both PIC MCU part numbers,with the only differencebeingthe numbersspecific to the different chips. expressioncan be evaluatedby A single-comparison the if directive,which alsousesthe elseand endif directives.You alsocandefinenumericvariablesin your application that exec$e before application assembly. For example,a variablei couldbe declaredusingthe variabledirective,and later in the application,it could be testedagainstdifferentvalues:
fn 6
r*lr,,
|h,
.i:ft {f,f
It)
H
t"{rd ,*.i
variable
i
L-n
,i , , " b8f PORTA. 5 eIa€ bsf PORTA, 0 i = i + 2 enalif
S e c t i o nN i n e A s s e m b l y L a n g u a g e R e s o u r c e R o u t i n e s
L97
Labelsdeclaredusingthe variabledirectivearejust that-labels.To changethe valueof a variable,it hasto be placedin the first columnof the applicationsource codeasI havedonein the previoussnippet. The final conditional-assembly directivesare the while and wend directives,which allow you to place the samecoderepeatedlyin an application.Theformat of theseinstructionsshouldnot be surprising;if you wantedto put in four nop instructions, you could use the directives: variabl€
CD2cathoal€ CD3anoale CD3cathoal€ CD4Anoale CD4cathoale CDsAnoale CD5cathoal6 CDSAnoale CD6cathotle cDTArode cDTcathode
i ,
i
variables variable LEDCount cBr.ocK 0x20 Dlay AcliveBi! ENDC r
r
rrasncond
-
Coflalitional
Thia plograln takes aalvantage of the conalilional assernbly features of !4PAS!I and instead of repeating block of coale seven tines that cycles the I,EDS on the PICkil 1 starter kit, !h€ coale is put in algoritlllnicall"y.
t , r r ,
Harflcrare Notes: PIC15F584 rulltling at 4 MHz Using hLertral Clock External Reset is UBeal Circuit Runs on PICki! 1 stalter
LED Defines: r CD0Anodl6 EQU CDocathod€ EQU CDlanotle EQU CDlcathoal€ EQU CD2Anoale EQU
4 5 5 4 4
the
to
Display
Activ€
Bit
asniPKLED
nop
t
cl.!f
r hitialize off off t rurn
Conparators
r AII
are
the
kit
novl"w novwf baf clrf bcf
7 Cr?rCONo STATUS, RPo ANSEL ^ 0x80 STATUS, RPo
clrf
Acti.veBit
incf
a
rr
lrhil.e lEDCoun! < -1 adillw btfas STATUS, soto $ + 10 baf STATUS, if 0 == LEDCount bsf bsf, else bsf bsf enali f bcf bcf bcf bsf bcf goto IrEDCount €ntlw
ICD Debug r/O
Bits
Return Delay t LoadMe i
ActiveBit,
!'or
r starl
IJoop:
Asaenibly"
r t r r r r r
1ge
of
t OnLy 7 B i t s
t Recolal
Var?Value
This last directiveprobablyseemssomewhatesoteric,but it allowsyou accessindividuallabelsasif they werearrayelements.I havedoneexactlythat in asmCond.asm, which is a rewrite of the sequencing LED applicationand usesthe while,il and #v directivesdiscussed hereto producethe identicalcodeto the previousexperiment'sasmPKLED.asm), but it avoidsthe needto put in the samecoderepeatedly. titl€
PAGE Uainline
= 0
org
Va!#v(i)Value
the assemblerwould processthe instruction: movf
l,lyke Predlko 0{.10.04
FCMEN OFF & IESO OFE & _BOD_OFF & -CONFIG -CPD OFF & CP O!'F & _IICIJRE_ON & _PWRTE_ON & ,litDt oFl' & INTOSCIO
When usingthe while directiveto implementmultiple instancesof applicationcode,you canusea littleknown directive,which is in the format #v(expr)and insertsthe nume c valueof expr into the application code.For example,if the variablei had the valueof 7 andthe statement: novf
2 2 4 5 2 2 5 2 1 1 2
LIST R=DEC INCIUDE "p15f684.inc"
Counter , hitialize i Repeat 4x t Put j"n notr> Counter i Inc!€nent t IJooP Enal
while i < 4 nop i = i + 1
EQU EQU EQU EQU EQU EQU EQU EQU EQU EQU Eou
with
Bits
Diglital
D0
Here Bit
after Nllnber
r Repeat the coale 8x Bi.t Cou[t i Decrement
rurn off, D7 if D0 B€ing turn€d on PORTA, CDTanoal€ i Turn OFF PreviousLy Display€al LED PORTA, CDTcathoale
TRISA TRISA
^ 0x80. ^ 0x80.
,
cD#v(IJEDcount-1).eloale cD#v ( lEDcount - 1) cathode
^ 0n80, cD*v( LEDcount )Anoate ; Enable LED,E I/O Pi[a TRISA ^ 0r.80, CD#v(LEDcour!)Cathoale STATUS, RPo PORTA, CD*v (lEDcount. )Anoale PORIA. CD*v (LEDCount ) Cathoale IrEDDLay Repeat ; Finishedl, += ! , Do the Next, LED TRISA
l , a 3 P I C o l ' l C UE x p e r i m e n t s f o n t h e E v i l
6enius
to
IJEDDIAY: clrf clrw addlw
, tligh
Dlay -1
I
Bits
Decrdn€n! of WREG 255'*
gTATgS,
btfss goto dlecfsz goto clrf
l-2 Dla]', S-4 DIay
clrw afltllw
-1
blfaE golo flecfaz goto
ST.I|luS, S-2 D].ay, f s-{
incf
AcliveBi!,
f
R€p€a!
for the
Decrelrenu of VIREG
w
;
aaaU.w
coutents
255x
Re9oat Again ma Delay
Rep€at
DeLay
the
for
-
{00
contenla
255x
rnclernent the Activo IJED Keep wilhin lang€ of 0-7
ActlveBit
goro
IJooD
,
Re9eat
enal
When you look throughthe code,you'll seethat I have replacedthe pin defineswith equates.This was donebecausethe #v(expr)directivecannotbe used with other dtectives. As I have emphasized,the previous and the next experiments'directives exec'rlebefore Only one the application'sinstructionsare assembled. passis madeto the preprocessor that executesthe directives,and if any directivesare changedand require additional execution,the application will fail. I did so with an When I createdasmPKLED.asm, eyetoward repeatingit with conditionalassembly statements, but it is still not that inefficientin termsof execution and program size.The problem with asmPKLED.asmis in its creation;althoughthe instructions for eachLED can be cut and pasted,I found it a chore to changewhich pin definesare usedfor eachLED (and I madetwo mistakes).By usingthe while directive and other conditionalassemblydirectives,I eliminatedthe task of repeatingthe sameinstructionsover and over andminimizedthe opportunityfor errorsin the application.This is really the major advantageof usingconditionalassemblydirectives:Theyhelp you minimizeopportunitiesfor makingmistakesin your aoolication.
k*t
n4
?-1;
r*
=,1 L'* :
,ar: :: .:. i:J
ExFeriment 76-Macros
i.t:
The MacroParameteris a singlestringor multiple stringsthat are substitutedinto the macro at assembly time.For example,if a macrowasrequiredto load WREG with a numericvaluedividedby two,the macrocouldbe definedas: novhrDiv2 tnovlw endm
The next level of codesubstitutionafter the #define,in MPASM assemblylanguage,is the macro.Macros consistof instructionstatementsthat are insertedinto an applicationalongwith the other directiveswhen the preprocessor is active.Although thereis not one allpurposemacrothat canbe usedto illustratethe concept,macroscan greatlysimplifyyour application programming.This is especiallytrue if you take advantage of the #define and conditional assemblydirectives presentedin the previousexperiments. The format for declaringa macrois quite sirnple: llacroName maclo i llacro coale enalll
}lacfoParaneterl,...
I
llacro Div2value Div2value / 2
If the macrowasinvokedwith a Div2Valueof 47, the followingcodewould be insertedinto the program: novlw
47
/
2
Macroscantake advantageof the conditional and surprisassemblydirectivesof MPASM assembler, created from them functions can be ingly sophisticated asI will show in this experiment. The reasonsfor usingmacrosin your application includethe following: . .
Minimizing programkeying Reducingprogram executiontime
.
Minimizing program .hexfile size Simplifyingthe sourcecode
.
S e c t i o nN i n e A s s e m b l y L a n g u a g e R e s o u r c e R o u t i n e s
199
. r .
Providingopportunity for optionally compiled functions Providingadvancedbuild-time options Simplifyingthe effort required by new programmersto createtheir own assemblylanguageprograms
Functions and subroutinescan be written as macros, and,dependingon their size and the nurnber of times they are accessed, they can decreasethe programexecution time, complexity,and size.Macros can be added to the program, in the sameway a subroutine or function call is added.Themacroavoidsthe overheadof the calVretum instructions,and placing parametersin subroutine- or function-specific variables can reduce both the total spaceand variable requirements of an application.They also provide the assemblylanguage code with variably added functions,and they do so without having to savethe functions in a library and hope that they will not be linked into the final application.
(t)
o l{
U d
E I
One importantnote to newcomersin the programming world about the use of macros:Although you may not have the abilities (yet) to implement macros for simplifyingyour programmingworkload,I'm sure you can identify situations where assemblylanguage programming seemsparticularly dfficult and, therefore, would benefit from a macro.One such example, which I addressin asmMacro.asm, is the if decision structurein PIC MCU assembler. In this exneriment-I havecreateda macrothat usescondilionalissembly directivesto insert the appropdate four-instruction templatecode(presentedin Section8) for a conditionaljump basedon two variablevalues.
\o t\
E
tflrla a9plicalioa alenonstrat€E the Mecro lrhich co4Dar€s lwo valu€a aaal execul€E according sDecif ietl coaalilion.
'ifgo!o"
IjIST R=DEC INCLT DE np15f
r.l
X
'lfgoto,
Dernonstrate
Uyke Prealko 0{.09.1?
'r{
P-.
-
Harahra!€ Not€6: PIC15F68{ ruEing al { IqHz in Re6€t ia lieal alirectly to vcc PuLLup/Prograrming Earalwar€
g (t
$
"asrdtacro
the
litle
r
Variabl€a CBIJoCK0x20
I, J
58{.
idcrl
to
Simulator vie
the
tlaclo i ifgolo ttacro Ver1, C6p, (1 CdE) 0) if (0 Corm 1) if movf Var1, !t aubwf var2, !t gTATUg, Z btf8a €1ae (1 coiq) 1) if novf V€,E2, \r autMf Var1, w btfsc sTATus, c elge novf Var1, w aubwf Var2, rd btfss sTATus, c €ntlif €nalif 6Lse i.f (0 corll) 1) (1 Cofqr 1 ) if novf Var1, !t aubwf var2, w btf,Ec STAIUS, elae novf Vat2, w aubwf, Va!l, w btf,sa SfATUg, eDdif elae (1 Co|sp 1) if movf Var2, w aubirrf var1, w btsfac STATOS, €1a€ 6r!0r ltahnowa ,,if,n endif endif entlif goto Dest endm org nop
Va!2, t
ch€ch
i
Elae
nl=n /t>n
n>n/r>=fl
; check
for
"<"/"<="
Conili.tlor^
15 i 20 j j,
, Requiledl
for
t Ge!
Valuea
i,
>,
no9 ifgoto
i,
>=,
nop if,goto
j,
<,
DO9 ifgolo
j,
<=,
L,
ErrorDOa€
IoD ifgoto
i,
==,
j,
E!rorDon€
i,
novnf
j i,
j,
E!rorDon6
i,
t
j,
geE Equala fo! Equels Teat
ErlorDon€
EO9
f.1
l,e3 PICo llCu Expeniments for
ICD2
ErrorDone
w
l-,
!|PIA8
EtlolDou€
ifgoto
Dovf
!!eal
ENDC
200
/\>=t
0
rnovlw trovwf movlw alovwf
ifgoto
Deat fo!
the Evil
Genius
Not
i,
ifgoto
==,
j,
coodDone
Codte Shoul.tl be llele
EtlolDone: goEo
NEVER
EfrolDone CouLdl shouLal He!e
GooalDo[e: goto
shouLal be rnatsch, i rrE) to PloDer Enal
Enal
GooalDone
enit
The ifgoto macro in asmMacrois useful to people other than new PIC MCU assemblylanguageprogrammers.I shouldpoint out that the preprocessorin MPASM assemblerwill not recognizethe difference between variable labels and constant values.This is unfortunatebecauseyou will haveto modify this macroif you want to perfom a conditionaljump basedon the contentsof a variableand a constant.The background for the changesrequired to modify this macro to support constant valuescan be found in the "ConditionalExecution"exDerimentin Section8.
95X 6J
ts:r{ iU
@
tgx
abIes utith Experiment77-16-Bit ValuesA/ari Flddition,Subtraction,and Eomparison 0x01234would be displayedin memory as"3412," which requires you mentally to rearrange the bytes. is not requiredin the This mentalrearrangement MPLAB IDE simulator.You candisplay16-bitdata in MPLAB IDE by settingthe propertiesof the Watch window to 16-bitdata,in little endianor big endian formats. With the availability of the cblock directive, you can declarethesamel6-bitvariableas. I find that whenI am doing actualPIC microcontroller eight-bitvaluesare simplynot enough. applications, Sixteen-bitvariablesprovideyou with a significant amountof additionalprogrammingflexibility in a variety of differentareagincludingthe creationand processingof data.Programmingfor 16-bitvariablesis not beyondyour capabilitiesif you havebeenfollowing along.In fact,you will find that 16-bitvariablesare not that hard to work with, especiallyif you follow the rulesthat I set out in this section. When I first startedPIC MCU programming,the dfuectives that I will introduceto you in this experiment werenot availablein the Microchip assembler products.For example,to declarea 16-bitvariable,you would usethe equ directive: il.o
equ
0x20
i
iHi
equ
0x21
t
Decla!€ a 15 bit starting at aaltlress 0x20
variable
to declarea 16-bitvariableastwo eight-bitvariables. The declaration format sholvn in this snippet is known aslittk mdianbecausethe leastsignificantbytesis declaredat the lower-fileregister.This is the format usedin many 16-bitprocessors(e.9.,the Intel 8086), and I feel that it makesintuitive sense.Theproblem with this format comeswhenyou are usinga debugger to displayvariables;inthe debuggera numberlike
cbLock ir2 enilc
i
w $r.t.
0x20 -
"i"
iE
a 15 bit'
(2 Byte)
valiabl€
and the low addressbyte (in little endianformat) is accessed asthe variable,and the high addressbyte as + 1.To showhow thev are accessed. here variable the is an initializationstatement: movlrr' 0x123{ - ((0x123d / 0x0100) * 0x0100) novrdf i r i = 0x1234 novl$ 0x1234 / 0x0100 novwf i + 1
The first instructionof thesefour linesfinds the low eightbits of the constantvalueby doing an integer divideby eightbits (0x0100)and then multiplyingit againby eightbits.After the multiplication,the values lower than eightbits will all be reset.Subtractingthis value from the original will retum the value of the lower eightbits.The upper eightbits are simplycalculatedby eightbits,or shiftedto the right by eightbits. Thesetwo calculationscould be built into defines.but Microchiphasprovidedthe HIGH and LOW directives,which perforrn the samecalculations.The four previousstatementsthen become: InovLw novwf
w
IJow 0x1234
r i = 0x1234
i
S e c t i o nN i n e A s s e m b l y L a n g u a g e R e s o u r c e R o u t i n e s
20L
ba; s-,1
fs rlJ
l-rj
$5 r:nl 6*t
{ }
tn 1_t,
movlw mov\rf
{l}
G} ',..{
-a d
.rl
i{ {$ qt (, Fl
r-l
{u
4J '*{ i{
a I
\s r-*
HIGM'.1234 i + 1
Understandinghow to declareand access16-bitvalues and variables is a good fraction of the work requiredto use16-bitvaluesin your assemblylanguageapplication.The remaining part is to understand how arithmetic operations pasqcarry,and borrow information from the low byte to the high byte of a variable.In this experiment'sprogram(asm16Bit.asm), I demonstratehow declarations,initializations, increments,decrements,addition, subtraction,and conditionaljumps are implemented. "es'l15Bit title 09€rations"
-
r\ t \
'-{ {, . F.{
Itaralwale NoteB ! PIC15E58{ rulrtriag at { UHz ilr Reset ia li€il tlirectly to Vcc Pul Lup/ Programl.ag Heralwale
STATUS, C
i a c f
i + 1 , w
adawf
j+1,w
movwf
D€slinalion
movf
j,
auborf n o v f btfEs
D€gtinatioD, j + f . w
iDeEtination=i+j
Incrom€at Eigh Bt t€ if, R€EuIt of t Lo$ B!.ts€ Atltl ie > 0x0Fl' (Carry Set) wlltten for low ; Not€: a|lal uial-Rang€ r PIC UCUg so no rradlallet i
1tr
+ 1
w
r Deslinalion Deatsination
STAEUS, C
,
j
rd
i
sultrf
Destinalion
+ 1,
sulrwf novf btf6a l n c f autwf btfss golo
j, w i+1,rt sTATItg, c i + 1 , n j+1,!t STATUS, C Errolloop
Sinuleto! vl'a
+ 1.
IJISE R=DEC INCII'DE'rp15f
ElrolLooD:
j:2, Destiaatlon:2 ENDC
Declaration t vari.abl€ (2 Byle) r 16 Bil Couater
PAGE 0 i R€quir€dl TCD2
fo:. l.tPI|IB
"i" with r rnitialize 123{5 al€cinal t High Byte Fl.fat
movlw riovwf lrovlw lrovwf
IIIGE 1234 i + 1 L@l L23{ i
llovlw movwf movlw nowf
IIIGII 56789 j + 1 rJow 56?89 j
,
lncfsz d e c f
i, f i + 1 , f
i i
i n c f
i + 1 , f
t
blfsc
STATUS, Z
alecf flecf
202
i+1,f t.
f
(i
,
if
i
i is ifump
> j)
hitialize
"J.
ui" lDcr€ment Incremen! High Byte if Reault of Increnenl ing lJolr Byle
rifl fiecreneat D€c!€neat Eigh ByEe if IJow Btte is equal to r initsielly i i
goto
E!!or
Less than j, Tak6rr, Error
if
Everytshing
Codrpare ODeration diftn't lrork cofiectly
i
684. incn gtolo
ors noD
(Lo!t If Cerry R€set By!€ Negative) Tak€ ole ltore Alray from th€ High Byte f
t Finish€d, okay
CBIToCK0x20
= - j
f
!A[ke Prealko 0{.09.21
lj.1
'*
blfac
lacf
l.{
s
i, w J, w D€stination i+1,w
15 Bit
D€alonalrate 15 Bit Varieble Declaration, Initializatioo, additio[, Eublraction, incr€rr€nting alecren€nt ing anat cod[)erisod operations.
! f*
Ddlotrstlat€
movf atLlwf rnofitrf movf
ErrorlooD
€Dd
Note that the conditionaljump hasa bit-skip instruction that follows the samerules as the eight-bit conditionaljump codepresentedin Section8.This meansthat the tablesusedto definewhich valuewill be subtracted(andfrom where),and the tablesusedto define the flag state for the bit-skip instruction are exactlythe same.The conditionaljumpcodefor a valuebeingequalor not equalto zero is a specialcase that canbe testedby simply ORing eachof the two bytesof a 16-bitvariabletogetherand checkingthe zero flap:. inovf
Lab€I,
ct + 1,
,
iolrrf
Lab€I
blf,ac gotso
STATUS, Z gL:rteenBilzero
w
i
i
OR Low Btrte rrith Eigh Bytse (bolb Z SaE if, reEult lrytea ) ia zero iturll) value
ia sixteen ia zero
bit
This exampleillustrates that although the different operationspresentedin asml6Bit are usefuland can usuallybe usedwithout modification,somecasesexist wherebetter codecanbe producedwithout the same number of instructions.For exarnple,think about how to implementaddingan eight-bitvalueto a 16-bit
l , e 3 P I C @l l C U E x p e r i m e n t s f o n t h e E v i l
6enius
variableand what would be changedfrom the previous codeto do so, When you have worked through the different operationslistedin asm16Bit,you shouldhavea good idea how to performbitwiseoperations. You shouldalso recognizethat the bitwiseoperationsare somewhat simplerthan additionand subtractionoperations
becauseyou do not haveto carry or bonow. Multiplication and division are somewhatdifferent than bitwiseoperationsor additionand subtraction,but you shouldbe ableto comeup with someideason how they canbe implemented.(Section12will examinedifferent methodsof multiplicationand divisionthat can be usedasa basisof these16-bitoperations.)
78-Universal DelagMacro Experiment
fsl {lt L'
6$ rlt
:'il
t''i' movlr movlrf alocfaz g o t o
When I discussed delaysin C programming,I probably seemedpretty nonchalantaboutit; basicdelayscould be implementedusingfor loops,and more precise delaysusingbuilt-in timersand critical signalswould be output from customhardwarebuilt into the PIC MCU. For C programmingand relativelyfeature-rich deviceslike the PIC16F684,this is a pretty good attitude to take.But whenyou are working with simpler PIC microcontrollers, which do not havemultiple timersor CCP rnodules,you are goingto haveto programa delayyoursell Programmingdelaysin PIC MCU canbe donesurprisinglyefficientlyasthe macro in this experimentdemonstrates. The PIC's clockis dividedinto four parts,eachof whichprovidesa differentfunctionin the instruction rycle.By knowing the clockspeed,you can easily period asthe reciprocalof derivethe instruction-cycle the PIC MCU's clockspeeddividedby four. Every instruction,exceptthe onesthat changethe program counterexecutein one instructioncycle,and this knowledgecan be usedto createsimpledelays.As you might expectthe nop instructioncanbe usedto delay one instructioncycleand the following instruction: goto
$+1
r Delay tswo iaBtruction cycles
will delaytwo instructioncyclesusingonly one instruction. If you needto delaymore instructioncycles,you canusea smallloon like this one:
i i t
Loatl
Countser
Declenent Loop Back
oremmino
,i
''
the count€r to count€r
Eachloop executesin three cycles,and a maximum of 769instructioncyclescanbe delayedusingthis method.Note that I am usingthe relativeaddressfor looping:Multiple delayloopscan quickly run out of your list of stocklabelslike BitDelayloop, and you'll end up with labelslike BitDelayloopT.Theseare not recommendedbecausethe loopsare probablycopied and pastedfrom other partsof the program,andyou may not alwaysrememberto updateall the label references.A jump to an incorrectlabel can be very difficult to seein a program.By avoidingtheir usein delay loops,you will eliminatea possiblesourcefor pro-
i,i" aa:a
*
:.n
crrnrc
For longerdelayqyou will probablyseethe needfor a 16-bitcounterand might want to usea loop like this one: rnovlw morwrf movlw novwf alecfsz goEo al€cfsz goto
HIGH Count Dlay + 1 LOW Courlt Dlay D1ay, f t-1 Dlay + 1, f S-3
r lJoaal 15 Bil
Counte!
* :l-.'i
Decrement
r Decr€menu t I,ooI) Back By!e
IJow Byte Bigh Byte to Low
{:i3
This codeworkswell, but it is extremelydifficult to comeup with a 16-bitvaluethat will delaya specified numberof cycles.I usethis codeto give me a quickand-dirtyapproximate200ms delayby resettingthe 16-bitDlay variablebeforeenteringthe loop:It's fast, easyto code,and doesn'trequireany thinking on my part. The following codeis the recornmendedway to use a 16-bitdelaycounter: novko monwf movlw
5ection Nine
Cyclea Dlay f Dlay, $ - 1
EIGE
(count
DIay row (Count
+ 255)
r
Loafl
15 Bits
+ 256)
A s s e m b l y L a n g u a g eR es o u r c e R o u t i n e s
203
!.;}i,
i!!
{r ;t
a;
aatal].w
-1
t
Decldment Byt.e
btfsc a€cfsz
sTATus, z Dlay, f
,
Decremen! High ByUe IJooD Back
goto S-3
.H t t rlt
br
This codehasa constantloop delayof five instruction cyclesand requires one fewer instruction and file registerthan the more obvioussolution.The 256is addedto the cycle count to ensurethe correct number of loops(otherwise,if the high byte of cyclesis zero, the codewill loop 255extra times,and whenit is not zero,it will loop one time lessthan you want it to). I shouldpoint out that the lastpassthough the loop executesin four cycles,and with the three overhead cyclesbefore the loop, the cycle delay can be written out asthe followingsimpleformula: Cycl.eaDe1ay
&,1
{tl
&q G} L'
! ,
P-
=
(Counl
* 5)
+ 2
In the program asmDlay,I have taken advantageof this delay and the one- and two-instruction-cycle delaysshown previously to create a macro that providesa precisedelayto a specifiedcyclecount.In the program, I have listed the macro and put in a number of teststo make surethat it executesfor the specified number of cycles.The nops after eachmacro invocation are usedto set breakpoints before and after in order to time the code'sexecutionusingMPLAB IDE'S Stopwatchto test the operationof the macro. tit.I€
.d
i
lJolt
"aamDlay
-
Creatse
a ltnivelsa1
The nDlay'r rnaclo Ln lhis loutine t dlelays ranglng fron 1 to 1.000,000 cycl€a. r Haralware Notes: r PIC15A584 runrring at { MHz in t ReE€t ia tied alirectly lo Vcc i Pullup/PlogrEll[ling llalibrare i r ,
Delay
r3i1l
Droviale
Slmulato! via
l4yke Prealko 04.09.22
r 1
$,,.
,"{ IJ
\t
P.{
X
sd
_coNFIG _FCI{EN_OFF & IESO_OFF & _BOD_OFF & _CPD_OFF & _CP_OFF & _!,ICLRE_ON & _PWR!!E_ON & & _rNTosclo _vrm_oFF CBIrOCK 0x20
t Varialcle Declalation 24 Bit r Requilea (w/ WREG) Count.e!
D1a]rya1u€:2 ENDC Dlay Dlacro CycL€s variable C'yclesl,eft varlaltle largeNum = CycleE CycleslJefl locaL IJongloop
204
i
r Can't Hanall€ > 93 SeconflE (e { !'lllz)
> 0*0{FFFF00
Cycles
"R€quireal error Delay is longer than rDlay, !{acro caa suDDort,l 6ndif if Cyclea > 327581 lJoop? t Ne€dl Large IJargelnrm = cycfe6l€ft / 327 6A! novlw IJarg€Iilum + 2 novwf DLat4lalue Number of t Calculate t oopa LouglooD I t R€DeaE for Each IJoop D1at4ra1u6 + 1 clrf t Do Ma:rimrm Poasible IJoo9 Coun! clrf Dlayvalue dlecf Dlayvalue, f blfsc z s!!a!!us, tlecfsz Dlayvalue + 1, f goto 9-3 dlecfaz Dla]^lalua + 2, f , ReD€at IJooD goto Longloop - ( (IJarge!tum * 327581) + qlcleal,ef,t = Cycleal€ft 1+(LargeNul[*3)) ontlif r Neeal Irarg€ lJoolt if eyclea > 1{ a IJooD be r WilI required? - 3) / 5) + 256) rovllr IIIGH ( ( (Cycle6lefE novwf + 1 Dlat^Ialue - 3)/ 5) + 256) novhr l,ow ( ( (Cyclesl,eft nonrdf Dlay'Va1ue tlecf Dlayvalue, f t 5 C]'cle Conslanl D€Iay tooD btfac STATUS, z + 1, f, alecfsz Dlat4ta1ue goto $-3 - (3 + (5 * ((Cyclesl€ft = Cl'cleaI,eft CycLeglef!
- 3)/ s))) e|talif vhiLe
C'yclesl.efl
goto Cyclealef,l if
; >= 2 t
$+1 = Cyclealeft
Cycl€slefl
== 1
Fini8hed lrith I,ooD Cotle Pltt- in 2 hatruction cyclo D€Iay6 - 2
i
Put ia tslr€ IJast Requileal Cycle
nop €ntlif €ndn
LIST R=DEC INCIjTDE rD16f 68{. inc"
{t
lf
PAGE olg no9
0 r Requireil
Dlatz nop
3
r shoulal
DIay nop
4{
r Dolay
for be goto
4{
t
DIay no9
r Delay
0.1s
Dlay 5000000 noD
t Delay
5a
Dlay
t Delay
50s
50000000
K€eD Tlack of Rdlalnlng C?clea
1 na De1ay
; Finish€it. Okay
Eve4.thiDg
ead
l , e 3 P I C @l ' l C UE x o e r i m e n t s f o n t h e E v i l
& nop
CycL€a
Dlay 1000 noD 100000
!@LAB ICD2
Genius
I would considerthis macro to be a combinationof If you wereto read showboatingand overachieving. throughthe application,you would seethat it is limited to 83 million cycles(83 secondsin a PIC MCU running at 4 MHz), andit providesaccuratedelaysto the instruction cycle.This accuracyis usually required for long delays,but for short delays,the accuracythis macroprovidesis not required.You might want to cut the macro down for your own use and avoid the initial loop, which is required for delayslon ger than 327,681. cycles(a third of a secondwhenrunning at 4 MHz).
If you comparethis applicationto othersin the book that are designedto run only in the MPLAB IDE simulator,you might think that my inclusionof the _CONFIG directiveis an oversight.Generallyit's not requiredin the simulator.However,in this casethe _CONFIG directiveis required.In the testingof the simulated delaysthat are longerthan 2.9seconds, PIC MCU would resetitself due to the Watchdog Timer resettingthe processor.Toavoidthis problem,I addedthe standard-CONFIG statementto make surethe WatchdosTimer is disabled.
133 :r!::
:,i,, tr:
il: . ,.n
ExFeriment79-High-Level Programmingin Fssembler andwould producethe following statements: ,l
tbsf novf tbef IbEf rnovwf tbcf
STATUS, RP01 i, w STATUS. RP0l STATUS, RPOI j sTATus, RP0l
: . f.-.1 !_-
for the macro invocation: ASSIGN J,
When I first startedworking after university,I waspart of a team developinga high-performance functional testerfor electroniccircuits.One of the taskswe had wasto comeup with a programminglanguagefor the tester,and I havealwaysbeenintriguedby the solution that waschosen.Ratherthan comeup with a custom compilerfor the programminglanguage,a standard compilerwasselectedandits macroprocessorwould be usedto convertprogrammingstatementsinto the data requiredby the tester.Tosomeextent,this effort wassuccessful asit did producedata,unfortunatelythe compiler'smacroprocessorcould not prodtce enough of it. Much of the data wasin the form of tables,and the maximumtable sizethe supportedby the macro processorwas32 KB. So far in this section,Ihavegiven you a macrofor conditionalexecution(or if) statementsand a macrofor precisiondelays.And, I wanted to seeif I couldcomeup with a macrothat would support assignment statements, becausewith sucha macro,I felt I couldclaim that I had developeda highlevel languagethat ran under the MPLAB IDE assembler. Unfortunately,I couldn'tdo it in ore macro.It requiredtwo.Thefirst macro,ASSIG\ wasusedto assignthe contentsof a variableor a constant(literal) valueinto a variable.Its format was: ASSIGN DeB!,
Equalsign,
alTtt)e,
SectionNine
Soulc€
or
:iiiu
novlw tbsf novwf Ibcf
47 STATUS. RP01 i sTATus, RPol
for the macroinvocation: ASSIGN
i.
=,
n.t.
47
The settingand resettingof the RPObit of STATUS is dependanton the positionof the variables.I could haveoptimizedthe macroto eliminateone set of bcf/bsfstatementsif both variableswerein bank 1,but I felt this wasgood enough.The blank ( ) or period (.) dTypeparameterbeforethe sourcemacroparameter indicateswhetherthe sourceis a variableor a literal. Thereis no way the macroprocessorcan determine which is which. I originallywantedthe ASSIGN macroto be ableto handlenot only straightassignment statementsto vari ables,but alsotwo-parameteroperations(like add or subtract).Unfortunately,I wasn'tableto discovera methodto determinewhetheror not a parameter waspresentand,in any case,if any parameterswere missingthe macroprocessorwould flag an error.So,I addedthe secondmacro:
A ss e m bI y L a n g u ag e R e s o u rc e R o u t i n e s
205
.:.tLr.
l -.i
OPERjATE Dest, EquaLSigm, alTtrpe2, Soulc€2
alTl.pe1,
Sourcel.
Ope!,
and would produce statements like: movl$ lbsf Bubwf tbcf tbsf movwf tbcf
47 STATus, RPol j, w sTATus, RPol sTATus. RPol i STATUS, RPol
for the macro invocation: OPERATE i.
"
-,
",
j,
-.
n.n,
47
The OPERATE macroputs in the secondparameter wasfirst to load WREG with the subtractorif the subtractionoperationis selected. To test the ASSIGN and OPERATE macros,I created asmAssign.asm: "aslBssign ti!1e Assignment llacro "
-
Experiment
with
an
This Drogran tl€monslralea hosr an assigfirent Inacro f,or the PIC MCU coulal be createal. Earahrare Notes: PIC16E68{ running
at
4 r!trIz in
Sinulator
Myke Predlko 04.09 .24 LIST R=DEC INCLUDE ip16f584.
cBr,ocK 0x20
inc" r variable
Declaration
ENDC ASSIGN macro D€st, Equalsign. variabl€ _aai = 7, _aa) aaj Equalsign _aai (_aai != _aai ) if rrNo Equala ('=,) elror in else r (dr!|I)e != ".") it , ( Source > 0x7F) if bsf, STATUS, RPo , endif movf Source & 0x7!'. nr ( source > 0x7F) if bcf, STAAUS, RPo r endif r movlw Sourc€ endif (Dest > 0x7F) if bsf stATus, RPo t enalif mowqrf D€st & 0x7E (Des! > 0x7E) if bcf STATUS, RPo t endlif endif
206
flTl.pe,
Souree
Assignnent Slalement Equals Present variabl"e Direc! Aank
1 Variable
Bank
1 Variable
Liceral
Bank
1 VariabLe
Banh l
variable
OPERATE nacro Dest, Equalsigm, alBrpel, Sourcel, Oper, ilTtpe2, Source2 = 7, variable aaj ,aai _aaj Equalsisn -aai (_aai != ,aai ) if "No Equal8 ('=,) elror in A6signment Statement t Equala P!€sent " . " ) (dr5/pe2 != if Dilect r variable (Source2 > 0x7E) if bsf STATUS, RPo r Bank 1 ValiabLe enali f nowf Souree2 & 0x7F, w (source2 > 0x7F) if bcf STATUS. RPo r Bank 1 Valiabl"e endif elae r Lit€ra] movlw Soulce2 enalif (alTtrpel != n.r) if Dilect t variabLe ( sourcel > 0x7F) if bsf STATUS, RPo t Bank 1 variable €nalif ((1 oper 1) == 2) if Operato! r Aaldlilion addwf, Sourcel & 0x7F, !r' eLse ((47 oper 25\ == 22') ; sublraction if Operator subwf, Sourcel 1' & oxtF, etse ((3 Oper 2) == 3) if t OR Operator ionrf Sourcel & 0x7F, w elae ' AND op€rator ((3 Oper 2) == 2l if anahrf soulce1 & 0x7E, w ((3 ope! 2) -= !) ' xoR operator xorwf Sou!c61 & 0x7F. w else "Unknolen Operatorrr 6!!0r enalif €ntlif endtif entli f endif if, (Sourcel > 0x7F) bcf STAIIUS, RPo t Bank 1 variabl€ endif el"se t Litelal ((1 oper 1) == 2) if Op€rator r Aalalition aaldlnr Sourcel else ((47 ope! 25) == 22) r subtraction if Operator subLw sourcel eLse ((3 ope! 2) == 3) if r oR operator iorlw soulce1 el6e ' .aND operator ((3 ope! 2l == 2\ if anallw Source]. else ((3 oI)€! 2, == r, i xoR OPerator if xorlw sourcel if
rrunknown Operatsor" error endif endif endif endif endif, endif, if, (Dest > 0x7F) baf STATUS, RPo t Bank endif
l , e l P I C @l l C l - JE x o e n i n e n t s f o r
1 variabl€
the Evil Genius
novwf Dest & ox?F (Deal > ox?F) bcf STATUS, RPo endif, endlif eadm
Prc15F584
t
ruDning
in
Prckit
1 stalter
kit
tql X
if,
t Ba.Dk 1 Varia.ble
i t
!'lyke
i
04.o9.28
Pledlko
b
r Reguireal rcD2 =' =, =,
ASSIGN i, ASSIGN 1, ASSIGI{ J,
for
UPIll|l
" "' j t.d, 47 tr n, TRISC
o P E R A T EI , = , " " , ) , + , O P E R A T Ei , = , " " , ) , & , O P E a A T Ei ' = , " " , ) ' - , OPERATE OPTIOII_REC, =, n
$
t
ry
FCIIEN OFF & -rESO_OFF e _BOD_OFF & collFrc CPD OEF & CP OFF & MCLRE-ON & _P!|RTE_ON & _lsDn_oFF & TNTOSCTO
cBrocK ox2o
Declaralion
i variable
".", 47 ".", 47 ".n' 47 tI OPIION_REC,
Fiuishetl,
Everything
d (*
2{ Bit r Dlay Requirea (w/ WREG) Counter
Dlayvalue:2
}J. ;-a 5
fD
t, J ENIrc
&,
..n,
AggIGll nacro Deat, Equalslga, ASSIGN necro sroulce ttot rr
OPEIIAIIErracro Dest, goto
t9
I.IST R=DEC INCI,UDE "p16f584.inc"
PAGE
Okay
ODer, tlTtzge2, oPERAIEE t;
ilFtzpe, ahown
Equalsign,
Source
{
ttTyDel,
gourcel,
\S
Source2 not
gholoa
ea(t DLay llacfo
When you test this application in the simulator, you are going to discover it is extremely difficult to follow the progress ofthe code;execution will bounce between the macro invocations and the lines inside the code.You might want to look at the Disassembly Listing, but common statements are listed one after the
other in the macro definitiong making the code even more difficult to follow. Your best resourcefor seeins how the macrosproducethe necessary codeis in the sourcecodelisting,asmAssign.lst, which providesthe insertedmacrosand indicatorsfor activestatements. Unfortunately,the MPLAB IDE simulatordoesnot stepthroughthe listingfile. From my perspective, this inability to simulate effectively the application is the biggest drawback to
Cl.cL€a
Dlav tnacro Eource not Ehoffn
;t
onceper secondand is written injust the ASSIGN, OPEI{ATE, Dlay, and ifgoto macros (the body of^ which I have deleted from the folloritititJ,iiJl,
l-,,
PAGE ors
€ Fd
o
nor)
t R€quir€tt ICD2
assreN poRTl, =, PoRrA' =. 1::I9I ff:]:il ff:;y'=;' AssreNrRrsa, =,
for
n.s, 0 i hirialize ""' oxrr
!!Pr.At
variableg
r R€lurn trele when Done
rJoop:
"o*ro,toT]1Y,",1'?."ii""u
ifsoto i, ==, j, setDo Assrc!{ PoRrA' =' ""' 0 o""o "3i13,
assrcN poR![A, soto
rJooD
t Turn off the LED
<< {)
r Ttrrn oN th€ rJED ' R€peat
eE. titLe
'a6ro[E].asb
-
FLash
DO usinc
rlaclosn t
Hiah
trevel
dlenonstratee how the Eish rever :*-::::^::"n'"lilacros ca! be use.r to FraEh the Prckiys Do i rrED. I
aardware Notes,
5 e c t i o nN i n e
h
ry
8-1
fn l'"t 0,
After a lew moments of study.you should be able to understand what is happening in the application code. However, if the appticiilon code dio not execute as expected when it is programmed into a PIC MCU.I would think it would be a major effort to find the problem in the program logic or the macro code.
Assembly Language Resounce Routines
!-{
4 &
,,. ;;' ,t n.n, b,001111,
ASSIGN J,
writingcodewitfthesemacros.A;;ondaryconcernis 3}|{o|:tl:t=,,,,,
the possible difficulty in reading what the source code is doing from the macro invocations.To illustrate what I mean,I created asmMFlash.asm,which flashes D0
H
ifgoro !{acro varr., conp, va!2, DeEt ir ifgolo nracro soulce nots Ehovn
2O7
F{
H F 1". |1 .X sd
Pq
ExFeriment 80-lmplementingFlead-Onlg Hrrags
Ft H
New Program
Counter Address (Goto/Call)
Fr
PC lncrement Pfogram l\4emory Read Address
F {
8-Elgment Program Counter Stack
It
L,'
d
'tl l-al
hr
la.{ I-
t I I
w +; \u . r.{
l-({
Read-only arrays are useful and effective solutions to a number of different programming problems.Typical applicationsrangefrom storingASCIIZ strings employedasusermessages in a format that is reasonably spaceefficient, to providing a translation table for different applications,and using a jump table to different locationsin an application.In a von Neumann processorarchitecture,a read-onlyarrayis normally implemented in program memory as a seriesof bytes that can be accessed by indirect addressing.The Harvard architectureof the PIC MCU doesnot lend itself to this simple solution, and more complex software is requiredto return read-onlyarraydata. To accesstabledatain the PIC MCU, you will have to perform what is known as a computedgoto whercin the processorwill calculatethe addresswherethe data is locatedandwrite this addressinto the program counter.If you rememberthat the PIC16F684has 2,048instructions(11 bits wide) and the databuswidth is eightbits,you may be wonderinghow this is accomplished. In the PIC16F684(and all the other mid-rangePIC microcontrollers), two registerscan be written to that allow programaccessto the processor's program counter.Thefirst registeris calledPCL and is actually the lower eight bits of the program counter (seeFigure 9-3).The upperthree bits in the PIC16F684(and up to five bits in PIC MCUs with a full 8k of programmemory) of the programcounterare loadedfrom the fivebit PCLATH register,the contents of which are wdtten into the programcounterany time PCL is updated.Thismeansthat for computedgotos,the addressspaceis effectivelybroken up into 256-instruction addressblocks.UnfortunatelyMicrochiphasnot givethis block of instructionaddresses a label,so you will seeawkwardtermslike "256-instructionaddress block."To implementa computedgoto,you mustfirst load PCLATH with the appropriate 256-instruction addressblock valueand then write the lower eisht bits of the addressto PCL.
208
Full program counter
Figure 9-3
Although it seemsthat I've wanderedoff topic a bit, I want to note that performing the computed gotos is half the problem of implementing a read-only array. The secondhalf of the problem is to load the appropriate array value.Fortunately,the designersof the PIC microcontroller have provided you with the retlw instruction,which providesa sirnplemethodof retuming a read-onlyarrayelementin WREG To take advantageof the retlw instruction,a subroutinewith a computedgoto is called.Ifyou look at differentPIC MCU applications,you may seea read-only array implementedin the samemannerasthe following subroutine, which returns the ASCII character for the nybblein WREG: Hera'lable: aaLlwf retlw relLw ll!etllr letllr relllr relllr relllr !6t1!t rethr relllr relllr retllr retllr relllr lethr !e!hr
r conv€ft cha! PC!, r0, t1, \2t .3' \4' '5' '6'
rwbbLe
ia
I{REG to
H€x
f
'8' '9' rA' rB' 'C' 'D' 'E' \F,
There are two issueswith this function.The first is the useof 16 retlw instructions. To easethe workload of creating read-only arrayg Microchip added the dt directiveto the languageto passits parametersto an appropriate number of retlw instructions The dt directive'sparameterscanbe ASCII stringsset in double
l , e 3 P I C @l l C U E x p e r i m e n t s f o r
the EviI
6enius
quoteqASCII characterssetin singlequoteqor numericvalues.Different data typescanbe concatenated,or linked,togetherusingcommas.The nybbleto ASCII conversionsubroutinecould be rewritten as follows:
INCLITDE "D16f58{.
inc"
?s1 6!d
variablea CBLOCK 0x20 St'!insr 18 t
r9 tfi
EIIDC
. i HexTable:
ailtlwf d!
r Converts char
Nybble
in
WREG to
PC!, f " 0 1 2 3 4 5 6 7 8 " ,0 x 0 3 9 , ' A , ,
ltej{
\B',
rnovlw
For rnorecomplexapplications, theseconditionscan be very difficult to meet,especiallyif multiple readonly arraysare built into the application.For these cases, a more generalread-onlyarraysubroutineis required.In this experiment'sapplication, asmTable.asm, I haveput in what I feel is the best read-onlyarraysubroutine.This subroutinesavesthe indexvaluein PCLATH, loadsPCLATH with the 256inshuctionaddressblock of the start of the table,and swapsthis value(in WREG) with the indexvaluein PCLATH. I must point out that PCLATH is only five bits,so the maximumnumberof tableentdesthat can usethis codeis 32.If you want more,you will haveto usecodelike that presentedin the following scheme. The indexvalueis then addedto the lower eightbits of the addressof the tablestart (and PCLATH is incremented if this value is greater than 0x0FF) and finally loadedinto PCL. - A R€atl Only
t i i
lhiF apDlicatLon copl.€s f:.dr a r€ail olrly tabl€ a variablo a!!ay.
t i , i i
Haltbrale Not€s: PIC15!58{ runainq at { MHz ia R€se! is li€d ilir€ct'ly lo Vcc PulluD/Progranmins Harfkfare
r , t
wilh
tsbe ASCIIZ stsling a|tal puts lt into
ltyke Pr€alko 0{.09. 17 or"t
Atray
*=o""
gimulalor via
ti..C
rc,,
The other problemwith the read-onlyarrayis that it will work only if threeconditionsare met: (1) the table datamustfollow the "addw{ PCL, f" instruction (whichaddsthe contentsof WREG to PCL and stores the resultbackin PCL); (2) the tablemust be totally within the first 256-instructionaddressblock (within the addressrangeof 0x0000to 0x00FF);and (3) the PCLATH register (which is loaded when PCL has the contentsof WREG addedto it) must be zero and not changedanywhereelsein the program.For many simple applicationswritten by beginners,theseconditions are not unreasonable.
"asnTalcle Eltle ItteBEage tr
'.r "
aop
a
movwf clrf IJooD:
String
t-r1
Point !o lhe Deatination Alray
]-t
EgR i LooD I'or charac!€r Gets Next Eldnetrt
novf
i.
w
caLL novwf
ReadlTabl€ INDF
incf
FsR,
iorlw btfss goto
0 STAlr['S, Loop
goto
$
Each to t{ull Allay
**
sto!€ Chafactse! ia valiabLe A!!ay Point !o l{ext R€aa Arlay Elem€nl Poiat !o llexts valiabLe Alray El€ment == 0? chalacter
f
t
Z t*:!r: Finisheit,
lool)
l..r ,11
subroutines i Readlable: movwf PCLATH novllr high ReatlTable xor\df
PCLATE,
f
xorwf
PCIATE,
w
xolwf
PCIATE,
f
aaLlhr
1ow _ReaalTalcle
blfsc incf,
STAgttS, C PCI,AEH, f
novwf
PCI.
S_$rap Conlenls of, PCI.ATH & WREG PCLATH = PCLATH ^ WREG waEG = WBEG ^ (PCI,TTH ^ WREG) WREG = PCIATH PCI|ATfl = PCLATE ^ (PCIJATII ^ WREG) PCIATH = WREG calculale Table offs6t > 256? Yes, Pot nt lo N€rrt 255 Atldr€sa BLock ituJqr to TabLe Elenent Readt only Table Sentsence Subj ects Cryptic verb
_ReattEabl€: tll alts alts dtr tll d r retLw retlw r€t1ra retLw retlw retlw
nMyk€ tr ra' + rE, 29*4 tw' - 4 L 6 , 2 0x77 0x5F 0x72 0x5D oxt 3 0
-
:i..:t:
Save Offset PCLATH Calculate
rA,
i
!".*
f.a i*r " ifl 'l.;.j sl !.!:
l'i
F } i,"*i
Noun
h'g
rR t Zero At St!iug
Endl of
&-d
n;
enal
SectionNine
:
A s s e m 1b y L a n g u a g e R e s ou r c e R o u t i n e s
es 209
When you read through and test asmTable,you will seethat it loads a file register array with the contents of the read-onlyarray.And, if you displaythe file registers,you will seea messagethat hasbeen(simplistically) encryptedin the read-onlyanay. As an exercise, I would suggestthat you try to come up with your own subroutine code that implements the generalread-onlyarray (i.e.,it canbe any'lvhere in the PIC16F684's memory;it is greaterthan 32 bytes,and its contentscanstraddlea 256-instruction address block). When you try to come up with your own routine,rememberthat you havea numberof directiveq suchasthe if directivethat can be usedasI havein the followins routine:
E!I6rdtabl6: clrf ((
if bBf
i PCIJATII i EenTable & 0x0100) PCLATH, 0
Relurn llex ASCII for Lslvbbl€ in WIIEG != 0)
Char
enalif (( Iler(lable & 0x0200) ! = 0 ) if baf PCLAAH, 1 endtf ( (_Ir$c!able if & 0x0400) != 0) bsf PCITATH, 2 endif antllw 0x00F ; rtust want low€r { Bits adatln l,ow _H€xTabIe lhe Correct t Calculate
off6et btfsc STATUS, C iacf PCITATE. f noverf PCI. _Ile*Tablel '0 L23{ 5578 gABCDEF"
Experiment 8l-Bata Stacks cationsandprinter control,and network-enabled printersallow datato be sentdirectlywithout the need of the printer switchand data spooler.But the data storagemethodsusedin this applicationare important to know as they will be required from time to time in your applications.
# /l
frt
u"t d
l\l
3 I
c-d
,&r *'{
,it
One of the first applications I designedfor microcontrollerswasa Multi-PC printer switchand data spooler.Thisdevicewould monitor the printer ports of multiple PCs,and when one startedsendingprint commandsto a printer,the devicewould passthem along to the printer.And if therewere other PCssending datato the printer later,their datawould be held in a memorybuffer until the first PC had finishedsending data to the printer.When the first PC had finished(I waited15secondswithout a new charactercomingin), the circuitwould then assignone and then passthe data of the other PC'sdata to the printer.Along with savingdatafrom other PCs,the spoolingfunction allowedthe PCsto passdatato the device,which "appeared"to be a printer,at full speed.Real directconnectprintershold the PC from sendingmore data until it hasfinishedthe operationit hasbeengiven. Thesefunctions allowed all the PCs connectedto the printer to work at full speedand have a minimal programdelaywhensendingdata to the printer.Today, modernmultitaskingoperatingsystemssuchasWindowsand Linux provide separateprocesses for appli-
2L0
Thereare two basicmethodsof storingdata temporarily. The first is known as the s/ack and can be modeledlike the stackof papersin an executive'sinbasket.When datais storedon the stack,other pieces can be stored on top of it (seeFigure 9-4) with the interestingresultthat the first pieceof data on the stack will alwaysbe the last piece removed from the stack.For this reason,stacksare knowr aslnstin frrst oLl (LIFO) memory To demonstratethe operationof the stack,I created asmStack.asm, in which I haveset up a 16-bytedata arrayin bank 1 for the storageof data.Tostoreand retrievedata on the stack,I createdthe Pushsubroutine:
/-------\ /
"Stack"
Fieure9-q
l , a 3 P I C o I ' l C UE x o e r i m e n t s f o r
Stack
the Evil
Genius
Outgoing
ht |
trstackn affay // Put Deta i! | / Al E1€dl€n! nstackPtrn
Pueh(Data)
(StackPtr == SlackEop) leturn ctv€rFlowE:afoli Pointer at €ndl of // The stack els6 // if
stack 5ti11
SDace Left
t = Datai SlacklstackPlrl = StackPtr + 1, SlackPtr retuln //
]
Save Data Poidt to Nexts E1€n6at
// //
PuEhcoodl,
€nil
Puah
And the Pop subroutine, which operates as follows: int
Po9()
//
Relurrl Data the gtack
a!
lhe
Top of
{ - 1) = stackBolton) ( (stackPtr r€tum ltnal€rrlowErroli Nothtng ltr gtack ela€ // "PoD' alatsa off Stack t stackPtr = stackPlr - 1r // ltov€ to r,ast gtack Eleneat
if //
r€luln
StackIStackPtrl
,rop
#*:
3;i.
novlr
20
novrdf, cllf
i i
PuahlJoop: novf call caLl incf tl€cfsz
goto
//
I feelthatlimit checking is important.evenifit is ignoredby thecallingcode;itensures thatno memory
j, !t T€Jr1€Read Push j, f i, f
outside the allocated stack array area is accessed. To simplify the limit testing in asmstack.asm,I took advantageof the bit a;ngement of a t6-iit uutter
golo
$
,
Finiahetl,
i
Push Value
t subroutineg Puah. bsf, STATUS, C
leturn
"olo.rr,
4
il}l"", rs", r
"
oroo
dl6cf
FgR, r
whenyou simulateasmstack.asm.
novf bcf
INDF, w STATUS, C
Eabl€Reeil movwf movlw novwf novf aalfllrd btfac lncf nofirf Table:
I -T€dE) HIGH ,Tabl€ PCIATE w _T€rrp, r,ow _Table STATITS, C PCIATII, f PCL
i t r
program rhis slack coulil Irqrl€oenteal
t r
llarahcare Not€a: PIC16F684 ruELng
i , ,
lryk€ Pr€tlko 04.L2.29
tl€monsllat€s be La the Prc
at
Si
holt
ple
Mcu.
{ MEz in
simulator
t Variable
_Tellp E![DC
olg
0
S e c t i o nN i n e
p
(-f
on glack
El€rlen!
Loop
onlo
have t A].leafly Elem€nta? t 16 El€m€nta, Error
,
Pop ToD of
Forever
Stack
16
Declaratiorr
OO
I
u
g, rF p,
Retuln
Q
Stack
i Notshhs nlt€r€?
rt g,
i Y€s,
ta
Return
Erlor
i Erse, Return toD Brrle
r Randlom Tab].e
r PORTA nnd IBISA Tabl€ valu€B
Bit
dt 47, 23, 33, 2, L90, 4t, 37, Ar, 42, 2r, 94, 74, 79 dr a, 6a, 54, 29, 37, 9!, t-0O
t IgT R=DEC INCIJTTDEn915f 58{. inctr CBLOCK 0x20
Va1ue
slack
F.
3 o
value
gtacki
a 15-Eleme!t
o
P
It also means that data can be lost, as you will observe
Denonstlate
gee what,s
r PoI) rop
a one,then I know I havegoneoutsidethe stackarray and can stop trying to accessinvalid memory locations.
-
t Gloto Next
Pop i, f, PoDLoop
srArus' c :::,, ollii"rr"t"tu"' "
"agnslack
llanalon
i
rsR, w
ti!1€
Get
r\ghTJooD
xonrf
with bit 4 ofthe addressalways being zero.If it is ever
i
Data onto gtack
20 i
Llj*, li"i-
X
Ft r Itah
FSR,
tql
t
leEuln
6nal PoD
!4PLAB ICD2
, stalt stack al 0x20 in Bank1
] )
f,or
novlw novflf PoDLoo9 ! call tlecf,az goto
blfBc
t
r Requi.r€al
6ad
When you run asmStack.asm and executethe Poploop, you will seethat the data is retrieved in oppositeorder in which it wasinput.This makesa stacka poor choicefor spoolingdata in the application mentioned at the start of this experiment.However, it
Assembly Language Resource Routines
2LL
}f U'
makesa stackan excellentchoicefor savingdatathat may be temporarilyoverwrittenand in needof retrievaloncethe operationthat overwrotethe data hasfinishedexecuting.Stacksare usedin the PIC MCU for savingthe programcounterwhen calling
The originalprograrncounteris saved subroutines. beforejumping to the subroutine.It is then retrieved when the subroutinehascompletedand the original programcountervalueis required
Experiment 82-Eircular Buffers Although I've drawnthe circularbuffer asa linked list,it can be easilyimplementedasa simplearray.For examDle. the Put functioncanbe modeledas: i,n
Put (Data)
int
Put Data Circular
//
Into th€ Buffer
t j.f ( ( (PutElement GetElenent) relurn
In this experiment,I will introduceyou to the circular buffer,which retrievesdatain the sameorder asit was written and is ideallysuitedfor the printer switchand buffer applicationI mentionedin the previousexperiment.
:-
.1
t , '
The circularbuffer consistsof a circular,singly linked list of data elements(seeFigure9-5).The buffer hastwo pointers,one pointingto the next location wheredata will be storedand one pointingto the next locationto be readfrom. If both the next storepointer andnext readpointer are pointingto the sameelement,the buffer is empty.Conversely, if the next store pointer is pointingto the elementjust pdor to the next read element,the buffer is full. Justa few instructions are reouiredto imDlementthesebasicrules.
==
+ 1) % Buffersize)
PutNexl + 1== (FuLL ) ReadNext the Dala El€menl / / Can Slore
Buffer!\rl1t
//
€lE6
t Buffe! [ PutElernent I = Datat = (I'utEl€menl + 1) PutElen€n! retuln Putcooali // fi I // End Put
)
e. Buffelsize,
And the Get functionis: int
Cet()
//
( int
the Next Buffef
Get uhe
value
in
T€dr!)t (GetELernent
if
r€tuln eLse
--= PutEl€nents)
Buf felEnutty, //
Elemenl
NoEhing
//
to
to
Retrieve
t T€trll) = Buffer
,1',,ti
Next Element )
j,t,.r.
Get lhe Eleneat = (GetE!.€ulent + 1) % Buffersizet GetElement relurn Tetngi // Retuln the ELenent // fi I // Enal cet lcetElement
],
//
To demonstratethe circularbuffer function.I createdasmCBuffer.asm, which usesthe same16-byte (0xA0 to data areathat wasusedby asmstack.asm OxAF).Thisallowedme to usethe sametrick to make surethat data outsidethe allocatedmemoryis not allocated(if bit 4 is set,the pointer is outsideof the circularbuffer).
i,.i
NextElement to Writeto
tit.le Buffert
"aEmCBuffer
t t ,
This proglam Circular Buffer coulal
i
Earahfar€
circuLa!
how a 16-ELement be Implement€dl
Figure 9-5
Circular buffer
212
t r e l P I C @l l ( U E x o e r i m e n t s f o n t h e E v i l
in
the
NoleE:
6enius
PIC MCU.
PIC15F684
running
at
4 UEz in
Simulato!
t novf
u!'k€ Pr€tlko 0r.12.29 TJIST R=DEC I N C T T T D En D 1 5 f 5 8 4 . i n c n CBIJOCK 0x20 _!!dE) _CBuf,f,€lPul, ENI'C
i
variable
Declaratiof
_CBuff€rG€!
0 Requireal tcD2
for
Stalt Buf,f,er in Bank 1
MPr.aB
al
0:{2 0
_CBufferPut _CBuff€rcet nrovlv lrofitrf clrf I\tIJooD 3 rnovf caLl cal,I incf tlecfaz golo movlw movnf GetlooD: caLl
r
nonwf xorwf baf blfac
FSR CBuffelPut, STAT['S, C STAT['S, z
movf incf bcf bcf,
INDF, w _CBuff,ercel, _CBuf,feleel, STATIIS, C
rc i
i|t
C.
thea
w
t4 X tn
t Nothing t Get the
h{
to Get Valu€
*.J.
f, 4
EF{
:U F"t
PAGE org no9
cBuffercet,
GeE Nex! value Buffer rF Put == Get, Notshtngl
20
dr 47, 23, 33, 2, 94, 74, 79 atr a, 64, 54, 29,
J
i
Put' Dala
i
G€E Rantldr
i
Goto
20 t
i
gee !l?rat,s
cet
i
Gel Next E].ement
j, w TableRead Put j, t i, f IttIJoo9
al€cfaz goto
i, f Getl.oop
goto
s
Next
t Finiaheal,
Into
auffer
value vaLue
on stack
Buffer
IJoop Eorever
subroutia€s Pul Value inlo cilcu1ar Buffe! movlrf movf movwf
_T€tq) CBuffelPut, FgR
aaltllrd andlvr
1 b'11101111,
r.olwf bsf, btfac
CBuffercet, STArsS, C STAtgS, Z
novf novlrf Lncf bcf bcf
w _Teq), IIIDE _cBuff€rht, _CBufferPlrl, STATI'S, C
TabIeReaal: novvrf _TerE) movhr AIGH ,Table movwf PCI|ATE movf Te!E), rd ailillw I,ow _Tab1e blfac STATgg, C incf PCIATE, f movwf PCIr _T6b1e:
w t Can,l bave Put i rf Itnreadl Dala Buffer t IIBEG haa VaIue
8ina1
== Gel in
eet
rt
i
No llore Space Slole Value
f t fncr€Erenl Pointe! 4 t Keep within Range i No Erlor
SectionNine
r Rarlalom Table
s*
Rr , PORTA andt TRISA Bit TabL€ valu€s 190. {{, 31, 43. 42, 2L, 37,
9L,
t I
1-OO
C J 5-i.
6ntl
you When you havesirnulatedasmStack.asm, shouldhavenoticedthat datais retrievedin exactlythe sameorder it wasplacedin the stack.You shouldalso havenoticedthat the maximumstorageof data in the circular buffer is one byte lessthan its total size.This canbe a concernto new programmerswho expectthe data structuresto storeeverythingavailableto the device,but in practicalterms,it really isn't a problem. The important considerationwhen using a circular buffer is that the averagerate of data removalmust be greaterthan the averagerate of datainsertion.For the printer switchand spoolercircuit,I found I had to increasethe sizeof the buffer to 256kilobytesof DRAM beforeI couldreasonablyexpectto avoid a conditionwherethe incomingdatawould fill the entire circular buffer. At 256 KB, the printer switch buffer could storeabout 100pagesof text,which wasusually more than threepeopleworking on PCscould generate beforethe printer finishedprinting.In most cases, it is not practicalto keepincreasingthe sizeof a circular buffer to meet the expandingneedsof an application; you will probablyhaveto put in somekind of"handshaking" to tell the sendingdevicethe circular buffer is full and enabledata sendingonly whenspaceis availablefor more data.
A s s e m b l y L a n g u ag e R e s o u rc e R o u t i n e s
2t3
[,4
t--t H IAJ
h& Hr fft Fx€
rn
Experiment83-Heading and [Jriting the EEPHOMOata Memorg
F\
rrovf
*-l
Addleaa,
lh€ AfLlleag r c€l to b6 Reaal
vr
STA!!I'S, RPO EEA.DR ^ 0x80 bsf novf
tlt
bcf
rr{ IU
et
FEr t4{ Fll
lei
L*{ $ tqJ
!
!
ar) ffi
Earlier in the book,I introducedyou to the PIC MCU's built-in EEPROM datamemory or in other words a number of bytes built from electrically erasableprogrammableread-onlymemoryandcan be usedfor data storagebetweenpower on or resetcycles of the PIC MCU Accessingthe EEPROM in assembler is a bit trickier than in C whereHT-Softhasprovided you with macrosthat will read andwrite the EEPROM for you.In this experiment,I will present you with the informationand codeyou needto access the EEPROM aswell asdemonstrateits operation usingthe sameapplication,but I'11do so in assembler, asI usedearlier. The EEPROM control hardwareis accessed by four registerslocatedin bank 1 of the PIC16F684. In other PIC MCUs, you will find these registerslocated in multiple banks,which makes the coding of the accesses more difficult.Two of the registersare usedfor passing a databyte at a specificEEPROM addressand are given the labels EEDAT and EEADR, respectively. Thereare two control registers:EECON1 (described in Table9-1)and EECON2,which is a key sequence register usedto ensurethat data is written correctly. Thesefour registersare usedto read and wdte the EEPROM datamemory. To perform an EEPROM rcad,the following instructionsequenceis used: Table9-1 EEC0NIFesister Bils
UJ F € r
Bits
Label
Unused(Return 0 when Read)
7:4 3
Function
WRERR
d!!
Setwhen write operationdid not complete coffectly write enablebit, set beforestart ofwrite operation
(f,"
2t4
WR
Wdte start bit,set to initiate wdte operation
RD
Read start bit
r g€l lhe aaltlr€Fa to Reatl
EECON1 ^ 0:.80, RD EEDAT ^ 0x80, !r
r Loatl in Byte dadalleaa n
at
STAEUS, RPo
Performing an EEPROM write is abit more involved asit requires the two-byte write to EECON2 to allow the wdte to take place.In the sequencebelow, notice that I store the addressin a temporary register at an addressthat is shadowedbetweenthe two banks before changingexecution to bank 1. novf
AaLlleaa,
!t
novwf
0x70
movf bsf noverf novwf
.tg Data, STATug, RFo EEDAT ^ 0t 80 0x070, w
novwf baf movf,
i
Get the Aaldresg lo be R€afl in t Store ahailowetl regisler
0x070 ia aame in Bank regiEter o/L EEA.DR ^ 0x80 t get the aaldreBg to lllile EECON1 ^ 0x80, WREN r gtsarl writso oDeratl.on EEDAT ^ 0x80, w r lJoaal Ln Btrte al "Adlttr€aa. r
bcf, DOp movlw
STA|!US, RPo
movwf movlw mofidf bsf
EECON2 ^ 0x80 0rrAA EECON2 ^ 0x80 EECON1 ^ 0x80,
WR
btfac
EECON1 ^ 0x90,
WR
golo bcf
S-1 STATUS, RPo
0x55
t
gtart of Requileat Sequ€nce
Enal of R€quiled S€qu€nc€ fo! wflte t wait to Cdll)L€ts€ i
This write sequenceis different from what you would seein a datasheet.I wrote it asa generalcase, and it will not return until the write hascompleted. In most applications (like the code usedfor this experiment),I will not poll the WR bit for completion at the end of the write;insteadI will checkit before startinganotherEEPROM access, asshownin asmEEPROM.asm:
l , e l P I C @l l C l JE x p e r i m e n t s f o r
the Evil
Genius
t'asmEEPRoM - Display/Save a value using till"e the EEPRoMtr ; a saveal EEPRoM This program DispLays , on vaLue Unlese lhe Button t RA3 is presseal antl th€n the AI)c is Displayeal. r is ; When t'ha Button ReLeas€dl, the A.DC Value is Saveil in EEPROM. ; This coale is baseit on ; ' t i ; ' r , ,
rlalahrare Notes: PrC16F584 runningr
in
PIckit
1 starter
kit
Myke Pretlko O4.72.2a IJIST R=DEC INCLUDE np16f,684. inc"
t
incf cal-L xotlw btfsc goto InitEEPRoM: clrf movlw catl incf movlvt call incf mowlvt call incf movlw call iIICf movll' call
== otAA?
t EEPRoM(3)
Gootl t Yes' Pattern the EEPRoM t hitialize
!'SR 0 EEPROMWTite FsR, f oxEF EEPRO!4Write FsR. f 0x55 EEPRoIqwrile ESR, f 0r.AA EEPRO!4Wfite FSR' f 0 EEPROMWTiIe
with
t Start
Nothing
Registers
FCr{EN-oEF & rESO OFF & -BoD oFF & -coNFrG & l{cr'RE oFF & -PWRTE oN -cPD oaF & cP-oF!' -wDT oFF & rNtoscro Variables cBLocK 0r{2 0 r, j Display, OldDisplay Buttonstat€ ADcstate. Dlay, TemP ENDC
HArIEEEPROM: 4 novlw mowf ea11 mowwf
;
;
FSR, f EEPROMRead oxaa z sTAlus. IIaveEEPROll
lJoop: movlw movwf novf novwf Displayloop: novf -
PAGE I'tainline org clrf novlw novwf novLr'
O PORTA 7 CMCONO b'00000001'
mov f bsf movlw nltrovwf
ADCONO STATUS. RPO 1 ANsEr, a Ox80
novl$r
b,00010000'
novwf bcf clrf clrf
ADCON1 ^ OxgO STATus. RPO ADcstate Bultonstat€
clrf call xorlw btfss EoIo incf call xollw btfss groto incf call xorlw btfss Eolo
FSR EEPRolrReaaI 0 STATUS, z IniIEEPROM FSR. f EEFRO!4ReaaI oxFF STATus, z hitEEPRoM FSR, f, EEPROMReaaI 0x55 sTAlus, z rnitEEPROliI
i
Turn
of,f
comParators
r rurn on the ADC with: ,Iuslif,ieal : Left ; vdll inB€ead of, vr€f 0 ; channel t Do Bank
1 Inits
ilust RAO as Analos InPut the clock as r select Fosc/8 i
r Init
state
variables
t
; EEPRO!I(2)
-=
0x55?
value
FsR EEPROMReaaI DisPlaY Loop t Displav i ],oop through the 8 t'EDs
7 i Dia!)lay. TemP
Each
of
w
t Get
1:-*
PORTA value
the
calt rlf btfss novll' novwf novlw adalwf, ca1l. bsf movwf bcf novl"w mov$tf, movll' adalt$ btfsc decfsz qoto clrf Inovlw
PORrATabl€Reaal Ternp, f t STATus, c 0 t PORTA 8 t i' w PoRTATableRead STATUS, RPo TRISA ^ 0x80 STATUS, RPo IIIGII ((2000 I 5l DlaY Low ((2000 / 5\ -1 t STATUS, z D1aY. f $ - 3 PoRTA t ! t
Eubvtf btfsc goto
f i' STATUS, C DisplavLoop
sanalle btf6s grolo
Press Button PORTA, 3 ButtonPreaa
or
ctrf btfss goto clrf movlw mo\twf
ADcstate Butlonstate' l,oop Buttonstale 4 !'sR
Releasetl t Button 0 t Ilave Nevt A.Dc value? t No' ,Just Return
t E E P R O T ' I ( 0 )= = 0 ?
r EEPROU(1) == O*FF?
Diaplav Initial EEPRo!'I( 4 )
,
up Temp to
Shif,t Bit
Reset'
Get
TRIS
Test
No write Pattern
+ 256) + 2551 Displav
LED f,or 2 ms
Turn Off r,ED Take 1 AwaY from DisPlaY
, l'oop
Until
i
the
== O*FF
Ignore t RA3 P?esseal?
i Wlite
New value
S e c t i o nN i n e A s s e m b l y L a n g u a g e R e s o u r c e R o u t i n e s
2L5
nlovf cal]. novf novwf goto
Display, w EEPROUWTiIe r' OtaLDiBpfay, Diap1ay loop
movf
ADCStsate,
btfBa goto baf Lncf
SAATUS, z BPADgtalel ADCONo, GO ADCState, f
r Roslore
Display
rnovlw tnovwf bsf bcf letuln
Value
oniAA EECON2 ^ 0x80 EECON1 ^ 0x80, STATITS, RPo
WR
EEPROUREA'I :
goto BPADStAt6l: xollw btfaa golo btfss iEcf
\r
i Wbat La the state?
.eDC Operation r Start to lhe Ne*t ; Increnenl Stale
IJooP t R€aal the
ADCState,
fol r wai! FiniEh
noverf
movr.!'
3iiilll;"I",
o
' saveDiaplavvalue?
7. Butlonslate ADmSH,
mov!'r
Diaplav
clrf
iu)Cstate
soto
rJoop
rd
0 .-{
t! 0) 1d .*{
st6t€
Machine
'r
Values
Contenta ;;;-";-;;;;,-;" Wrile
of,
FSR
EEcolt1 ^ 0x80, wR i waits for EEDAT ^ 0:.80
novr
FsR, w
l*
novwf bsf nop novlw
EEADR ^ 0x80 EECON1 ^ 0x80,
novwf
2L6
i
Stote
EECON2^ 0x80
Woral tso Write
.
37 instructions that the PIC16F684's (and all midrange PIC MCU's) processor recognizes. The instructions are listed in Table 9-3.I recommend that vou trv
The MPASM assemblerdirectivesare listedin Table9-4.Many of the directivesare listedfor completenessand will not be requiredduringnormal programming;thesecasesare markedin the table.Also note that the list directivehasa numberof arsuments: theseare listedin Thble9-5. "Use of this dfuectiveis In Table9-4,the message not recommendeddue to unknownooeration"indicates the directive is carrying out its function by insert-
ing instructions.The instructions usedare unlnown, may affect the contents of other registerq and may
$REN
r stalr
0x55
previous
w'i!e ro cdE)lere
solo s - 1 novwf
:
to memorizetheseinstructions, a brief explanation of what they do,andthe registersthey affect).Youwill be ableto programmore efficientlyand be ableto think aboutwhat instructionand the algorithmto be usedto solvea programmingproblem.
RPO
L) ts{
t PoRTAan'l TRrsA Bit
b , 0 0 0 1 00 , ilt b , 1 0 0 0 0 0 , , b , 0 0 0 1 0 0 , , b , 0 0 0 1 0 0" b'000010' alt b,001111,, b,001111,, b,101011,, b'101011' dt b,011011,, b,011011" b,111001., b'111001'
btfsc
.
the originalvalueis displayedand the lastADC read valueis storedin EEPROM, to be displayedthe next time the PIC MCU is resetor poweredup.
Table 9-2 lists the different parameter options for the
b,010000,,o,tooooo,,JTJtooooi,
w
displayed on the LEDS. when the button is released, '
For Eonsideration
C
EEPROI'twlit€:
The asmEEPROM,asm code is a direct translation
of cEEpRoM.candperformsidenticallyto it (the
f,or
PCIATH ErcH _PoRTAtabLe PCIATH, f PCIATH, !t PCIATE, f
STATOS,
r,f
Dotentiometeron RAO is readbv an ADC and then
ADC vaLue
Table
bEf
AaldreaE Reaal Byt€ at AaLlroaB
, Get
r Ciet Table vaLueE Irigbt Display
inc! pcr.Ar*, t novrdf pcl. I -PoREATable
.rt
EEDAT ^ 0x80, gTATuS, RPo
glore
starter kit,s button (on RA3) is pressed.when the PICkit 1 starter kit's button is pressed,the value of the
a'lfllw r'ow PoREArabre l-t
movf bcf !€EUrn
Previous cor$)let€
t !{ark Diaplay value gav€al
r ReEet
r subroutLn€a PORTATabIeR€aal:
ST.nmS,
S - 1 ASR, rd EEA.DR ^ 0x80 i EECON1 ^ 0t<80, RD i
fo! to
valuesavedin EEPROM is shownunlessthe PICkit 1
OIdIDiaplay
nrovf
blf,ac
goEo rnovf movltrf b8f
WR t wait write
aDC R6aal co
i sav€ the sar\9Le varu€
mov!,f,
noficf novlw xolwf xorsf xolwf
STATUS, RPo EECON1 ^ 0x80,
f,
BPADState2:
ffi:"
baf btfac
ADC Va1u6?
1 gtATItS.
Z BPA.DSlale2 ADcoNo, co
r R€adl EEPROU at Adalresd in FSR
ADc
of Required
sequence
change with different versions of MPLAB
IDE,&4PASMassembler.
l , e 3 P I C @l ' l C UE x p e n i m e n t s f o r
the Evil
Genius
trl
Table9-2 sgmbolsUsedin the PIC Dataand EesllnatlBn Listedin Tableg-3 MEUFEEembler lnstructions Sgmbol
FunEtion
D
Destination instruction: can be either f for register or w for WREG
F
Register address:seven bits for direct addressing within a bank
k
Bit specification for iNtructions, only 0 to 7 valid
kk
Eight-bit constant value: literal inshuction argument
kkk
Eleven-bit constant value: goto and call instructiotr addrcss
p
PORT register: for PIC16F684,only 5 (PORTA) and 7 (PoRTC) are valid.
Z
STATUS, Z: zero bit
c
STATUS, C: carry bit
DC
ST:ATUS,DC: digit carry bit
o
r'1
o o p
u
,-,.
g
o
rt
0,
(+ l-r'
o 5
Table 9-3 PlCl6F6Etl(and Mid-HangePIC)MicroEontroller Instructlon5et lnstructlon Flass Flffected Instruction Dperatlon addlw kk
Z,C,DC
Add constantkk to contentsof WREG and storeresult in WREG.
addwff,d
Z,C,DC
Add contentsof registerfto contentsofWREG and storesum either ilr registerfor in WREG
andlw kk
Z
AND constant kk with contents ofWREG and store result inWREG
andwf i, d
Z
bcf f, k
None
AND contents of register f with contents ofWREG and store sum either in rcgister f or in WREG. Clear bit k in register f. Inshuction operation is: f = f & (0x0FF " (1 < < k)).
bsff,k
None
Setbitk in registert Instructionoperationisf= f l(1<< k).
btfsc I k
None
Skip following instruction if bit k in register f is reset (0).
btfss f, k
None
Skip following instruction if bit k in register f is set (1).
cal kkk
None
Saveaddressof next instruction and load PC with new addresskkk.
clrfl
Z = 1
Clear (load with 0s) register I
Clrw
Z=7
ClearWREG
clrwdt
None
Clear the PIC MCU'S watchdog Tfter (wDT).
comf f, d
Z
Tll.ebits in register f are inverted and the result can be stored either in register f or WREG
decf I d
Z
Decrement the cotrtents of register f by one and store the result in either register f or WREG
decfszf, d
None
Decrement the contents of register f by one and store the result in either register f or WREG. If the result is equal to zero, then skip the next instruction.
goto kkk
None
Load PC with new addrcsskkk.
incf t d
Z
lnc'ement the contents of register f by one and store the result in either register f or WREG.
incfsz f, d
None
I[qement the contents of register f by one and store the result in either register f or WREG If the result is equal to zero, then skip the trext instruction.
iorlw kk
Z
lnclusive OR constant kk with contents of WREG and store rcsult in WREG
iorwf f, d
Z
lnclusive OR contents of register f with contents of WREG and store sum either in register f or in WREG
movl f, d
Z
Passthe contents of register f thiough the PIC MCU processor'sAlgorithm,ilogic U t's (ALU) zero check and save them either back into register f or in WREG
movlw kk
None
Load WREG with constantkk.
mowvf f
None
Store the contents ofWREG in register I
nop
None
No-operation for one instruction cycle.
S e c t i o nN i n e
Assembly Language Resource Routines
2L7
Table 9-3 (continued.) PlCl5F58q[and Mid-FlangePlEl MicrocontrollerInstructionset lnstruction Flass Bffected lnstruction Operalion option
None
Storethe contentsofWREG in OPTION_REG.Notq useof this instructionis not recommendeddue to devicecompatibilityissues.
retfie
N/A
Restoreprocessorintelrupt requesthardwareto waiting stateand retum to instructioninterrupled.
retlw kk
None
Load WREG with kk beforeloadingPC with addresssavedby callinstruction.
return
None
Load PC with addresssavedby call instruction.
rlff,d
C
Rotate registerf to the left with bit 0 beingloadedwith the curent carry flag.Bit 7 of registerf is storedin the carry flag.Theresult is storedin either in registerf or in WREG
rrff,d
C
Rotate registerf to the right with bit 7 beingloadedwith the current carryflag.Bit 0 of registerfis stored in the ca y flag.Theresult is storedeither in rcgisterf or in WREG
sleep
N/A
Put the PIC MCU into a low-power mode.
sublwkk
Z,C,DC
Subtractthe contentsofWREG from constantkk and storethe differenceback into WREG
subwff, d
Z,C,DC
Subtractthe contentsof WREG ftom the contentsof registerf and storethe differenceback into registerf orWREC.
swapff, d
None
Swapthe leastsignificantnibble with the most significantnibble of registerlThe swappedvaluecanbe storedback in either registerf or irt WREG
t sp
None
Storethe contentsin WREG in the specifiedPORT register.Note Use of this instructionis not recommendeddue to devicecompatibilityissues.
xorlw kk
Z
ExclusiveOR constantkk with contentsofWREG and storeresultin WREG
xorwf f, d
Z
ExclusiveOR contentsof registerf with contentsofWREG and storesumeither in registerf or in WREG.
Table 9-4 MPF5M Fssembler Directives Functlon
DlEctlve
o
,t{
"tJ tu
f{ 0l d .r{
._badram exprl-exprll,exprf-expr]l
Specify registers that should not be accessed.Whena direct accessto these registers is made, MPASM assemblerflagsthe instauctionwith a warning.This directiveis normally usedonly in the Microchip written part number .inc file to define the PIC MCU part trumber register ranges.
-badrom exprl-exptfl, exprf-exprll
Specify program memory addressthat should not be accessed.When instructions are found in these regiongMPASM assemblerproducesa warningor erlor. This directiveis normally usedonly ilr the Microchip w tten part number .incfile to definethe PIC MCU part number addressranges.
-config expr
SpecifyPIC MCU configurationword value.Option specificationequatesare found in the Microchip written PIC MCU part number .inc file.
-config expr
Speciry16 bits ofdata to be storedin non-program-accessible memory.Generallyusedfor serial numbersor programrevisioninformation.
_maxtara expr
Directive usedto specifymaximumfile registeraddress. Like _badram, this directiveis normally usedonly in the Midochip writtet pa number .inc file to definethe PIC MCU part numberregiste{ ranges.
maxrom expl
Directive used to specily maximum program memory addres$ Like -badrom, this directive is normally usedonly in the Microchip written part number .inc file to definethe PIC MCU part number regtsterranges.
{0 L{
U t"r trt
#definelabel Istringf #1ncl,Jdeinclude,file
Declarea text substitutionstring.Definesdo NOT replacecompletelineslike macro$
#undefile ldrel
Delete label previouslydefined.Previous(above)instancesare not affected.
#v(expr)
InsertASCII valuefor expr in the st ng du ng macroprocessing. Used to differentiatelabelsalgorithmically.
bankisel ldbel
This directive will set the IRP bit of the STATUS register according to the value of label. Use of this ditectiveis not recommendeddue to unknownoperation.
banksel laDel
This directive will set RPURm bits of the STAIUS register according to the value of label. Use of this ditectiveis not recommendeddue to unknown oDetation.
2L8
Load the contents of the specified file into the assemblylanguagesource file.
l , a 3 P I C @l ' l C UE x p e r i n e n t s f o n t h e E v i l
6enius
Table 9-4 kontinued) q t
cblock lexpr]
Start variable,structure,and equatesat specifiedvalue.Labelsbetweencblock and endcare given mcrementingvalues.Larger value numbersare specifiedby a colon (:) after the label.
Uabel]codeIROM_addressl
Not requiredfor singlesourcefile applicaUsed when objectfile is createdfor linked applications. tions.
const^ntlabel=er.ptf. . . ,label:exprl Specifya constantvaluefor a label.Seealsoequ. Createda packed14-bitASCII string(i.e.,sevenbits per character)in programmernory.The Uabeflda expr L exp2. . . . , expml PIC16F684cannotaccessthis daia.
i t
llabe\ dat^ expr,l,expr,. . . ,exprl vabell db erprf,expr,.. . ,exprl
Storedata asfull instructionsin programmemoryThe PIC16F684caDnotaccessthis data.
fn
ReseNeprogrammemory with packedeight-bitdata.ThePIC16F684cannotaccessthis data.
li"J,
flabel]de expr [, expr, . . . , expr]
Define data to be burnedin data EEPROM during PIC MCU programming.
llabell dt expr [, expr, . . . , exprl
Define table bytes(retlw expr).
flabel]dw expr[,e4r, . . . ,expr]
Rese e programmemorywords.The PIC16F684cannotaccessthis data.
else
Usedwith if directiveto indicateend ofprimary optionsand stat of secondary.
end
Indicatethat the end of the sourcefile hasbeenreached.
endc
End cblock label assignments.
' ! !
endif
May follow else. Used to end if conditionalassembly.
'-*,
endm
End macrodefinition.
endw
End while loop.
label equ expr
Assignthe valueof expr to the label.Seeset.
error String
Forcean efior with a message string.
fl\
gu
errorfevel{0l1l2l+t1s8ruml-msgnumlInhibit printing or displayingspecificerror and warningmessagenumbers. Exit ftom macrowithout processingany followingmacrostatements. exitm expand
Expandall macroinvocationsin the listingfile. Used with list and noexpand.
externLabel [, Label . . . ]
Declarethat the specifiedlabel is locatedin a linked file.
Uabe\ flll instuctlexpr,count globallabel[,label . . .l
Fill programmemory startingat the current address, with the specifiedinsftuctionor value.
Uabe\ idata IRAM addrcssl
Declarethe start of initializationcodein a linked application.
lfexpr
Begin block of conditionallyassembledcode.Completedwith either else. . . endif orjust with endii The if codeand other conditionalassemblycodecan be nested.
ifdef label
Begin block of conditionallyassembledcodeif label is present.Theifndef is a complementary directive.Completedwith either else. . . endiforjust with endif.Can be nestedwith other conditional assemblycode.
lfndef label
Begin block ofconditionally assembledcodeiflabel is ,ot present.The ifdefis a complementary directive.Completedwith either else. . . endif orjust with endil Can be nestedwith other conditional assemblycode.
list llist_option,. . . , list_optionf
If just the list directiveis on a line,listing is printed.Usesparameterslistedin Table9-5.
locallabel l,label. . .l
Define conditionalassemblylabelslocal to the current macro.
labelmacrofarg, . . . ,ergl
Declarea macrowith optionalparameters.
messg"messagetext"
Generate a messagein the listing file.
noexpand
Turn off macroexpansionin the listing file.
nolist
Tirrn off code listing.
flabellorgexpr page
Specifywhereaddresscode is to stafi.
p Eesellabel
Update PCLATH pagebits for the specifiedlabel.Use of this directiveis not recommendeddue to unknown operauon.
processorprocessor_rype
Specifyprocessort'?e. Use of this directiveis not recommendeddue to the processortype being specifiedbY MPLAB IDE.
ftdix default_radit
Insteadthe r: option ofthe Specifynumberradix type.Use of this directiveis not recommended. list directiveshouldbe used.
Define a label that can be accessed by other linked files.
Start a new pagein the listingfile.
5 e c t i o nN i n e A s s e m b l y L a n g u a g e R e s o u r c e R o u t i n e s
2L9
Table 9-4 (continued) MPFI5MFssembler Eirectiveg Dlrectlve
Function
flabell res mem_units
Reservespecified program memory for other linked files.
label selexpr
Assignnume c valueto label.Similarto equ directive,but label value can be changedwith additional set directives
spaceexpr subtitle "sur_te.rt"
Insett expr blank Iines into the listing file,
title"title_text"
Specify st ng for top line of each listing file page.
vabefludatafRAM-addressl
Declaresuninitializeddata areain Iinked objectfile.
llabeq udata acs\RAM-addressl
Declares uninitialized data area in linked object file for PIC18 series line PIC midocontroller$
Uabequdata ovt lRAM-addrcss]
Declares a section of overlayed uninitialized data in linked object file.
Uabell ldata sht fRAM-addressl VariableLabel[=expr][, . . . ]
Declares a section of shared uninitialized data in linked object file.
while expr
Loop code within while . . . endw until the expr is rot true (or zero).
Specify secondliDe of program title.
Declarevadablewith optionalinitial value for assembly.
Table9-5 OFtionalParametersFlvailableto the List Eirective
'
riniiii
b:#
Set tab spaces. Eight is the default.
c=#
Setcolumnwidth. Default is 132.
f=hexfileFormat Specif, hex file output format.Default is INHX8M and can be INHX32 or INHXSS. F.ee Allow ftee-fomat parser.Default is "fixed." mm =OFF
Turn off memorymap displayin listingfile.
n=#
Specilythe numberof linesper page.Default is 60.
p:type
Specifyprocessortype.Default is definedby MPLAB IDE processoroption.Use of tlis list parameteris not recommended.
pe=type
Specifyprocessortype and enableextended instructionset.Availableonl] in PIC18series PIC microcontrollers.
r=radix
Specifyoct or decnumber radix. Default is hex.
st=OFF
Tum off symboltable print in Iistingfile.
t=ON
Truncatelines.Default is OFF and will cause linesto wrap to the next one.
w=0 | 1 | 2
Setthe reportingmessagelevel.Seeerorlevel directive.
x=OFF
Turn macroexpansionofl Default is ON.
":-1 r \
rd i!'l
0l "Fl
r l f-i
n &x{ 220
l , a l P I C @f i C u E x p e n i m e n t s f o r
the EviI
Genius
Section
Ten
5ensors
1 DMM 1 Wire st!ippers 1 Ne€dle-nose
pliers
2 Bleadboards 1 Wiring
1Plcl6F684
1 4.7k fesistor
1PIC12F5?5
1 1k res istor 4 10k resi stols
2 tLC251. 1 Two-line dj.splay I
by 16-character
LCD
4 47of,) resistors 2 33oO !esistors
?4LSt?4
2 2200
1 Sharp GP2D120 IR ranging 2 38 KHz IR TV remote
module
control
1 U-shaped IR opt o- intelrupt (see text) 1 10-LAD bargraph 3 Higfh-intensitY
er
47 pE elect:.olytic
LEDS
L electret (1N4148) silicon
2
10k breadboard-mountable tiometers
I
10k 10-pin
capacitor
4 0.0L pF capacj,tols 1 16-button
1 ]R LED fN9f4
(R
4 0.1 /rF capacitors
4 LEDS (anY color)
f
poten-
resistols 2 10k light-dependant decleases with 1i9ht) 2
display white
resistols
2 10of,) !es istors 1 1k breadboald-mountable t iOmete!
1 2N3904 NPN tlansistor
diode potea-
SIP
I
keypad interface midlophone
SPST breadboald-mountable
switch
4 bleadboard-mountable on pushbuttons
momentaly
1 Four-celI
clip
2 Three-cell
Or I
kit
Ail battery AA battery
clips
10 AA batteries 10k resistols
1 5V lanteln
2 3.3M !esistols
battely
1 55nn black heat-shrink to 1.2sinches (2.5 to
2 2.3M lesistors
When I passedarounda proposedtable of contentsfor thisbook,this sectioncaughtmany eyes,asan introduction to sensorswasfelt to be useful for robot developers.Atfi$t,I wasa bit disappointedby this response
I tubing, 3 cm) long
becausethe topics I cover in this section are actually requked in many different microcontroller applications;it providesyou with many of the basicsneeded to changeenviroffnental parametersinto valuesthat
22'1
canbe processed by the PIC MCU This informationis usefulfor both microcontrollerapplicationandrobot developers. The topic of proper sensorinterfacingand dataprocessingwould take up a book at leastequalin sizeto this one,but in this section,I will introduceyou to someof the differentsensorsthat are typicallyused with microcontrollersaswell asprovideyou with a simple intedace that will allow you to create efficient multi-MCU applications. An important aspectof implementingsensorinterfacesis characterizingthe parameter being monitored andthe approp ate time intervalbetweensensing operations.Instead of rusingsensingoperations,I will usethe more commonlyusedterm pol/lng.The polling intervalcanvary widely and accordingto the characteristicsof what is beingpolled.In Table10-1,I have listedsomedifferent thingsthat are typicallysensedin microcontrollerapplicationsalongwith someideas about the appropriatepolling interval. The applicationspresentedin this book are actually very simplesensorapplications. Thereis very little processingdone on the data other than magnitudecomparison.And, in many commercial applications,the rate of changeand projectedfinal valuesare calcu-
lated.Beyondthesecalculations, when you are trying to identify an objector a total environment,the processingrequirements can be formidable. To simplily the experimentspresentedin this section aswell aseliminateany integrationissuesyou may haveusingthe sensorswith somekind of user interface,I am going to break from tradition and usea simpleinterfaceasa basefor complex,multiprocessor applications. When mostpeoplethink of a microcontroller interface,they think of an asynchronous serial interfaceusingthe non-retum-to-zero(NRZ) protocol of RS-232(the serialinterfaceusedin PC Modems). The problemwith this protocol is the needfor dedicatedhardwareto wait for and decodethe incoming signal.The PIC16F684and many lower-endPIC@ MCUs do not havethe built-in serialinterface(called a UART), so different communicationsmethods are necessary. The methodI choosefor this sectionis a sl'nchronousserialinterfacethat I originallycameup with for Ihe TAB ElectronicsBuikl Your Own Robot Kitmis interface takes advantageof the Parallax BASIC Smmp2 (or BSZ) built-in SHIFTIN and SHIFTOUT synchronousserialdata transfers. The PIC MCU
Table 10-1 EnvironmentalParameterEuJithFppropriateSensors and Folling Intervals Parameter
Sensor
Ambient Light Level
Light DependentResislor(LDtuCDS Cell) 200 to 500 ms
LDR responseis generally100ms.
SectorLight Level
LighrDependenr Resiqlor(LDR/CDScel
200 to 500 ms
Multiple LDRS or a singleLDR on moving turet usedto characterizeenvironment.
Object Location
DigitizedVideo
15 to 30 ms
Object identification;locationdetermination can changewith sensormovement.
Object Distance
UltrasonicRanging
100to 300ms
Sensormovementrequirescontinualpolling.
Object Collision
IR Reflection
50 to 100ms
Usually usedin safetyapplications(robot or operator);continuouspolling required.
Object Collision
"Whisker" or MechanicalSensors
20 to 100ms
Usuallyusedin safetyapplications(robot or operator),continuouspolling required.
SoundEvent
FilteredSoundInput
1to10ms
Short,loud eventscan be easilymissed.
SoundCharacteristic
FilteredSoundInput
50 to 200ms
Waitingfor tone or other easilyrecognized characteristicthat is presentfor up to several seconds.
Verbal Command
Digital SignalProcessor
500to 2,000ms
Speechprocessingrequiresa significant amount of time to complete,
vJ
Pollinglnteval
L-a
9 i
Eommenls
Ambient Temperature Thermistor-Calibrated TempemtureSensor 1 t o 1 0 s
The assumptionis that the ambienttemperature cannotchangequickly.
Fire,High-HeatSourcesDigitizedVideo,Pyromete$,LDRS
50 to 250ms
Typicallya safetysensorwith possiblerequrement for sourcelocation,generalrequirement to respondquickly.
Humansand Animals
Pyrometersor IR Reflection
250to 1,000ms
Typicalapplicationsincludeburglar alarms and automaticlights.
(Air) Pressure
Barometersor PressureSensors
5to60s
Pressurechangesgenerallytake placevery slowlyexceptin safetyapplications.
Humidity
Humidity Sensors
15to60s
Slow changesin environmentalhumidity.
222
l , a 3 P I C @l l C l JE x p e n i m e n t s f o r
the Evil
Genius
peripheralclocksdatain and out usingthe clocksignal producedby the BS2.ThePICSend(sendinga sevenbit commandto a PIC MCU from a BS2) and the PIC(sendinga seven-bitcommandto a PIC SendReceive MCU from a BS2and the PIC MCU respondingwith an eight-bitresponse)are demonstratedherein BS2 IF Base.bs2: r BS2 IF . Basic
BAS€ Bs2 to
r nPrcsendtr r suDgolteal
I ltrke
Template
PIC llCU InEerface
aaal ,'PrcsenttReceive' t OperationE
are
only
Prettko
. {$PBASTC 2.5}
- Put in B€lo\t
PICDatsa = 1
\ High
PIC MCU I/O
r Wait
fo!
progiam
PinE
PIC MCU to
Sta!€ments
. Sendl Basi.c MCU
as
Sets Up
Shown
cormanal
to
cosuB Prcsenal PAUSE 100 PICData
= 58L
. tvait Prc to Finish fo! PrevlouE . genal 0x81 anal Receive RegDollS€
GOSTB PlcsenflReceive DEBUG iPIC Respons€", ENI)
\ PICSenal are 1 - 8 Cdmanals r PlcsenalR€ceive Conlanils S81 - S88 r Prc Mcu rnterface Pins r Data Byte tso senal tolReceive PICData vAR Bybe ' IO Pina PC PIN O PD PIN 1 r setral the Byle in rrPrcDatatr Plcsenal: r Holal IJow foi 1 msec b€fore LOw PC ' shifting in DATA PAUSE 1 SEIFTOIJII PD, PC. I.SBEIRST, tPICDatsal HIGII PC RETIJRN
PD,
PC,
LSBPOS!!,
DEC(PICDat.a),
CR
PIC
$*. ;.J
a-,!
Eid
A PIC MCU applicationthat interfacesto this code caneitherwait for a commandfrom the BS2or continually poll and processthe sensor,polling the clockpin (PC in BS2IF Base.bsz)at Ieastonceper ms in order to not missthe beginningof any commands.If the samerequirementwasgivenfor an applicationthat interfacedto anotherdeviceusingthe NRZ protocol, the maximumdatarate would be approxirnately300 bps,due to the need to also poll the serial input line and still be ableto perform someusefulapplications. In contrast,the BS2takesabout2 millisecondsto send a byte,one-fifteenthof the time requiredfor the 300 bps NRZ sendtime. I realizethat few peoplehaveBS2savailablefor working throughthe projectsin this book, so in the first experiment,Iwill showhow you can simulatethe BS2usinga PIC MCU. With the additionof a simple LCD userinterface,you canexperimentwith different sensors.
S e c t i o nT e n S e n s o r s
IJ i r
IPICDAtA]
RET['RN
'variabl€s
' +*#* r
{n
Predko
SHIFTI}I
' {$srar{P Bs2}
Mainline IIIGII PC ITIGII PD PAUSE 1OO
I r4fke
codle Follows
r genal Ebe Byle in "PIcData" PICSenatReceive ! r HoLal lJolr for 1 maec befo!€ IJOW PC . shiftlng in Data PAUSE 1 SEIETOUT PD, PC, LSBFIRST, IPICData] r wait for Op€ration to PAUSE ]. r cdll)L€te
10o.,"".r.
\
r Prc Mcu rntserfac€
223
(u
?a
r 3
Experiment 8r-l-Plf MCUB5a User Interface
0)
U d
tt-.| h
1 Prc12F575 I
o
fwo-line by 16-character LCD dj. splay 7 4L577 4
P
g
1N914 (1N4148) si licoo dj,ode
H
l0k b!eadboard-mountable potentiometels
tl
1 10k lesistor
v,
1 B!eadboa!d-mountable momentary on pushbuttons
o
0 .01 pF capacitors DMM
p
Needle-nose pliers Breadboard
c{
Itiring
Three-cell clip
kit
a
AA battery
3 AA battelies
s U
X
U H
Pr
I
To createthe PIC MCU-based,simulated,BS2user interface,I usedthe two-wire LCD display first presentedin Section 6.The application shown in tHs section simulatesthe waveform clock lovoause lms/shiftout/clockhigh oI the PICSendBS2subroutine and the waveform of PlCSendReceive.In Figures 10-1and 10-2,I havecorrelatedthe differentfeatures of thesetwo waveformsto the BS2 statementsthat producedthem (listedearlierin this section).Thedata transfer is basedon a 14 g.sclock pulse over a 46 ps period for eachbit (seeFigure 10-3).The work to create the application code wasfairly substantial,and the need for precisetiming gaveme a good feeling for
writing assemblylanguagecode for the PICC LiterM compiler.The final result is quite easyto work with, althoughI discovereda potentialpitfall that you shouldbe awareof. The circuit usedfor the simulated BS2 interface (seeFigure10-4)usesall the availablepins of a PIC12F675.Inadditionto the two LCD interfacepins, the circuit assignstwo pins to a potentiometer/button userinterfaceandtwo pins to the simulatedBS2 clock/data lines.The circuit was built on a breadboard (seeFigure10-5)andis about ascomplexasI would like a PIC MCU breadboardapplicationto be. Included in Figure 10-5is the application circuit from
Flgure IDJ
BS2Send
Fisurel0-e
224
l , a 3 P f C c 'l l C u E x p e n i m e n t s f o r
q
(l 'd tl ,tl
P.t n IJ
gd
BS2Send.Receive
the EviI
6enius
P1 X
ro o
Ft
Fr.
o Figure f0-5 BS2simulntorcircuit on a breadboard and connectedto testsensoraDDlication Fisure f 0-3
@
BS2 Shifioutdan
|}5
the next experiment, to test out the operation of the interface and the PIC MCU code. The user interface consistsof a potentiometer that selectswhich command is to be sent to the PIC MCU instrument circuit. The user interface is capableof sendingthe comrnands0x01through 0x08 aswell as the responsecommands0x81to 0x88 by turning the potentiometer.To avoid the need of precisely setting the potentiometer, the first half tum selects0x01to 0x08and the secondhalf turn selects0x81to 0x88. Once the commandis selected,the button is pressedto
Clock t To S()nsor 1J C i r c uits I r-Data
P C 1 2 F76 tC v
10k
; F L
4
----l: 1 ir--
GPIOO 6PIO1 GPlO3
G PI O 5
l u F
GPIO4
sendthe data.If a responsecommandis sent,the responseis displayedon the lower line of the LCD. This method of specifyingand sendingthe command and then displaying the responseto the instrument PIC MCU is surprisingly easyand fast to work with. If you are looking for a simple-to-useinterface,you might want to consider using the method I provided here. The applicationcodecBS2Sim.cprovidesthe LCD, potentiometer, and button user interface aswell asthe two-wire BS2 comrnunicationssimulation code.The
74L5174 2
5Q/5D
3 6Q
Gnd
vc d
--J-
- r -
T .:
-
II I
15
I rox
4 . sv J_ .:
lI
I I I
0.01 |
u F l
L
( /
E
I J
10k
m o
|,/l
fi
1k
1Q/2D
H
r\}
dd
CLR | 1 6 t""
ry
m
t\a 1 N9 1 4
GPIA2
I
H'
Yoo
L2/14 15
I
H
F
2/4
5/6 2 Q / 3 D '7 /1-L 3a/4D L0/L3 4a/5D
|
|
|
|
(r
o
|
Il :
h r+! p,
L
o tv
Flgure fO-q BS2simulatorcircuit
S e c t i o nT e n S e n s o r s
225
0, fl rv
t+{
1.r {,
g H LI €,
&0
p
rq VJ rY1
rt .*
r 1
tu
basiccodewaswritten in C to take advantageof the codealreadywritten for the BS2two-wireinterface and the ADC (for the potentiometer),althoughthe tu7oBS2simulatedsubroutinesare written in assembler to ensurethe timingsare ascloseto the BS2'sas possible.As a referencefor the simulatedBS2,an oscilloscopewas usedwith the Parallax BS2 datasheets to make sure the signalswere aspreciseaspossible. *incluile - Sfu{rlated cBS2 Sl$.c /*
Bg2 Senso!
Interface
l,lria ProgEam Inltializes the Hltachi {{780 Baaett I|cD in { Bit Uoal€ a.Dd then coatinually !h€ lrotenli@r€ler oD cpIO2 as well Dolla aE the Button oo GPIO3. llhen the ButEon iB gress€al, th€ (Drocesa€tl ADC Value aE b€1o$) is Sent to another PIC lEU as if il wele a BS2 ComAnal. |Ih6 ADC value ADCValu€ ADqvaluo 0x07 ) t ADCVaIUe
is
proc€ss€d
as:
= (.a!RES >> 5) & 0x08, = ( (ADCtIalue & 0x08) << {)
PICSenil ( Ints DatavaLue)
{ //
Hex values
GPIOo - BS2 Interfac€ CPIO1 - B's2 Inlerface
Clock Pin Data Pi.n
IJCD Write Infor atiodr htstD: //w{w.rvk€.cd!
can b€ foural
Thls aDDlication uses arld PIC As6€nib1€r.
a cdnbiration
of
eiEher
of
andLw ttf btfsc iollw nol^rf
0x01-
PICC lJite
C
TSIS APPIJICATION USES tt'HE PIC15r675Ilt
GPIOs - I,cD Data Pla CGIOII - I,cD Cloch Pin
ig
qr
ce 4r ,tt
.t 1
&{ nl i,
& I'NPROIECT & BORDIS & !'!CIiADIS & -COIIFIG(T'NPROTECT P1IRTEN&IIDII'DIS&\ r$Tro) t int in!
IraatADc ButtotfLag
r'Ilsigrled ungigned uEaignetl
char cbar char
-1r - 0i
// //
€LastADCr ait aDlayt
taeb Italk // // //
I& value Reaat In Wlren Pre8aed
aasenbLer aasembler ass€rnbler
oL234557 490!2345 /t conat cbar rolabaaage II conat cbal BotsMaaaage I I = n Rea9onEe *defin€ Clk GPIO{ ll Defi-'ie the LD g€lial Control Pitr6 Data ePlos *defin€ // Lf Etj-ese Cha.nge, CharEe aesesibler cdrst
226
int
Tweftyrn5
= 1250;
tastADC Countor D€lay
3lrr _aLaEts.Al)c, status, 0 02h porta
r Clock Line iE Lort 5J + 256 t DeIaY l'!' 1,598 ua
/
5) + 256t
i
Shif,l
Outs the
Data
, Set GPIO1 t aDgrolrliale1y
f
iorllr 01h baf _a.DLay, 2 PSPTeIJooD: d'ecfaz f _a.Dlay, grolo PgPrelJoop [ovlrf Dortsa a*Uw 3dr baf, 2 _aDlay, PSCIockIJoop : tlecfsz f _aDlay, goto PSCIockIFop novllf Dorta rnovwf nqD PgPoatI6oIr
ryke prealko 04.n.23
0 Dorta, ((1688 lligh
novvrf _aD1ay novlw ldr ((1688 | PsgtartIJdqrDLay: -1 aaLlLw btsfsc statua, 2 al€cfaz f _aDlay, goto PsstartlJonDlay llovlt,r I rbvrff, ai PSOutsIoo9: lrdtrf, w Dotta,
&
a!
= Datavaluei alaatAllc gave ADc value tso S€nd
*asn bcf novLw
= .A.DgvaLue + 1t
ThiB wLl1 nsiufaclure 0:.08 or 0x81-0x88
NCIE:
= (ADCValue
a cdrstant f,or 20 nE Delay // Declate const irrts EiverDs = 300, con8! Ltrl TaroErmitr€ihrB = 10,
t ltlhia PoinE 14 cycl€s Clock Ei t befor€ t Set Clock Blts
t Sav€ Clock Eigh , Turn Off Cl.ock Aiglb
_aDlay :
, Data VaLiat fo! i ci'cles
al€cfaz goto alecfsz goto
f _aDlay. PSPoatLooD ai PSOUtloop
novlto
62
i R€Deat
i R€turn i af,ter
!rcvlrf a!1ay PsEndlonlLoop : alecfsz f _aDlay, golo Pstldrdlrl/ooD bsf 0 x,orta,
f,or
32
8 Cycl€a
Clock El.gh 188 cycl€s
Clock ia r Finally, Cqt!tr.rd Sent r High,
#eudasr ) // End PICSerd 0x00
n. in!
( ints Iratavalue)
PlcsebdRec€ive
{ //
aIJaatIDC = Dalavalu€t Sav6 ADC value to Senal
{iaEn bcf
9or!a,
0
l , a 3 P I C o l ' l C l JE x p e r i m e n t s f o n t h e E v i l
r Clock
line
6enius
ia
LoI'
hish ((168S / 5l + 2s6l ; D€LaY b!' 1'588 us nolwf alrlry low ((1688 / 5) + 256) novllr PsRslartsI,onDlay: -1 adaulr btsfac Btatua, 2 alecfaz altlay, f gotso PsRsltartldvrDlay rnovlw 8 o|rt the Data t ghift PSROUtsIJOOD : porta, novf
€natLw rlf btsfec iorlw rnovwf
bcf
3Dh _ar,a6tiaDc, atsatua, 0 02h Do!tsa
f
Point 14 ql'cleg r rhia Clock Ei r before , geE Clock Bit
iorlw 01h bsf 2 _aD1ay, PSRPrelooD: f tlecfsz _aD1ay, PSRPreLop Soto Inovlrf I)orta aDdlw 3Eh bsf _aDLay, 2 PsRclockl.ool, : d€cf,az f _aDlay, gotso PSRCIockLoop porta movwf
; After ; llata
0
porta, 1 btfac bsf atatuB, 0 rrf _aIaElADC novhtr 4 mov{rf _aDlay PSRlDoneIFop :
r Set GPIO1 r r*rDroD?iately
w
atatua,
seve
in
t Dala valifl t q!'cles
decfaz goto tlecfBz golo
f, aDlay, PsRPoallool) ai PSROutIoop
llov1v
high
f _aDlay, PSRPDon€IJooP
al€cfsz gotso
f _ai, PSRPoL!.Lop
rrcvlw
high
H"
fi.
+ 2561 r rinal
5l
/
5\
Clock
IJon D€lay
t Rel)eat
DaEa Pin
stsatus, 5 1 I)olla, slatus, 5
r !{ahe
baf
porta,
Clock is r rinally, CdrlEdril Sent r uigh,
bsf, bsf, bcf, novlcr
slatus, I)or!a, alatus, 8
blfBg goto bcf
for
8 cycLes
5) + 255\ t Po1I Response r 1.450 us
/ 5,
Buatsua, 2 f _aDlay, PsRPollDlaylooD
PSRPoUIJooD : bsf Dorta, noD rEvlw 3 PSRPHigbIooD : -1 atLl].n
//
letuln Return ll
lwbblesbift // shifr
*r{
0
i-"rl {. *t
(int T,Cf,iout, Ehe r,rybble
(
< 5r i++)
CLk = 1t CIk - 0i , // iof
Itata
Pin
PoIIing
r clock
Eigh
Re6Do(rse
to
q& i.,} iDl
Clear
//
,IuBt
,
lioggl€
the
Regiater
; *.*
Clock
| ((RS & 1) r (1 << {))t Shift Dala Out
(0 l= (LcDoul & (1 << s))) if Data = 1t // shift Bits Data = 0t LCDOut = IrcDouts << 1, Clk = l.t
PolI
tshe Sbift
!r-!i€
// //
tr! j
o{rt
th6
;
Eigheat
*-.!
Shift Up the Next Bit idto Clock the Bi! rh€ s/R
Clk = 0t // tof
i,J
rn d $
t Aftser
14 Ct'clea,
NoP()t
Clock
// lrovLw 5 PSRPWaitt ooD : aqp -1 aaLl]'trr 2 btfEa atatug, gotso PsRPwaitsloop
Iis)
//
LqDo|rt = Lcmut | (1 << 5) (i = 0r i < 5; i++) // for
Iaput
{ t start
r'rF9
8-rl
5
FtsatsuB, 2 PSRPHighIoop 0 DorEa,
our
Data = 0, (i - 0r i fo!
1
0
aIJaatADCt tsbe ReEponae
afte!
+ 256)
i llake
t
Outgrt
u\d. PrcsenalReceiv€
(
/
btfsc decfsz goto
5
32
s
i.''."
+ 255)
b8f bcf, bcf,
,
((1640
arovwf _aDlay abvLw low ((1840 PSRPollDlaylJoo9 : -L addlw
fo!
1."t
m n
to
*enalaam Dovwf aDlay nqD PSRPoatI,oop:
l*t
nalraalaDcn
, Delay {6 clrcleB t Ner.t Clock
Ilovltrf f _aDlay. movlw ].ow ((350 / PSRFina1T.oorr : -1 aaltllw statsus, 2 btfsc f alecfaz _aDlay, golo PSRFiIralI.oop
r Save Clock High r Elrrn Off Clock Eigh
PoI1
!r3 i
dlecfgz goto
((3s0
25 C:'c1ea,
tshe NybbLe clock th€ LCD
int
NOP(), Data = 0i
n!
r', gtl
|
//
B^d Nybbleshift
S e c t i o nT e n S e n s o r s
22'7
IJCDWTit€ (int |
{.}
int
a'1
//
r$
((0
if
i
.{*}
for
ICD
LcDwrite
( (LCDDaLa >> {) & 0x0F, Rsvalu€) (LCDDala & 0x0F. RSValue), // Shifl out ByEe
LCDWrite ( 0b1100000 0,
= llwollunalrealus
ai
r*
(i
= 0r
< ir
i
Delay
//
i++)r
for
character
(i
fo!
0,
//
!= 0, 1)t
i++)
!{ove CurBor to lhe Seconal lriae i++)
== 1)
//
-
0r
i
I.oop Through PoLliltg GPIO3 anal AN2
< Tw€nlt'mB, i++)t // BaEic Delay
fo!
ADc
main( )
int
i,
GPIO = 0b110011t Inlerface // gtsart with A.DCONo = 0b00001001i
ANSEI = 0b00010100,
CMCON = 0b00000111r oPTION = 0b011111!!t
Bits High // ADc Turneal on: ADI'U - left .tualifieal // VCEG - Valal Reference / / clls - aN2 // QO - Off // A.DoN - On // // ANSEI Specifieal as Tosc = Toac*8 // AN2 - Analog I/ laDut // Disable CofiE)araEor Uodlule // E':abLe pu11 uDs on RAo & RA1
wPU = 0b000011t TRISIO= 0b001100t // Everything Buts cPIo3/aN2 //
CiODoNE = 1t // Stsart ADC operatior == GODONE)t whiLe(1 j = (A.DRESH >> 4) & 0x0F, // Ploc€ss Usins ALgolithm Above j = ((j & 0x08) << {) + (j & 0x07}t j = j + a, (j t= LaatADC) if // If Different, Save antl DiEpLay
jt
8**,li
t-f
0)t
(
Enil LCDwrit€
//
itr,
f*; i, '; ".:i
lurD On LCD anal Enalrle Cursor
//
t
t
ry
0)r
(i = 0r BotMessaselil for IJCDwrite ( BotMessage t i l , while(1
)
( 0b000 01110.
f,or (i = 0r ToDU€a6ag€[iJ l= I.cDwrile ( ropMesaage t i l , 1)t
t
== (LCDData & oxFC)) && (0 == RsvaLu€) ) // S€t Delay ht.erva!.
".i
t,l
ints RSVatue) Sendl Byte to
j,
i.
NybbLeshift NybbLeshift
i.a-{
f-J
LCDDala,
Inilializ€ j = $tentlms for (i = 0r
< j;
i++)r
LaatADC = it // Sav€ the Nelr ADC Value LcDvlrite ( 0b10 0011OO, Ori /l Mov€ to 10a of OulDu! j = (j >> {) & 0x0Ft High Dtgits // wrile LCDWrite (J + t0', 1)t IrcDwrite ( (LestADC & 0x0F) + r0., 1)t ll fL , ((0
if |
to
the
W€b page
Wait fo! LCD !o power UP
//
-= GPIO3) && (0 == BuEtonalag) ) / / Debounce Buttoa
Press
(i < Tnenltlma) whtle (i = 0t (i < lw€ntt'ms) && (0 -- CPIO3); for i++) t = 1r But.tonFlag Pr€sseal // Button (ra3ta.Dc < 0x60) if PICSenaI (IJaaEADC) t else // Get Remo!€ Statua/Va1ue
OulDutsa
IJCD accoraling t i
t
t N1'bbleshifl(3,
1 !
q*4
i!"!
+-] ;^,i
ti
s
. r''.:l i$t
j
0)r
= Fivemst fo! (i = 0r i
< jr
(3, 0), Nybbleshift j = TlroHultlrealus t fo! (i = 0, i < j, (3,
lwbbleghtft
lrybbl€shift
(2,
RegeaE ReEets Cdmand
i++)t //
Repeats Reset Thiral Tlme
Cqrdnanal
i++),
0),
j = TwoHuntl!€alu€ t fo! (i = 0r i < jr LcDwrit€
//
0),
j = rlroEundlrealus t for (i = 0, i < j,
( IJastADC ) t LaatsA.DC = PlcgenalR€ceive LCDWrite(0b11001100, 0); j = (IJaatADC >> 4) & 0x0Ft High Digit /./ Write tf (i > e) rrcDwlire ( j + ra' - 10, else LcDwrite (j + .0,, 1), j=laBtaDC&0!.08, // write r,ow Digit i f ( i > 9 ) I J c D W r i t e( j + . A ' 10, 1)t eLse LcDwrit€ (j + '0,, 1)t // ti , ((1 == gp1g31 && (1 == ButtonFlas) ] else if ) ReleaBeil | // I,ook for Button i = 0t (i < Trreatt'ns) while (i = 0, (t < Tw€ntldrs) && (1 == GPIO3), for i++) t = 0t ButtoaFLag Releaaeal // Buttoa
Star! Initialization Ploeeag // gendl R€set Conmanal i++)t //
//
rniEiau.z€ l4oat6
rJcD 4 Bit
i++)t
( 0b001010 00,
0)r
//
LCD is 2 IJlne
IJCDwrite(0b00000001,
0) t
//
clear
IJCDwlite(0b00000110,
0) t
//
Move Cufao! After Each Charact€r
4 Bit
I/r',
| r,cD
, I
i;i
// Er
/ / eri}lw / / E'l,d cBs2 sin
f-.tl
228
l , a 3 P I C @l l C U E x p e r i m e n t s f o n t h e E v i l
6enius
The assemblylanguageusedin cBS2Sim.ctook longer than I would have expected,this was due to two factors.The ffustwasa mistake on my parl I did not disablethe comparatoron the PIC12F675'sGPIO0 and GPIO1 pins (usedfor the BS2 interface),which I discoveredoften resultsin unexpectedresetting of a pin when wdting to a singlebut different pin. In Section 8,I went to geat painsto explainhow the bsf and bcf instructions work, and, in this program, I ended up with a great exampleof how they can unintentionally changea pin value. In my applicationcode,I set the data pin (GPIO1) and then I thenset the clockpin (GPIO0),usingthe standardinstructions: baf bsf
GPIO, GPIO,
1 0
but whenI looked at the signalson an oscilloscope, I sawthat the data pin (GPIOI) would go low whenthe clock pin (GPIOO) wasset high.When I wrote the application, I wasunder the impressionthat the PIC12F675had an ADC but not a comparator,but I waswrong. Like the PIC16F684,the PIC12F675has a comparator with its input pins being GPIO0 and GPIOl.And like the PIC16F684, if the CMCON register is not written to turn off the comparator at power up, thesetwo pins are assumedto be analog inputs (which alwaysreturn zero when the port register is reador usedby the bsf instruction).OnceI tumed off the comparator,the pins behavedasI expected them to. I'm explainingthis becauseifyou had an applicadon that didn't work or if it behavedasmine did, you might be inclinedto assumethat the PIC MCU chip wasbad.Rememberthat you shouldalwaysassume
first that the chip is good and the problem is software related,aswasthe casehere:I didn't properlyinitialize the chip.Assume secondthat your circuit/wiring is bad. Over the 10 yearsI've beenworking with PIC MCU chips,I've encounteredonly two chips that were bad. The first time was when I waswiting Programming and.Customifing the PlCmicro@Microcontroller,in which I seemedto have worn out the Flash program memory of a PIC16F84;severalinstructions could no longer be programmed.The secondencounter happened when I was debuggingthis application and I miswireda PIC16F684inshumentapplicationto this BS2simulator;I accidentallyconnectedthe BS2simulator's ground to the instrument application's positive power.AAer correcting the error, the instrument application would work periodically,but required a special sequenceof actionsto get it working.(I had to power up the instrument application first, next power up the BS2 simulator, then disconnectthe two applications, and finally reconnectthe applications) Pro$amming another PIC16F684with the sameapplication did not require any of these actions and would, in fact, work perfectly regardlessof which PIC MCU application waspoweredup first. The root causeof this problem wasthe use of two breadboardcircuits,eachpoweredseparatelyand connected by three wfues(two for clock/data and one for ground) asshown in Figure 10-5.This connection reflectshow I wantedthe BS2simulatorand the instrumentintedaceapplications-eachasseparateas possible,havingonly the signaland gound reference in common.If I were using this application for anything but prototyping,I would createpolarizedconnectionsthat couldnot be pluggedrn error.
f{l lr,t a1
ru tv
Ft 1..
3 tv !-i
CIo #t I I
ry H
n K
n
u,
U) h,)
m tn
$ H 4
1n tl
r.h sl (l fn
S e c t i o nT e n S e n s o r s
229
AI
ri rrt
Experiment B5-Plf MEUB5a KegpadInterface
s{ &,
Prc16F684 1,5-button face
b'{ d
keypad
inte!-
1 fwo-Iine by 16-character LCD display
i
1 10k breadboald-mountable potentiometer
T {'d
Either
1 10k 10-pin
Or 810k
:&
SIP
resistors
1 0.01 pF capacitor
a!
1 SPSf bleadboard-mountable switch
DMM Needle-nose
pl iels
1 Three-celI clip
Breadboard Wiling
kit
AA battely
3 AA batteries
"i'ta
F I q: -':
.'l
',
t^-]]
a'l , :
i
.i1
a'-r fi -.:
r-: s:,11 ai.. fi.1. C'.t,{ !-*1
Although the potentiometer-controlled PIC12F675 interfaceworks well,I wantedto seehow easyit would be to createa keypad-controlledinterfacewhile at the sametime eliminatingthe needfor the 74LS174used asa shift registerfor the LCD display.Pin allocation can be difficult in this situation.A four-by-four(16-button) keypadrequireseight I/O pins;an LCD requiresa minimum of six if the two-wire shift register is not used;andto top it off, two wiresare requiredto provide the BS2interface.The total number of pins requiredfor this applicationappearsto be 16.However,asI will show,the keypadcolumnand the LCD datapins canbe shared,allowingthis applicationto be wired into a singlePIC16F684with only 12 I/O pins. The trick to sharingpins in an applicationlike this is to look for output pins that canbe sharedbetween interfacedevices. It shouldbe obviousthat clockingor control pins cannotbe sharedbetweeninterfaces,as the devicebeingaccessed will be confusing. The LCD datapins and R/S pin canbe sharedwith the four column drivers usedin a four-by-four switch matrix keypad.The combinationof thesetwo componentson the samedatabits worked very well with just a coupleof complications. For this application,I wantedto keep the LCD data pins on RC3:RC0to simplifythe programmingof the LCD writes(keepingthe databits in the lower nybble of a byte).And I alsowantedto keepthe wiring assimDleasDossibleon the breadboard.Thesetwo condi-
230
tionsweremet (seeFigure10-6),althoughit wasdifficult to showthe simplewiring to the keypad.The schematicmight be a bit confusing;rather than draw the rowsand columnsof the keypadasfour individual wires,I useda bus,which is a thicker line.Thesefour linesare passedto the rows and columnsof the keypad asshown:The keypadI used(boughtfrom a surplus storein Toronto)had the rows and columnsin two groups of four pins,which simplified the breadboard wiing for my prototype. Note in Figure10-7,the four columnbits (the bus linesthat intersectwith the LCD bits) do not useall four LCD databits.Insteadthree data bits and the RiS bit are used-asthis worked bestwith the breadboard. This made the software a bit rnore complex but was worth it, asI did not haveto wire eachkeypadpin individually to the breadboard/PlC16F684. InsteadI could simplypushit into the samecolumnasthe pin-1 sideof thEPIC MCU. In the apptcation,I pulled up all eightpins of the keypad.Like whenI startedthe application,Ididn't know which pins were which, and I had to decode them.When you look at the sourcefiles for this application,you will seethat I createdasmsctrll.asm throughasmsctrl4.asmto decodethe keypadand make surethe operationwas(reasonably)intuitive. The final result.asmsctrl5.asm.takesin a maximum two-hex number command (taking advantageof my keypad's2ND key,which I usedto shift the key inputs
l , e 3 P I C @l l C U E x p e r i m e n t s f o r
the Evil
6enius
Fiqurel0-7
BS2 Fiqure l0-6 Breadboard-wiredkeypad-based breodboard simulator wiretl tr.tsensor
of 1 through6 to A throughF). The CLEAR key was usedto erasethe two-charactercommand,and ENTER sendsthe command(and,if the valueis 0x80 or greater,it alsolooksfor a reply). Dependingon the keypadyou usefor this application, you may not be ableto wire it assimplyasI have
Keypad BS2
for my prototypeor the keyson your keypadmay requireyou to work out a differentuserinterface. When you createyour own keypadinterface,follow the stepsthat I have:First,get the LCD working;next, work at decodingthe keypad,and model the user interface;and,finally,add the B52 interfacefor the peripheralfunctions.You will probablyfind that working throughthesestepswill take you a few days,but they shouldbe fairly uneventful,and whenyou haveto perform this task againlater,you'll find that it will take onlv a dav or so.
86-PlC MfU lnstrumentInterface Experiment
1PICl6F684 1 LED 0 .01 pF capacitor fhree-ce11 cli p
AA battery
AA batteries
P I C 1 2 f 6 ? 5 o ! P I C 1 6 F 6 84 based BS2 coBnand interface sinulator DMM Needle-nose pliels Wi!e strippers Breadboard Wiling
With the BS2and PIC MCU equivalentintertaces available,we cancreatea simpleapplicationthat turns on and off the LED connectedbetweenRA4 and RA5 of a PIC16F684remotely(seeFigure10-8).Thisexperiment hasonly threecommands:(1) LED On, (2) LED Of| and (3) 0x81- Return LED State.And its codeis basedon asmBS2Template.asm:
kit
5 e c t i o nT e n S e n s o r s
23t
$g t
RAO
I BS2 J Interface
RA1
ftt
wl
tr
cnd
t R€giatser usag€ CBI|oCK 0rr20 t i, j, k Bg2Btrtse , Dlayvalue:3 r t ENDC
RA5
Plct6F684
p
liat R=DEC INCTTTDE'p15f 58{. incn
Sgart
of
cP R€gistela
Bg2 Senal/R€ceive Value lrhree ByEes Neetleil for Macro
D€1ay
0-J PAGE
-T; .5 V
#
_coNFrG ,E C!{EN_OEF & _rESO_OFF & BOD_OrE & & PIVRTE Oll & _qPD_OFF & Cp_OrF & _!{CLRE_OF! _wD1!_OFt' & IN:IOSCIO
I _t_ :
fil
Figurel0-8
BS2Demo
t [qaiDline
;J iJ
s
"asr8s2
Eitl€ llcu Intelfacer
t},t
This Program Drovidles an Intelligent BS2 Interface.
t; *,1
f l
r*r t
r{ F,ed
a t
\s ffi
the
BjISIC
baaia
StarD
II
for
Bs2 CorElantla (tso be ilefineal by applicalion) 1 - CdmaaA 1 2 - Comland 2 3 - Cdmanal 3 4 - Codmanal 4 5 - Cormand 5 6 - CoduEnal 5 7 - CodEranal 7 I - CoiElantl 8 (to b€ tlefined Data R€aDo[al Coltnanala by agl)licaEion) 128 - ResDoutl CorElanil 1 129 - ReaDonal Corrlanal 2 130 - ReaDoail Cortrlanal 3 131 - ReaDonal Cotunarrd { 132 - ReaDondl Cor@aaal 5 133 - R€6Donal Colulanil 5 135 - R€sDontl Comtanal 7 135 - ReaDonil CofinenCl 8
f-1
1
T€!!p1ate
-
llaralware No!€a: t PIC15F684 runnLng at { UHz Uainq th€ r Inlelnal Clock r Int.elnal Reaets is Useil r aAs - Clock hput t ltA4 - Data I/O t Renaiaing Pins a!€ for VariouE t I/O atrd Fullc!ions
pIC
o!9 no9
=i*fi € r
i , ,
ConData Comclock
Uyke Proalko 04.LL.25
PORTA, 1 PORTA, O
i
trovlw
0x0Fr
movlrf movhr
PORTA 7
rnovwf baf clrf
Cllcolro STATUS, RPo ANSEI, ^ 0x080
bcf
OPTION_REG ^ 0x90,
movld
b'000011'
For
r Make , BLta
; r 7 , i r r
All PORIA High
mov$f WPUA | 0:rg0 #*l+# - uoatj.f,ylPut 1n Aalditional t Bil/PeriDheral Initializations bcf SIATUS, RPo lrooD waitiag fo! r IJooD: btfsa Cdclock caLl **** t oDelation8 goto
AlI Bils a!6 Digita]' Eneble PORTA pull UI)E Enab].e RAo/RA1 Pull U9a Porl
BS2 corEEndt i Reaal BS2 Eor t Codmanal
BS2R€aal P€rfofir here IJooD
Reatl/R€apoaal ; BS2Reaal:
aDy Repeating
to
gub-ns
BS2 Comlanala i D€coale tsb€ BS2 t CorEraad i Mrnber of Bits i to Reaal
i
movlw rrrcH (3800 + 255) movwf J movle LOw (3800 + 256) as2RlrooD].s
r Wait for Data to t becdne Active
&d
232
ICD2
t qodE)arator8
lnovwf, *alefln€ *alefia€
0
l , P 3 P I C o I ' l C l JE x p e r i m e n t s f o n t h e E v i l
6enius
btfsc golo aflilhr btfsc decf.z goto
comclock BS2RSkiD3 -1 STA!!US, Z j, f BS2R]JooP1
i coun!
BS2RE!ro!: S!!ATUS, RPo CdlData
bcf reEur!
STATUS, RPo
blfEs goto dl€cfsz goto goto
i i i
, i t i
r Clock LowlReatl r the Data Bil
il,cf .z golo
i, rd BS2RSkip2
btfBc
BS2B!rt€,
r sbift
in
the
.i at the rJest - No... i 7
Bg2RReaponflcdmanal
i Bg2 R€sDondl t C@land? i.f No, wait t
i BS2RSktD2:
Final
clock
Bj.t Bits?
for
Eigh
, Clock StiU , Low/Wail f,or High 100 j r wait 500 pE for r Clock EIgb
BS2RIJOOI'2 : CoitrClock BS2I€kips j, f. BS2RLoop2 Bg2Rlirlor
BS2RShLps:
goEo
Retuln
Cdclock BS2RSkiD{ j, f Bs2RLoop3 Bg2RElrol
STATUS, C C@Data STATI'S, C BS2Bl,t€, f
al€cfaz
Datsa
t Wait 15 Fs for t Clock Pu1ae i Activ€
bcf btf,sc baf tlf
btfac golo tl€cfEz goto goto
Meke gure i5 Iry)ut
4 j
BS2RSkiD4:
novlw movnf
Valial
wail t Clock High, it lo qo ].ow i for
BS2RSkID3 ! novlrr novlrf BS2RLoop3:
Down
, Nothlng i R€ceiivetl
baf bsf
nop r.or1w btfBc no9 r{or1!r btf,Ec noD *or1w blfac nqp xorlrd blfac trqp xorlw btfac aop xorlw btfac nop goto
,,
f
r r r t
Clock High Agai!/finishetl with Bit Reaal Anothe!
t t r t t
Cbalge tsh€ Cd[larrtl ODoralion GeE the co@anil Cd[)are tso C@lanal 1
ES2RSkiD3
BS2Prj.rnarl|c@lanal: nrovf :
Bs2Btztse, 1
w
btfac no9 xolIrr blfac
STAIIUS, z - comnand t **#* 2 ^ L SltrAlrOS, Z
1 code t Coraltalal
2?
- Cof@and 2 Coale , **## 3^2 r Corl.rtt STA!!US, Z - cofdland 3 Coale t **#* l^3 r Cdmantl STATI'S, z - Cdmand 4 Cotl€ t **#+ 5^{ , CdmtDtl STAIrOS, z - Cddand 5 Coile t **** 5^5 r Cdmand SIeTUS, z - cdmand 5 cod€ t ##** 7^6 t Cdirnendl gTAmS, z - Cqflranil 7 cod€ t ll**{l 8^7 ; CdmanA STITUS, Z - Colnalat 8 Code r #**ll Bg2$r!or Itnklownlcodlrl€l€d t otherrdLa€,
- Pu! coulalit Eele with t\rDctioas **#* "gtoto Bs2RErlor" to junDa ov€r evoidl havlng funat' **** "switsch" corqrariaoDB asseribl€f
tcl X
3?
id
{?
o
r-t
5?
F,,
6?
3 o
7?
5 cl
8?
coiMenat Filel
BS2RResponalcddandl : lrilbin Ittforllation Retuln lhe R€questseil t 1 lrE to "BS2B!r!e" i anfl rrgoto BS2RResDondl: i bsf STATUS. RPo i llak€ ConData aa OutsDut bcf ComData bcf STATUS, RPo w novf Bs2Btte, t Get Eb€ cor@r'otl lo R€apontl laor1w 0x81 i Corltrare 1 t C@raad btfac SrAtUS, Z - R€a9ond Codrald 1 Coal€ noD r *##* xorlw 0x82 ^ 0x81 i CdE ar€ to Responal 2 t CdEand srATtrg, z btfsc 2 codl€ nqp t *#*l+ - ReEDontl cdalanfl xor1$ 0xa3 ^ 0x82 r Collpare to ResDordl t Co!trranal 3 btfac SllAllUS, Z - ReEDolal Conlanal 3 Coile aop t **** tso ReaDondl xorld 0x84 | 0x83 i Cot[tale 4 , CotElald gfATUS, Z btfsc tro9 CotElend { Cotl€ , #*## - Iteapoait to ReaDonal xorlw Ox85 ^ 0x84 i Codpare 5 t cdrland gTATgg, z btf6c 5 Coale noD r l+lf #* - R€apond C@lantl ,ro!1w 0xg6 ^ 0x85 i CoaE ere to ReaDoatl t codnnenal 5 gIATttS, btsfac Z - ReEgonit C@lanal 6 Code noD r li#*lf xolLw 0x87 ^ 0xg5 t CorqDare tso Reaponfl 7 , CoMlantt blf,sc STAEUS, Z - RealtoDd Cotnaatl 7 Codl6 Dop , ***# *orlrd 0x88 ^ 0x87 i Coqpar€ to R€apond g t Cdmand btfEc aop lrovlw
STATUS, z - Resgond Cdmanal , **** 0t 15 r C@la|rfl
I
Coale Not
O
o\
I ry H
o K
o
c H
p
a d l-t
6
I o p
ct H
p
d
o
rt
Fh
0,
o o
5 e c t i o nT e n
Sensors
233
G,}
movwf
BS2BtrUe
d
golo
Bs2RR€sDonal
{r a }{ ,it
IJ
4J ;J F{
l-a
Bs2RReEpondt: rnovlw 8
novlw novwf lrovl.w Bs2Rr,ooD4: btfsc golo aaLllw btfsc alecfBz golo gtoto Bs2RgkiDS: rrf btfsc bsf, btfsB bcf, movlrc movlrf BS2RLoop5:
U s g.i
btfaB goto dlecfaz goto golo
r*; BS2RShipT: r--N nrovlw novwf & rrovhr I I In
BS2RError
i i
ghow
to
FiniBh€tl, anal Keep
Retutn Proceasing
€nd - Execute ***# RegDontl cotElandts t Executso ldithL! 1 rns
novwf
L'
goto
; Supgortodl t Bi! Pattern t coanection
gt
CounE Nunber Bita to sentl
To operatethe applicationcode,I modified asmBS2 Ifasm to get asmBS2Test.asm by makingthe following changes:
of out
i
1.
HIefl (2500 + 255) j low (2500 + 255) for Deta i wail becdre Active Cqlclock BS2RSki95 -1 z STAmg, j, f BS2RLoop{ BS2RError
BS2Byle, STATOS, C CotnDala STATUS, C CdDaEa
f
2. to
3. 4. 5. Bits Bits
6. i
Deta
Bit
Higb
i
Data
Bi!
Lor,t
"ComClock" and "DataClock" were changedto RA1 and RA0, respectively, For "Command l," replacethe nop with "bsf PORTA,4." For "Command2," replacethe nop with "bcf PORTA,4."
lhe Data i OutDut t Put the LS Data into calry
4 j Wait 15 ma€ca fot Clock PuIa€ Activ€ Comclock BS2RSkiDT j, f BS2RLooD5 Bg2REfior
The xor*{/btfsc/nop instructions for the remainingsix commandswere deleted. For "RespondCommand1," the "btfsc STATUS, Z/nop" wasreplacedwith a "btfss STATUS, Z/goto InvalidReturn."And the following xorl btfsc/nopinstructionswere deleted. After "goto InvalidReturn,"the following instructionswere added:
novllr btfac {rovlw novwf goto
O
,
novwf
BS2Bf.le
Wait fo! to Enal
Hrclr ( 3 0 0 0 + 2 s 5 ) j rJow ( 3 0 0 0 + 2 5 5 ) wait 3 na for High
clock
Codclock Bs2RskipS -1 SEATUS, z j, f Bg2RIJoop5 BS2RErro!
BS2RSkiDS: alecfaz i, f golo Bs2RSkiD5
i uor€ i
Bit6
to
S€nal?
Yea, IJooD Aroundl Aqain
R€lurrt
i
CorE|anal Not gu9port6al
i
Bit PatEertr CoDn€ction
to
Sbow
With thesechangesin place,the PIC12F675tnterface connectedto the breadboard with the circuit in Figure10-8,and the PIC16F684loadedwith asmBS2 Test.asm,you can nouTremotely tuln on and off an LED aswell as query the LED's state.To turn on the LED, set the PIC12F675interface'sLCD to 1 and pressthe button-the LED connectedto the PIC16F684shouldtum on. Similarly,settingthe PIC12F675ntertace's LCD to 2 will turn off the LED. Settingthe PIC12F675interface'sLCD to 0x81and pressingthe button will senda command responseand retum zero or one,indicatingthe stateof the LED connectedto the PIC16F684.
.r{ 9 , . ,i!
4",S
234
r,ED gtatse
PORTA, 1l 1 BS2Blrte Bs2RReapontl
hvaLidlRetur!: novLw 0xA5
BS2RIJoopS: btfsc goto etLllw btfsc decf,az golo goto
- MusE
l , e 3 P I C @l l C U E x p e r i m e n t s f o r
the EviI
6enius
krt
t-J
Experiment87-Sound Detection
Prc16F584
;;e" *{
TLC251 LED Elect!et
1v
miclophone
3.3M resistols 2.3M resistols l,ok lesistot 470O resistors PIC12F575- o! PICl5F68 4based BS2 conmrand simuIator inte!face
220O resistors 0.1 pF capacitors 0 .01 ,pF capacitors
DMM NeedIe-oose plie!s Ili!e
stlippers
t r!
Breadboard Wiring
t i
kit
:iSoundinput recognitionis an interestingand often usefulsensorto add to your applications. With just a bit of signal-conditioning circuitry,you can add the ability to recognizesoundto the PIC MCU. Before you start gettingvisionsof addingvoicecontrol to differentelecffonic devicesaroundyour house,I mustwarn you that the circuit usedin this application is quite rudimentary and will not recognizesoundsof differentdurationor frequencies. What you'll get after building this experiment is the front-endcircuitryusedin the "clapper" light switchesthat were popular a few yearsago. The applicationcircuit in Figure10-9is probablya bit more complexthan you would haveexpected. Along with the PIC16F684with its BS2 sensorcontrol interface,I have also included an LED, which flashes when sound is received,and a two-operational-atnplifer (op-amp)circuit,which is usedto filter out highfrequency sounds(defined asanything above 340IIz) and amplify them to useful levels for the PIC MCU to recognizeaslogic level changes.The circuit fits easily on a smallbreadboard(seeFigure10-10).However,if you wanted to add any additional circuitry to the experiment,you would haveto usea largerbreadboard.
I don't want to go into a greatdeal of explanation aboutthe operationof the TLC251op-ampsexceptto explaintheir basicoperation.I shouldpoint out, however,that the componentvaluesare criticalto correct operationof the circuit.If the resistoror capacitorvalues are changed,you will find that different parts of the circuit may go into oscillation.You shouldbe particularlyconcernedaboutmatchingthe impedanceof the electretmicrophoneto makesurethat you maximize the voltage output. If you feel the need to change any of the component values,make sure that you understandthe ramificationsof what you are doing. The electretmicrophoneproducesa relatively small-scale signal(in the tensof mV, asseenin Figure 10-11).Thissignalis passedthrougha dual-poleButterworth low-passfilter, and then amplified an extreme amount.The amplification factor usedin this application is on the order of ten thousandtimes for eachopamp.The reasonfor the extremely large amplification factor is that this application can amplify the signal only to the input voltageextremes. Anything greateris clippedandproducesthe signalseenin Figure10-11. The signal from the microphone is the analog signal shownin the top waveform. By amplifying the signal
S e c t i o nT e n S e n s o n s
235
t{!! 1 a : !;a i i
r& { }
vdd Ptct6F584 RA1
RC4
RC5
J.2 5
Data 1 l
(_L -
t
,'04
Clock
RAO
vdd
TLC25'I
470 3.3M
,s
rF-l .e :
vdd
0.01uFI
TLC251
-T; .5 v
lI :
I
ft '(jt '$i
t-"1 $,4
Figure l0-9
Soundcircuit
by suchan extremeamount,the more digital-looking signalis producedand canbe passedto the PIC16F684'S input directly. There are rrany books available that will explain the operationof op-ampsin greaterdetailthan I will here.Whenyou look at thesetexts,you will seethat
a
t
most of them usethe LM741,not the TLA57 that I usedin this application.I did not usethe LM741 in this applicationdue to its requirementof at least12 volts to operate.The TLC251 works comfortably with the 5 volts usedby this application. There is one problem with this circuit: If the sound transition occurswhen the BS2 interface is communicating with the PIC16F684,the PIC MCU cannot poll the incoming sound line. When I presentedthis circuit tn 123Robotics Experimentsfor the Evil Gmtus,l passedthe signalto a14LS74D-flip-flop clockwith
a-li I
.&r flt "r{ 1 !d{
gsi
Figurc lo-'f0 Soundinput testcircuit buih on small breadboard with BS2 command interfaceproviding signalwiring as well aspower
236
'f Figure 0-ll
l , e 3 P I C @l l C l J E x o e r i m e n t s f o r
Soundoperation
the Evil
6enius
the expectationthat the soundwould causea new value to be latched into the flip flop. To avoid this requirementnow,I passthe conditionedsoundoutput to the TMR0 input pin. Then, after setting TMR0 to OXFFand resettingthe TOIFbit to find out if soundhas beendetected,it is a simplematter of checkingthe TOIFbit asI do in the experiment'sapplicationcode, asmSound.asm.
The simple ability to recognizethat a sound has happened(evenwithout the sound'scharacteristics) canbe usefulin a varietyof differentapplications, rangingfrom the "clapper"to a robot'scollisiondetector. The collisiondetectoris actuallya very usefulsensor in robotsand often more reliablethan whiskersof the infrared (lR) or ultrasonic methodspresentedlater in this section.
I --l .'r|
lt't 1U ,<,
,1
g Experiment BB- Multiple Microsuritch Debouncin
ai-
& G8 1Prcl6F684 a
4 10k res istols 1 0.01 pF capacitor 4 Bleadboard-mountabl.e or SPST push-buttoo switches
PICI2F6?5 or PICl6F684based BS2 cofimand sirnuIator inte!face DMM Needle-nose
pliers
Wire strippels
pins on PORIA, but decidedagainstit when I looked at how I would poll and debouncethe buttons.Instead, I usedthe leastsignificantfour bits of PORTC,allowing me to come up with an efficient method of polling and debouncingthe buttons.Theapplicationitself can be written out in C pseudo-code asfollows:
B!eadboa!d Wiring
?
H. t*J
tv
?
j = 0t (1 == 1) whil€
kit
(
Previously,in this book,I haveshownyou how to debouncebuttons,switcheqandkeypads(in both C and assembler).What I havenot doneis showhow multiple,independentswitchescanbe debouncedin an environment that can be polled periodically. In this experiment,I will usethe BS2comrnandinterfaceperiodicallyto poll a PIC16F684wired with four buttonsor switchesthat mustbe debouncedbeforea valuecanbe retumed.Thisis very similarto what would be donein a robot that hasseveralwhiskersaroundits penmeter. The circuit usedfor this experiment is quite simple andcanbe built on a smallbreadboardwted to a BS2 commandsimulator-either the PIC12F675usinga potentiometercommandselectionor the keypadinterface(seeFigure10-12).WhenI wasdesigningthe application,I debatedwhetherto usethe pulled-up
// //
// //
// / /
for (i = 0t i < 215 usi i++)t I.oop takea 250 ua (0 == BS2Clock) if Clock Lotr' - ES2 Cofidland BS2Read( ), (0 == (PoRrc & ( 1 << j)), if Bit i-a IJow (0 == value ti I ) if Blt vas P!€viousLy IJow (Count. [j I < 20] if Counts=Count+1t elBei Count == 20. Do Nolhing elBe BiE $ae Pr€viou61y High
h*
t
ra
valuetjl = 0, Count [j I = 0, j ll fr elae // Bir iE high if (1 == valueljl ) High / / B..E vae P!€vloualy if (counttjl < 20) count=count+1i
ii,
1.3 ?.t
l-r '
S e c t i o nT e n S e n s o r s
237
elset == 20, Do Nolhing count else Eow // Bit vraa Previoualy //
{ va!.ueti] counutil |
//
= 1t = 0t
fI
j = 6 + a l % 4 t j to next // Increment // elihw )
value
In this2507:.is loop,one of the four switchesis polled,and if its valueis differentfrom the previous poll, the new valueis savedand the counteris reset.If the valueis the same,the counteris incrementedto 20. With eachloop taking 250ps and executingfour times betweenpolls,a count of 20 will meana 20 ms debounceperiod.The216ps delayloop,when added to the 34 g.spolling codetime,resultsin a 250pcsloop. The assemblycodefor this operationcanbe found in asmUSW.asm. This codecouldbe expandedquite easilyfor more buttonsor reducedasrequired.(Six couldbe made availablequite simply,by addingRC4 and RC5 to the
Figurel0lP
B32 uSwitch
four alreadypresent.)The codeexecutesin just a few instructioncycles,allowingyou to add additionalsensorsor BS2functionsto the mix quite easily.
Experiment 89-Light 5ensors Ple!n[t"
1 1 Prc16F684 L0k resi stors 10k light resistors with light
dependant (R decreases )
10k potent iometer 0. 01 pF capacitor
Tool
Box P I C 1 2 F 6 ? 5 o r P I C 1 6 F 6 84 based BS2 comnand simulator interface DMM NeedIe-nose pliels l{i!e
strippers
Breadboard Wiling
kit
In the previousexperiment,I showedhow you could time sharebetweenoperationsto checkvalueswhile polling for BS2commands.Inthis experiment,you will get the chanceto experimentwith differentwiring of
238
light-dependantreslstors(LDRs) or Cadmium Sulfide (CDS) cellsaswell asIook at a methodof reading eachADC individuallywhile polling for the BS2commands.Thismethodof operationis not compatible with the previougbut either the microswitchpolling methodor the one in this experimentcouldbe modified to work with the other. To demonstratethe operationof the CDS cells alongwith how the ADC works for multiple devices,I usedthe circuit shownin Figure10-13.TheSPDT switchshowsthe high- and low-voltagelevel provided by a simpleswitch,and the LDR connectionsshow how the voltagedivider output voltagechangeswith the LDR resistancevalues.Thein-circuitpotentiometer shouldwork exactlyasyou expect.Thatis,the
l , e 3 P I C @I ' l C l JE x p e r i m e n t s f o n t h e E v i l
Genius
ADC valuereturnedfor the potentiometeris proportional to the positionof the wiper. The applicationcode(asmlight.asm)for the experiment is very straightforwardand readseachADC valuetwicebeforesavingthe value.Readingthe value twiceis simplyto ensurethat the valueto be readis correct.Thecodeis calledasmlight.asm.When you test this application,you shouldrecordthe ADC valuesfor the LDRs whenthey are exposedto ambient light and againwhenthey are shieldedfrom the light by a finger.(TheADC valuefor the LDR connectedto Vdd shouldgo down and visaversafor the LDR connectedto the circuit'sground.) The applicationshouldwork quite well,with only one possiblesurprise:Youmay find that valueof either the high- or low-voltagelevel returnedfor the SPDT switchis off by a few digits (a valueof 0xFFor 0x00, respectively, is expected).Thisis due to resistances throughoutthe wiresand breadboard,which cause smallchangesin the voltagesat differentpointswithin the circuit (a singleADC digit represents17 mV in this application).The reasonfor pointingthis out is to rein-
Ptc16F684
":_r 6".+,,,. -o:i
{"-1;
II
I
.5 V
Figure 10-13 BS2 light
: force the idea that nothingis absolutein electronics circuits,and you mustalwaysdesignyour circuitry and softwareto accommodatetheseinconsistencies.
Experiment90-lnfrared (lFl)SurfaceSensor
1 PICI6F584 1 2N3904 NPN trans istor I
U-shaped IR opto-inte!(see text) luPter
L LED 3300 resistors IOk resistors 1 0.01 gF capacitor DMM
1 Breadboard-mountable SPDT switch
Needle-nose pLiers Wile
clj.ppels
Three-cel.1 clip
Wire strippers
AA alkaline (see text )
Breadboa!d Wiring
kit
In 12j RoboticsExperiments for theEvil Genius.I demonstrateda basicline-followingrobot usingtwo cut-apartU-shapedIR opto-interrupters. If you look backat thoseexperiments(numbers48 and 119in that book),you'll seethat by cutting apartthe two halvesof the opto-interrupterand placingthem sideby side,you
AA battery batteries
could make a fairly effectivewhite/blacksurfacesensor.Theproblemwasthe cfucuitsrequireda fair amountof supportcircuitrydue to the requirementsof amplifyingthe currentfrom the opto-interrupter's phototransistorand comparingit to an expectedvalue. The built-in comparatorsof the PIC16F684allow you
S e c t i o nT e n S e n s o r s
239
:. .,:
to simplifythe circuitryconsiderablyasis shownin Figure 10-14.With just a few resistorsand a transistor,you canproducea voltagethat canbe sensedby the PIC MCU and canbe coupledwith surprisinglysimplesoft ware. Thesepartsgo by a varietyof names,including "slottedIR opto-interrupter"and "IR switchOptoNPN" if you werelooking in a catalogor online,be sureyou seea pictureof what you are getting,because the devicesvary widely.Another issuethat you should be awareof is that if you wereto buy the pa s from a distributor(e.9.,Digi-Key,Mouser,Jameco),you'll probablybe quite shockedat the price,especiallyconsideringI'm tellingyou to cut them apart (seeFigure 10-15).Thereare alsoIR reflectivesensorsthat perform the sametask asthe cut-apartopto-interrupter,but thesetoo canbe quite expensive. Rather than be subjectedto the high pricesof new opto-interrupterEI buy a few from electronicssurplusbins for a just a few centsapiece. Buying the partsfrom a surplusbin meansthat you will not havea part numberor a datasheetfor the part. Instead,you will haveto build a circuit like the one in Figure10-16to determinewhich set of pins are for the IR LED and which set are for the IR p hototransLstor (PT) that makeup the opto-interrupter.Assumingthat the wiresfor eachcomponentcomeout at different ends,thereare only four waysof wiring the circuit.You can do it by trial and error until the LED lightsand turnsoff whensomethingis put betweenthe two sides of the opto-interrupter.Or you canspenda few minutesand comeup with a strategythat simplifiesthe search.For example,to find the IR LED and its polarity,usethe LED and a 3300 resistor.Tiyeachsidewith differentpolaritiesfor the pins and the LED until the LED lights. Onceyou haveidentifiedthe componentsin each sideof the opto-interrupter,recordwhat eachcomponent is,recordwhich wiresbelongto each,cut apartthe
l0-1q
240
IR white/black circuit
opto-interrupter,andthen placethe opto-interupter in a breadboard(seeFigure10-15).This orientation will allow you to run a pieceof paperwith white and black marksover the IR LED and phototransistor. With this done,addthe three-batterypower supply,the resistors,and the transistor(seeFigure10-14).Thetwo 10k resistorsand the 2N3904NPN transistorwill producean analogvoltagethat can be very easilysensed by the PIC MCU'S comparators. I decidedto usecomparatorsinsteadof the PIC16F684's ADC becauseI didn't expectthere to be a needfor processinganalogvalues(white/black shouldbe very binary),and the comparatoroutputs can be polled continuously, whereasthe ADC mustbe initializedand then polled until the operationis complete.As canbe seenin the applicationcode,the task ol polling the comparatorand turning on the LED (if somethingis reflectinglight from the IR LED to the IR phototransistor)is extremelysimple. Usingyour DMM, measurethe voltagedifference with somethingwhite in front of the lR LED/IR phototransistorpair and then with somethingblack.I used a white sheetof paperthat had largeblack areas printed on it. For testingthe opto-interrupter,I used with the componentsspecified,the voltageat the 2N3904was3.06volts with the black printed paperin hont of the phototransistorand 0.20volts for plain white paper.For the comparator'sVRef module,I choose1/21hese extremes or 1.5volts. To calculatethe valuepassedto the VRef module,I measuredvoltageat the PIC MCU's power pins (asthe VRef module'soutput is proportionalto Vdd) and found it to be 4.54volts.For the VRef module.I decidedto run it in low-rangemode,which allowsfor
Figure l0-'f5 IR surfacesensorcircuit usinga cutapart U-shapedIR opto-isolqtor
l , e 3 P I C @I ' l C UE x o e r i m e n t s f o r
the Evil
Genius
HI X rd
i
t r
lryke Preilko 05.01.03
LISf R=DEC INCrirDE "plSf
I
584. tncn
(D
-CONFIG _ECUEN_OFF & _IESO_OFF & _BOD_OFF & CPD_OEq & _CP_OFE & _!{CLRE_OFF & _P!iIRTE_ON & & _INToscIo _lfttt_orF
t::o, .
:L-
t
l
f".|,
:t
Veliables CBI.oCK 0x020 ENDC
o
b't
-T: r
I'
PAOE Ueinlin€
r+
-L
nop
Figute lo-f6
ry
IR phototrenststorcircuit
voltagesup to two-thirds of Vdd with a fraction denominator of 24.With this information, I calculated the VRef module's voltage specification value to be: Value = (1.5 volts
/ 4.54 volts)
X 24
As you can seein the software for this application (asmRwb.asm),Iput in a valueof 8 (b'1000')to the VRCON register: "aBnIRwb - Us6 Com9arators tille geDaola" whits/BI.ck
with
clrf movlw
PORrA b,00001010,
movwf
CIICONO
baf, cIrf, movln
STATUS, RPo ANSEL ^ 0xg0 b.10101000,
mofidf movhr novrdf bcf
VRCON ^ 0x80 0!a0r TRISA ^ 0x80 STATUS, RPo
IJooP: movlld blfsc
0 C!{CO!{o, CIOU!
lrovLw lrovDrf
1 << { PORIIA
goto
IJoqp
Eo!
\o
ICD Debug
O lrith t Corqtarato! lilodu1e t Vref
I
I 1.5 r Specify ; Tfansilion ; RC{/RCs
H
volt
l'.{
OutDulB
n
with LED of,f t start t if, Cl.viD+ > i Refarenc€ lben lurn on IJED t
IR
This PrograD PolLs th€ voltage cooiag flom IR LED/PbototralEigtor !!dl turrrB on an LED lrh€a th€ voltag€ ia is greaE€r than 1 VoIl. tfh€ coq)arator La ua€dl for tsbl,a op€raELon, Ea!dfirere Noleat PIC15r58{ runriDg at 4 ! lz U5lng th6 Interagl clock 4.{5-{.5 Volt Pow€r (3:. nAA' Cells} RAo - Phototrrnaialor Output RA4l - IJED Anodl€ RA5 - r,ED calhodo
,
a end
The asmRwb.asmcode could be easily extendedto up to four IR phototransistor modules by selectingdifferent comparator inputs (two for eachof the two comparatorsgiving you a total of four). Although if you do this,I recommendyou do your bestto make sure the opto-interrupters have the samepart number so you do not have to charactedzethe circuit repeatedly and provide different comparator (or component) valuesfor eachinout.
S e c t i o nT e n S e n s o r s
24L
rt l-h
0l
o o w o u
o
Ft
()
ExFeriment 91-lnterfacingto Sharp6Paila0
c{
Flanging0biect Sensors N
tu
t3
1 PIC16F68 4 1 Shalp GP2D120 IR !anging moduLe
l*l
1 1o-LED bargraph
fi
I
tu
di.splay
0. 01 pF capacitor
1 Breadboard-mountable SPDT €witch Thlee-cell clip
Dldll Needle-nose pliers liire
*-r
AA battery
AA battelies
stlippers
B!eadboard Wiring
kit
tTr l-r ,r{ d{
(u H
Sharp has a number of different IR object detection and ranging modules that you can interface very simply to any PIC MCU. In this experiment, I will introduceyou to the GP2D120module,which providesan analogsignalroughlyproportionalto the distance betweenit and somelight-reflectingobject.TheSharp modulesare designedto work usingbetween3 and 6 volts,with 4.5to 5.4volts beingthe rangewherethey work mostefficiently.Other than providingreasonably cleanpower to the modules,you haveto connectonly a singleline to a PIC MCU to read distances. The circuit that I usedfor this experiment is quite simple,asyou will seein Figures10-17and 10-18,andit
shouldnot causeyou too many problemsin wiring it together.The basicGP2D120module hasa white plastic connectoron the bottom,and to useit with a bread board,I simplysolderedthreeshort breadboardwiring kit wiresto the threepins on the backsideof the module (seeFigure10-18). The codefor the applicationis very straightforward and assumesthat the maximum voltageput out by the GPZD120is 3.0 volts.Insteadof displayingthe distanceas a binary value,I use the bargraphas a 10position scalewith a singlelit LED. The application code (asmGP2D12)teststhe voltage output from the GPZD120by repeatedlysubtracting15 from the
a
r-6 L)1
-:-:_-r_, I '
t
I I ___-L
a+ 'f Figure 017
242
GP2D12circuit
Figure l0l8 Prototypecircuit seenfrom the rear of the GP2D120module
l , E 3 P I C @l l C U E x p e r i n e n t s f o r
the Evil
Genius
returnedADC value.The reasonfor taking away 15 is that 3.0 volts measuredin a maxirnum255range for a 5-volt circuit is 150.Therefore.15 is eauivalent to 300mV. I havebeenquite cavalierwith the GP2D120in this circuit becausethe circuit has only one LED active at any time and is poweredby batteries,and the breadboard hasa lot of built-in capacitance. If you wereto usethe GP2D120(or any of the other SharpIR object-detectionmodules)in an application,Iwould
recommendplacinga fairly large(10 pF or greater) capacitorcloseto the module'spower-supplypins.As I will showin the following experiments,IRreceivers canbe somewhatsensitiveto electricalnoise,and in an applicationthat haselectricalmotorsrunning (e.g.,a robot),you will find that the output may be erratic.By addingthe capacitor,you shouldbe protectingthe modulefrom noise,which couldpreventit from operatins correctlv,
?:t v1 i-
':'" ..-:.
1.":
Experiment 9?-Do-lt-YourselflH ObjectSensor ti1j I t P1c16E' 684 38 KHz IR TV remote receiver control
1 -:i
1 IR I.ED 1 LED L l0k I
lk
t-x
!esisto! resistor
1 470O !es isto! 1 100O !es isto! DMM
1 lk Breadboald-mouotable potentiomete!
Needle-nose pliers
1 0 .01 pF capacito!
Breadboa!d Breadboald
wiring
1 47 pF electrolyt caPacj.!ol.
kit
i?
ic
i.t
1 Sntn btack heat-shrink 1 to 1.25 inches tubilg (2.5 to 3 cm) in length
f':' ti
1 Breadboa!d-mountable
When Ben Wirz and I designedthe "TAB Electronics Build Your Own Robot Kit," we spentabouta month strugglingwith coming up with a way that objects couldbe detectedusingsimplewiresthat,when moved,would closeor opencircuits.An enormous amountof work wasdone to comeup with a design that wassensitive(would detectan objectwith enough time for the robot to stop),robust(requiredno bending of wiresbackinto shapeafter a collision),reliable (madeno "false"hits),andinexpensive. The solution that we cameup with wasa noncontactmethodof detectingobjectsby usinga modulatedIR light beam and a TV remote-controlreceiver.You would probably be surprisedto discoverthat this methodoutperformedmechanicalswitchesin eachareaoreviouslv
5P51
StdLCCn
1 Three-cel,1 clip
AA battely
ii{
3 AA battelies
,:;
listedin this book and it wascheaperto implement.In this and the experimentsthat follow,I will presentyou with somenoncontactobject-detectionmethodologies with which you can erperiment. When you usea remotecontrol to turn a TV on or off or changethe stationor the volume,the remote controlin your handis usuallysendingout a modulatedstreamof IR light pulses.You may have
S e c t i o nT e n S e n s o r s
243
L.{ i-) !:!a itt
*1 ! f
I
et .Y'a
3.3.i1
.r*s >a L,-{
!
fq
discoveredthat the remotecontrol can"bounce"its output signaloff differentobjectsin the room (e.g.,the wall behindyou) and the TV will respondasif you werepointingthe remotecontrol directly at it. This is the theorybehindthis experiment;asyou canseein Figure10-19,lightis bouncedfrorn an IR LED to aTV remotecontrol via someother obiect.Earlier in this section,an IR white/blacksensorperformeda similar function,but the distanceat which it works is limited to a half-inch(1 cm) or so.The circuit presentedhere can detectobjectsasfar asseveralfeet awayand will evengive you someidea of its distance,asyou will see in the next experiment. Consideringit costsjust a few cents,the TV remotecontrolreceivers(suchasthe SharpGP1UD series) are amazinglycomplex devices.They continually monitor the incomingIR light andrespondto a signalthat is modulated(turned on and off) at 38 kHz. Insidethe TV remote-controlreceiver,the input signalis processed, the and if a 38 kHz signalis encountered, open collector output is pulled low, which allows multiple receiverson the samecircuit. Amazingly it will filter out any constantsignalsand continuallyadaptto its environment.What I discoveredwith the TAB Electronicsrobot is important:It will learnto filter out any continuous38 kHz signalasnoiseif it is left activefor more than a few millisecondsThis is why in Figure1019,I havedrawn a PWM signalthat allowsthe 38 kHz signalto be passedto the IR LED only periodically. Figure10-20showsthe signalsentto an IR LED and the responsefrom a TV remote-controlreceiver;the in the output is delayof severalhundredmicroseconds simplytheTV remote-controlreceiverrecognizingthe incomingsignaland then recognizingthe signalhas stopped. To demonstrateusing an IR LED and TV remotecontrol receiverfor objectdetection,Icameup with the circuit shownin Figure10-21.It'swired with the IR LED bent over and pointingin the samedirectionas the TV remote-controlreceiver(seeFigure10-22).The
IR LED hasa f-inch (2.5cm) pieceof black heatshrink tubing placed over it to direct the IR waveform away frorn the TV remote control. The circuitry shown in Figure10-22is actuallythe circuihy for the next experirnent.The four LEDS are usedto determine the rangefrom the circuitto anotherobject.Only one LED is required for this application. The 1k resistorandpotentiometerusedin the applicationis to limit the amountof currentbeingpassedto the IR LED and thereforeto limit the light output from the LED which will help set the point where objectswill be detected.Thisschemeis often usedin robotsto limit the detectionto 1 foot (30 cm) or so, eventhoughit is not really a recommendedmethodto A better way will be limit the detectiondistance. shownin the next experiment. The first application for testing this circuit is asmlR.asmand simplydelaysfor 50 ms the sendingof 10pulsesto the IR LED. As the signalis beingsent, the TV remote-controloutput is beingpolled,and if the signal is active for two cycles,then the application acknowledges an objectis in front of the circuit. tits1e
"asmlR
Your
own IR
Obj€ct
Thi6 Progr€m Outpul6 a 38 KHz Sigrnal (25 |rs Periotl) aigual a for 10 Cyclea anaMonilolE IR Tv Rdlole Contsrol Receiv€! for reflectionE.
r t t ; r i
Haltlware Notea: PIC15F68{ running at { MHz using the Inlernal Clock Input RC{ - IR R€ceLve! Rco - rnaicator rJED RC5 - IR IJED OulDuts
t i
Myk€
Pretlko
[nnnlnnnt ltltL|il1i1;*__ -IR LED
! 1
a lR LED
0.5%OutyCycle PWMRunninsal20 kHz
OpaqueBarrier
,rd { r
Contrcl Signal 10k?
te{ !c.c
RoIl
i r , ; r
m irt
-
#
ig
**:*:T
5
Reflected SignalReception
€
p u H lJ.oDelctll
Figure l0-19
244
IR detectortheory
i*
5 v
Figufe l0-40
l , P 3 P I C o l l C U E x o e ri m e n t s f o r
100.tr9
IR operation
the Evi I
6enius
Iroop: novlw novwf movLw atltllw blfac flecfaz goto
Fisure l0-al
clrf
IR detectcircuit
HIGH ((50000 / 5) + 256, Dlay Low ((50000 / 5l I 256) -1 tbe ; Wait to Repeat , Test STATUS, Z Dlay, f S-3 ; 5 C-ycle Deley I.ooD i for 20 ma l 20
movrdf IRLoop: goro goto btfaa
PORTC, 4
.T; l l
xo!!rf
Figure 10-22 Breadboardcircuit usedto detect objectsand measurethe distanceto them ,
05.01.03 IJISI R=DEC I N C L TD B n p 1 6 f 6 8 4 . i a c n
1 < < 5 PORTShaalolr, PORTShailow PORTC
fl€cfaz goto
IRIJooIt
novlw aubwf
4 j,
novf aEallw btfsc lorhr lrovwf novwf
PoRTghatlow, or
t r r t t r i , i
nJ. coutrta lh€ Active IR Sead 10 cr,clea. c:tcl€ at a t:ine OutsDuts 8 qlclea Count Lotlr Iilt Delay Fu].l 13 C?clea in IlooD
i i i i
Poll IR R€c6iv€ If, Rea€t, Increlrents Counler roggle RC5
,
org
0
aqD cLrf cllf movlw
t
Coqrarators
TRISC ^ 0x80, STATI'9. RPO PoRlsbailow
0 5
right r Vj.6ibte , OulDuts , IR IJED Oulgut
, CL€a! , Out9ut
r,ED
lh€ PORTC Valu€
\o N I
I
U
Aglaia?
i trou! Po1ls lrow? t Carry get if Four re i
Tur!
,
Cerry
H
on IJED? s6!,
j
>= {
2 -
Ro11 Your
F
o v
OleD IR
o n
r+
a
o
3
a
o
r-J
Obj€ct
llhia Progrem Oulputs a 38 KHz Siqlal (26 Ea 9erioal) .ignal for 16 CalcIeE uEing the ECCP Ptt!{ a!41 Monitora a IR fV Remole Codtrol Recel,v€r for refleclions. Ealalwale !{otes3 PIC16E584 rurr.oing al 4 llHz Using the Internal Clock RC{ - IR Receiver Input RCo - htlicator LED
S e c t i o nT e n S e n s o r s
o
H
w
I'aEnIR tille Detectorn
C!{CONo STATUS, RPO INSEI. ^ 0x80 TRrAC ^ 0x80,
clrf
ICD Debug
PORIA PORTC 7 i
novtrf
For
3
rF
Although asmlR.asmworks perfectly,Iwantedto come up with a way of performing the sameoperation using the CCP's PWM c cuitry. Instead of having to come up with the 38 kIIz signal for the IR LED in software,the PWM can do it and tell me when it is complete by using the TMMIF flag and the 16-times postscaler.This has some advantagesthat will become apparent presently.The changedapplication is called asmlR 2.asm.
uainlirre
l-r.
anfl
€nd
vari€lc1€s CBLOCK 0x020 i, j DIay PORTShadlolt ENDC
Ff
X
& _BOD_OFF & _colltr'lo _ECME![_oFF & _IESO_OrF _CPD_OAF & _CP_OFF & _!'ICLRE_O!F & _plfR!!E_ON & _}IDT,OFF & _INTOSCIO t
(D
A/2
w
t LooD
rrl X ,rd
245
RC5 -
15
Rua 1'MR2 for cycLes
b,01111100'
IR LED Outpu!
!!2CON $yk€ Prealko 05 . 01. 03 LIST B=DEC rNcrJr[rE rp16f 684. incn -CONFIG _FCIIEN OFF & _IESO_OFF & _BOD_OEF & _CPD_OFF & _CP OEF & -!,!CLRE_OF!' & _PVIRTE_ON & _WDT_OFF & _INTOSCIO
*"4
t
Variabl€s CBI,oCK 0x020
DLay PORTShadlow ENDC
ni
v*
t
STATUS, RPO TRISC ^ 0x80, STATUS, RPO
cl!f
i
IRIJOOP
b!fsB
PORTC,4
incf btf,Ba
PIR1,
bBf bsf
0 nrovwf r For
:--
,'.-Jl
rlovlrtr
rci,tt !
PORTC 7 cltcoN0
b'00001100'
mowf movl$r
ccPlcoll 13
Enable ECCP
P!0tiI Modle of
CCPR].L
b..:i
RPo sTAllrgs, ANSEL ^ 0x80
mov\tf bcf
PR2 ^ 0x80 TRISC ^ 0x80,
bcf
STATUS, RPO PORTShaalow
0
i visible r Output
r,ight
r,ED
clea! lhe PoRTc OulDuts Value
Repeat tbe
i T€EE
i; i:.j
s
STATUS, D1ay, f
cLrf bcf
TMR2 PIRI,
t:1
Z 5 Cyc].e DeLay for 20 ns
TIIR2IF
fo! out
IRlooD STAITUS, RPO TRISC ^ 0x80. S|!ATUS, RPo
5
i
IR tED Output
r Tllrn
b,01111000' T2CON
off
TMR2 Off
30
movf anatlw btfac iorLw
PORTShatlow, o:tFF ^ 1
goto
IJooD
ahilty Carry
PolLs if
Low? Four
Sel
rs TUIN
ON LED?
sraTus, c 1 PORTShaalow POBTC
Carry
Set,
j >= {
CI€ar EMR2 Reaet Inte:arup! Requeat Flagl
Loop
By usingthe PIC MCU's built-in PWM, I have come up with a method of performing this task that doesnot needcountedassemblylanguagestatements to createthe 26ps-periodwavesentto the IR LED. Becausetheseassemblylanguagestatementsare not required,the applicationcould be written in C (as dernonstrated in cIR.c). In cIR.c,you may havenoticedthat I checkthe poll count for only a valueof 15 insteadof 30,asin the asmlR 2.asmroutine. The reason for this wasmy useof the 16-bitvariablei asthe counterinsteadof an eightbit variable.I assumedthat the codewould take approximately twice as long to executewith a 16-bit counter as it would with an eight-bit counter.The asthe codeworks assumptionmustbe reasonable, without anv issues.
.ft ** *1
X i *--1i
246
TUR2 to
end
Hrcn ( (50000 / 5) + 2 5 6 ) Dlay I , o v r ( ( 5 0 0 0 0 / 5 ) + 256, -t r Waits to
btf,ac flecfEz goco
Wai! Time
, get I'uR2 Perioal
IrooD:
adatlw
ON
"j" eount8 the Active IR 8 cycle6 antl Output Count IJow Rx Don,t. If RC4 Eigh, Irlc!€dr€nt coudt
TIIR2IE
lrovlw aub$f
get th€ Pvt!! output Reael Conlrol
baf clrf
I,ED OulpuI
ICD Detrg
Turn off Cof,E)arators
movlrd
IR
!
go!o
PAGE Mairline org
bsf bcf bcf
l , e 3 P I C @l l C U E x p e r i m e n t s f o r
the EviI
6enius
t{ tt
ExFeriment 93-lH Obiect-Flanging Sensor
tn
ils
tv
t1 Fr.
P r c 1 6 F 5 84
H {D x
38 KHz IR TV remote!eceive! control 1 lR LED 4 LEDS I0k
resi sto!
1k res istor 4? of,) resistors
(A)
100O !es isto! 0. 01 pF capacitor
DMM Needle-oose
CapaCl't,Ol
Breadboa!d Breadboard
wiring
!,
4? /rF electrolytic
pliers
H
Smn bLack heat-shrink tubing I to 1.25 inches (2.5 to 3 cm) in length
kit
w o tf
1 Breadboatd-mountable SPST snitch I
Thlee-cell c1ip
AA battely
LJ,
3 AA batteries
In the previousexperiment,I useda 1k potentiometer to limit the amount of curent that passedthe IR LED. By limiting the current,I dimmedthe LED's output and shortenedthe detectiondistance. The problem with this methodis that it is not very reliableand would be difficult to reproduce in a manufacturing setting.If you look at aTV remote-confol receiver's datasheet, you would discoverthat asthe IR LED's modulatingfrequencychangeqso doesthe sensitivity of the TV remote-controlreceiver.If you assumethat a brighter signal is required for the TV remote-control receiver to recognizeit (when the signal was different than 38 kHz), then you would alsoassumethat a closer objectwould producea brighterreflectedsignaland would only be detectedat a closer distance.The purposeof this experiment is to test this hypothesis. To indicatethe basicdistanceto an object,I modified the circuitry from the previous experiment (see Figure10-23).Theactualdifferencesare minor;the 1k potentiometerhasbeenremovedand three additional visible light LEDs and three 470O currenflimiting resistorshavebeenadded.TheseadditionalLEDs are usedto indicatewhetheran objectis detectedat different modulatinsfrequencies.
o
t! The basefor this experiment's code (asmlRDist.asm)wastakenfrom asmlR 2.asm.One of the reasonsfor using the PWM to generatethe modulating IR signalis that it allowschangesto the values passedto it conditionally.By taking the delayand IR objectdetectcodeof the previousexperimentand placingit in a macro,I wasableto comeup with a code
ff
F
11! !"t (A'{
dJ,
r{
'R LEO Sending38 Kh2 -
\\\
tlt
l|l
,/,/l
///
q
({r=
'A
/n
D
4
Lighl
m
l/R 38 Khz
t{ Figure l0-?3
5 e c t i o nT e n S e n s o n s
IR rangingcircuit
247
novhr novlrf bcf
pelioal Plt2 ^ 0x80 gTATuS, RPo
t
S€l
clrf bcf
1'![R2 PIR1,
nrovlw
b,01111100,
I'MR2 Clear Reget Int€lru9t Requeal FIag Run 1l{R2 f,or 15 cycl€a
fhiE Program outputE a drltl-perLotl (atarling at 38 kxz sigmal, 26 lra Perlotl antl golng to a 31 llEz signal, 32 Ea P6!Lot[) aLgaal fo! 16 cyclea uging tsh€ EccP Ptgll aad l{onitsors a IR w R€trole Control R€ce:iver for reflecliong. D€penallng on whLch gig|ral Proaluced a reflectioa, e gpecific LED !ri1L be lit.
t i i r r
novwf
T2CoN
bsf bcf bcf
STAIIUS, RPo TRISC ^ 0x80, SIIATUS, R"0
t
IR
cIrf,
i
btfsE
PORTC, {
![he aclual frequeacy, Pelc€nt off Pelc€Dtag€ andl Rec€Dliv€ ia lidted in the ltaclo invocalionB
ndBinal
blfaa
PIRI,
lilacroa ar€ Nola! this apDlicabion
ir1
basethat could test different modulating frequencies easily aswell as ouFut object detectionsat thesefrequencieson different LEDs.
${
o
"aBnIRDist tille IR Objecl Detectori
n c o
a
Ut g .F{
ttt
c
-
lteasure
ua€tl
Distance
ext€nsively
with
bhe
goto
Eeralware Not€s: PIC15F58{ ruDniDg at { MHz Uaing the Int€rnal Clock - IR R€ceiver RC{ Input RC3:RCo - Inilicato! LEDa - rR r.ED Output RCs
d
€,
I
fl{R2IF
{J
5
uyk€ Preatko 05.01.07
.a
o & H
I 0a O\ {J
c
(,
g
.l-l
f{
IJIST R=DEC rNcrrtDE .D15f 584. iacn
t
VariableB CBIOCK 0x020
,
Dlay PORTShatio!. E}IDC
11{R2IF
t Wail t fime
STATUS, RPo TRISC ^ 0x80, gTATug, RPo
movLv nrovwf
b'01111000' T2CON
r Turtt
nov].w auM
30 i, !t
r Thirty t carry
mov! a'1tllrr btf,sc iorlw
PORTShatlorr, w oxFF ^ (1 << ledl) STATUS, C (1 << l€d)
i
5
r IR
IRT€st Macro Deriot!, novlrp b'00001100'
the
IJooD
lrovwf, movhr movlrf
CCP1CON / Doriodl CCPRI!
X
baf,
SIATI,S,
l€d , EDabIe r ECCP 2
t
Square
LED Out9uts Off
I'llR2
Po11s S€l if
cleer
!ord? Four
IrED Bit
t Carrtz Set, j >- 30 i so Turn on I,ED
PAGE Maialine 0 t
clrf novl\r
PORTC 7
movrdf
C!'CONo
bsf clrf movllr
STAIUS, RFo ANSEL ^ 0x80 0x30
novwf,
ERISC
bcf
SfATUg,
PWM !{oil€
clrf
PORTSbatlow
^ 0x80
Eor
ICD Det{rg
Wave Oulput
i Botston { PORTC i Bitss are rJight TJED r visible t OutDuls
RPo
of IJooD 3 Dley5 ons rRT€ats 25,
0
RPo
r Clear the PORTC t outpu! value r 38.{6 kHz ,1-.2%/LoO% r P€rioal = 25 ua, r LEDo
kl
248
Off
t CdE aralors
eudrtr
c,
9{
Delay r 5 Cycl€ 20 n6 i fo!
!t'MR2 lo
PORTShadort PORTC
nop
btfac STATttg, z alecfsz Dlay, f qoto $-3
f,or Out
bsf bsf bcf
org
Macloa i DLay50na !{acro t 50 ns D€Iay novLw HrGH ((50000 / 5, + 256\ novwf DIay novlw LOIq ((50000 / 5l + 255. -1 aatdLw r Wait to R€Dea! t Teat
ON
$-3
movwf tnovwf endm
-CO}IFIG _ECMEN_OFF & _IESO_OFF & _BOD_OFF & _CPD_OFF & _CP_OFF & _MCIJRE_OFF & _PV{RTE_ON & _!{DT_OFF & _r!|TOSCTO
IJED OutDut
countE th€ i "i" IR i Active Don,l i If Rc4 High, Coun! t fncrernent
t l
c,
tt'MR2 Peliod
l , e 3 P I C @l l C U E x o e r i m e n t s f o n t h e E v i l
6enius
DlaysomE 6.O%/9O"/" = 28 r Periotl IJED].
rBTes! 28, D1ay5o:lE rBTest
30,
L2.2%/ 60e" = 30 r Periotl T,ED2
2
t 3L.25 k'lz 20.o%/35e" = 32 i P€rioil LED3
DLay5oms IREest
32,
After building the circuit, I tried it with both Sharp and Liteon IR receivers.I wassurprisedat the nonlinear distancesthe differentfrequenciesproducedfor both manufacturers'products.With a fasterPWM base frequency(i.e.,the PIC MCU's clockfrequency),modelingof the applicationcould take place,and a better understandingof the distancedetectionversusPWM frequencycouldbe developed.
3
i..-j ' q-i
l. .j :-,:, :*
;r:t fti
goro
fi-
€nil r.l.,1
:'!1
Experiment 9t-l- UltrasonitrDistance-Flange 5ensor
i"t 1PlCt6F584
1..:,,
1 Polaroid 6500 ultfasonic ranger
i,t
r
10-LED balgraph
dispLaY
.{;i
1 10k resistor 1 0.01 /rF capacito! 1 1, 000 pF electrolytic (see text ) capacitor 1 6-voJ.t lantern (see text )
DMM
battely
Needle-nose pliers Breadboard Breadboald
wiriog
kit
Although the IR Light provideda basiclevel of object rangingto a sensor,the bestnoncontactmethodfor measudngthe distanceto an objectis to measurethe flight timeof an ultrasonicsignal.A numberof demonstrationcircuitsare availablethat you could look at, but the Polaroid6500is very commonlyused,asit is fairly availableandvery easyto interfaceto. In this experiment,I will showyou how to add a Polaroid6500 ultrasonicrangerto a PIC MCU and useit to measure distances. The Polaroid6500is a high-energydevice.When it is active,it requires1 ampereof current.This is why I specifieda 6-volt lantem batteryfor this experiment insteadof the traditionalAA batteries.This batterywill provideseveralampsof currentfor a surprisinglylong
period of time.I chosethis batterybecauseit could alsobe usedto power the controllingPIC MCU without a voltageregulator.When the Polaroid6500is active,it createson-boardvoltagesin the neighborhood of 400volts (DC). whichwill giveyou a surprising shock(and I am speakingfrom experience)if you are not careful.Whenyou are workingwith the Polaroid6500,make sureyou nevertouch a metal objectthat couldprovide a currentpath throughyour body,and definitelydo not touch the metal transducer (the circularperforatedmetalpieceseenin Figure1024) when it is in operation. The circuit usedfor this experiment(seeFigure1025) is quite simple,althougha coupleof thingsshould be noted whenyou are layingout your own circuit. First,you'll notice thereis no on/off switchin this application.When I usedthe traditionalEG1903 breadboard-mountable switch(ratedfor 200mA, not the 1 amp of this application),Ifound therewasa
S e c t i o nT e n S e n s o r s
249
:f; i a i1,:1 :l-i ! f'\
fri
nr,! ,f.i; ,.1i t a
it i'''l ,|?.
tt
r,nnu, "*f ",nn" f:
i;
i
jr :
"rrn"otitisnr' BetweenInit and.--.--1 . Echo(5.4ms)
r,f:
r!1 Ut
b
3 t
Figure f0-e5
Uhra circuit
I I
LJI
:*-i
significant voltage drop through it and the breadboard tracesthat the power passedthrough.I put the Vdd wire directlyinto the Vcc rail and kept the powerpin of the Polaroid6500very closeto it. In additionto the lack of a switchand the needto keeppowerresistancesto a minimum,thereis a 1,000pF capacitor acrossthe application's Vdd and Vss.The purpose of this largecapacitoris to preventany largedrawsfrom
i
"Echo" Response
lr: +
ait
Figure fO-eq Polnroid 6500ultrasonicranging module with circular transducerdisk (from which rlistancesare measured)along with the breadboard experimentcircuirand 6-volt lanternbattery
I
Figure lO-aE
Uhra waveform
the Polaroid 6500from affecting any of the other circuitry (i.e.,the PIC MCU) in the application. Although wiring the Polaroid 6500into a circuit presentssomeunique challenges,interfacing it to a PIC MCU is very easy.As shown in Figure 10-26,the Init pin (pin 4) is driven high, and then the time required for the ultrasonic signal to be sent from and return to the transduceris the time it takesfor the Echo pin (pin 7) to becomeactive. Assuming that sound travels at 1,127feet per second,it takes73.94/rs to travel 1 inch.When deterrniningtbe time of flighl, you have to assumethat the signal actually takes 147.88pcsfor eachinch, to account for the time out and the time back. In the application code (asmUltra.asm),I rounded up the tirne of flight to 148ps per inch to measurethe time it takes from when the Init pin becomesactive to when the Echo pin acknowledgesthe signal. In asmUltra.asm, whenyou look at the LED bargraph, remember that the fust LED indicates the distance from the transduceris between 0 and 1 foot. The secondLED indicates1 foot and 2 feet,and so on. If the distanceis greater than 10 feet (or an echo is not returned),the first and last LEDs are turned on to indicate the error condition.
: .
250
l , P 3 P I C @l l C U E x p e r i m e n t s f o r
the EviI
Genius
Experiment95-Hobot lFlTag
1Prc16F684 2 38 KHz lR TV lemotecontrol receivers ]. ]R LED High-intensitY LEDs 1 Yellow/Red I
4.7k resistor
4? OF electlolytic capaeitors
DUM wiring
LED
2 100O lesistors
BS2-based robot
Breadboald
white
kit
I don't go out of my way to watchthem,but anytime "Robot Wars,""Battle Bots."or other robot combat showsare on, I love to tape them.It's a lot of fun watchingtwo robotsduke it out with partsflying everywhere,althoughI shudderat the amountof work that is beingdestroyedin just a few minutes.I would love to take part in the competitions,but I would like somebodyelseto rebuild (and pay for) the robots.In this experiment,you can havemany of the thrills of robot fighting,without the mesEcost,and effort of rebuilding.Thisexperimentwill let two, or more, robotsshootat eachother with beamsof lisht and recordthe numberof "hits." The circuit and softwarepresentedherewere originally designedfor the "Thb ElectronicsSumo-Bot Kit," which I codeveloped, but they could be transferred directlyto any other microcontroller-based robot fairly easily.In the photographof the circuit mountedon a Surno-Bot(seeFigure10-27),you can seethe IR LED cannon,enclosedin a pieceof 5mm heafshrink tubing,alongwith the IR receiversand four indicatorLEDs.The operationof the circuit is quite simple,by pressingthe one-barbutton on the robot'sremotecontrol,a speciallycodedsignalis sent from the IR LED cannonto anythingin lront of the robot (e.g.,anotherrobot). If the robot receivesa hit from anotherrobot (the operationof the application preventsa robot from hitting itself),it registersthe hit
Length of 5rnm black 1 heat-shrink tubing, to 1.25 inches (2.5 to 3 cm) Iong
and incrementsa counter.This countercan be set for one,five,or an unlimited numberhits until the indicator LEDs flash,letting the world know that the robot hasbeen"killed." Normally,threehigh-intensitywhite LEDs flashin sequence to allowlight-seeking. autonomousrobotsto find and shootat a human-controlled robot.When a robot hasbeenhit five times.the countercan be resetfrom the BS2,
Figure l0-a7 Fronl view ofTAB ElectronicsSumoBot showingoff itsIR LED "cannon,"receivers, LEDs, and controllingPICl6F684
5 e c t i o nT e n S e n s o r s
25L
With the robot controllingthe motorsand providing basicguidance,the circuit in Figure10-28takes careof the businessof shootingandregisteringhits. If you havea Sumo-Botor a ParallaxBoe-Bot,you might think the circuit will be difficult to wire on the smallbreadboardsthat comewith the robots,but this is really not the case(seeFigure10-29). Thereare a few thingsyou shouldbe awareof when you are assemblingthe circuit: .
The bright white LEDs shouldbe arranged120 degreesapart.This is important to allow autonomousrobots a chanceto "see" their competition and know when to fire on them. The IR LED must havea pieceof 5mm heatshrink tubing placedover it. If the heat-shrink tubing is not in place,the robot'scannonwill havea much wider than 5{o-10-degreefield of fire and be ableto hit its competitorsvery easily.
.
i
,
.
.
The IR receivers'leadsshouldnot be trimmed so they stick up high abovethe robot. As I have outlined the circuit layout,they shouldbe placedroughly back to back to ensurethey receivesignalsfrom all around them. Before startinga tournament,I highly recommend that the two robots are placedfacing eachother,and that one shootsat the other until the other startsflashing.Thenreversethe process. This is lessto ensurethat the receivers are in placethan to make sure the cannonsare properlyaimed.Becausethe cannonsare going into breadboards,they can be easilydislodged and put back into the breadboardsincorrectly. Before the competitionstarts,everybody shouldbe confidentthat his or her robots can fire.This processwill alsoensurethat a competitor hasnot commandedthe PIC16F684to turn off receivinghits from the two IR recervers.
'
Ptc16F684
LEO
I
( . , Labels Indicate Robot Power/8s2 Conneclions
Figure l0-28
IR tag circuit
Figure 10-29 IR tag layout on aTab Electronics Sumo-BotBreadboard
252
The PIC MCU softwarehasresidedon a PIC16C505, PIC16F630, and PIC16F684.It is quite versatileand easilyported to different devices.I have taken out the conditionalassemblycodefor the lowend (PIC16C505)executionto try and make it asreadableaspossible.(You may think this wasa losing battle.)However,I want to point out that the condi tional assemblycodewasusedonly for disablingthe comparatorsandADC (whichthe PIC16C505does not have),changingPORTA in the PIC16F630and PIC16F684to PORTB in the PIC16C505,and taking advantageof the TRIS instructionof the PIC16C505. This lastchangewasthe most significantand potentially the most confusingwhenyou read the code;to provide a one-instructionaccessto the TRISA register, I placedits addressin the FSR registerrather than setting and resetting the RPObit of the STATUS register. Table10-2liststhe differentBS2 commandsthat are built into the PIC16F684for controllingthe IR tag circuit.Thesecommandswere chosento give the user asmuch flexibility aspossible.Note that the only BS2 commandthat returnsvaluesis 16,not 0x81that I use in the BS2interfaceapplicationspresentedin this book. I createdthis application(asmlRTag.asm) beforestartingthis book, and I followedthe BS2interfacebuilt into the Sumo-Botrather than thinking of a more genericstandard.Second,noticethat the robot will fire only oncea second,and if the hit-counter valuehasbeenreached,it can no longerfire until it is reset.
l , a 3 P I C @l ' l C l JE x o e ni me n t s f o r
the EviI
Genius
I alsohavelisteda sampleSumo-Botapplication (calledMax 5 Tournament.bs2) for a five-hit toumament competition.Thiscodeis loadedinto the robot's BS2and allowsthe robot to be controlledby the robot'sremotecontrolaswell asfire at its opponent. This circuit (and software)hasbeentestedon a vari ety of differentSumo-Botsand hasbeenbuilt by a fair numberof people.Throughquite a bit of testing,we havefound that the five-hit tournamentseemsto be optimal,givinga minuteand a half of combatand an opportunityfor somebodyto comefrom behindand win.The toumamentsare very excitingand asfun as watchingother people'srobotsdestroyeachother on TV.
Table 10-2 lF B5e Eommandssupported bs the PlEl6F6Br-{ Tag MiErocontroller Eommand
Value Comments
TagFire
1
Fire onceper second.No firing when robot "killed"
TaglROff
2
Turn off the IR sensors
TagIROn
3
Tum on the IR sensors(defaultcondition)
Tagwhiteoff
4
All three white LEDS are turned off
TagwhiteAll
5
All three white LEDS are turned on
Tagleftwhite
6
Togglethe stateof the left white LED
TagRightwhite 7
Togglethe stateof the right white LED
TagRearwhite
Togglethe stateof the rear white LED
8
Tagwhitecycle 9
f€t t
t't yv4
,4 1tJ Fq
L.'l
white LEDS cycle(defaultcondition)
I
Taglndon
10
lndicator LED on
Taglndoff
11
Indicator LED off (defaultcondition)
TagHitclear
12
High counterclear
p
TagMaxHitl
13
Maximum t hit beforeLEDS flash/firing stops
0 FT.
TagMaxHits
14
Maximum 5 hits before LEDS flash/firingstops
TagNoMaxHit
15
No maximumhits (defaultcondition)
TagcetHitNum
16
RETURN the number ofhits in the counler
i
.!. t
$rt
ry rx*
S e c t i o nT e n S e n s o r s
253
Section
Eleven
Motorfontrol PIC12F575 or PICl6F58 4based BS2 cotnnand si-mulator intelface DMM c^1
rarr
n^
t r^n
Solde! Needle-nose pliers Wire clippers Breadboard k j.t
Wiring
S ci s s o r s Krazy Glue I
1 B!eadboard-mountable
P r c 1 5 F 6 84
1 L293D motor
driver
DC motols
chip
2N3904 NPN bipolar
transistors
1 Bipolar
2N3905 PNP bipoLa!
transistors
t
1N914 (1N4148) silicon disp lay
1 Fou!-celI
I
Servo connecto!
(see text )
I
SIP I
Thlee-cell
poten-
Six-pin text)
(see text)
selvos clip
AA battery
clip
batteries
0.100-inch
Four-pin text)
0.01 pF capacitor
motor
A,A battely
AA alkaline
4 10of,) resistors 10k breadboald-mountable t iomet e !
steppe!
Radio control
diodes
10-LED barglaph
resistor
stepper moto!
Unipolar
I
1 470f, 1o-pin
SPST s!ritch
0.10o-inch
header heade!
(see (see
Ca!dboard
I expectthat you feel you understandsmallDC motors very well;you'vebeenexposedto them sinceyou were a smallchild,in toys and differentdevices.You've probablyseenhow you canreversethe directionof motor rotation by switchingthe polarity of the battery that drives.And, you surelyknow that you canchange the speedof the motor by addingmore batteries.It doesn'tseemlike thereis muchmore to understand. As it tums out, there'squite a bit more,especially whenyou considerthat the basisof all typesof motors ts the inductor(or coil).To devisedifferentmethodsof controllingcurrentandpower to the inductor,you needto be awareof the moderateto high currentthat passesthroughit and of the "kickback" produced when the amount of current passingthrough the
inductoris changed.An inductorstoresenergyasa magneticfield.When the currentpassingthroughthe coil is changed,the coil resiststhis change,asit will causea changein the amountof energystoredin the magneticfield. This resistanceto changetakes the form of largevoltagespikesand currenttransients. Figure11-1showsa simpleNPN transistorcontrol of an inductor.The diodebesidethe inductoris a kickback diode,designedto absorbthe voltageand current transientsproducedwhenthe transistorturns on and off.When usinga bipolar transistorfor motor control, this diode must alwaysbe present.This circuit can be usedasthe basisof a DC motor control by changing the inductorwith a relay and then wiring the application. asshownin Fisure 11-2.
255
' "Kickback" supressing diode Figure l'f-l
Coil control
Fiqure fl-?
Relaycontrol
r{
G f''l "tJ
o
U
t4
u
L.i
X , ,
$ P
CI !*{
l![
ti ! t
"rg , t
Eu
The relaymotor-controlctcuit of Figure11-2is the first approachmanypeopleuseto controllinga motor. This is disappointingbecauseit is redundant,especially comparedwith the single-transistormotor control of Figure11-3.Thereare reasonsfor usinga relayin some applications;for example,the available driver transistors cannot switch enough current to effectively power the motor or the voltagedrop throughthe transistoris too high for the motor selectedfor the applicationto work at full power.But for the mostpart,you should be usingthe simplesingle-transistor motor control. Not only doesthe circuit control the basic operation of tuming on and off the motor, it also allows very fast switching of the motor, which in turn allows you to use high-speedpulse wi.dthmodulation (PWM) for motorspeedcontrol, rather than attempting to vary the voltagelevel, which can be very problematic. There is a basicproblem with the motor control shownin Figure11-3:Thedirectionof the motor cannot be reversed.Figure11-4showsapll H-bridgecirczjl in which the direction of current passingthrough the motors can be changedby selectingdifferent
256
Figure lf-3
Motor control
transistors. In this sectionyou will be building a full Hbridgecircuit usingdiscretebipolar transistors,and you will seea common full H-bridge chip that can be usedfor controllingtwo DC motorssimultaneously. A modification to the full bridge is the ftaf Hbridgecircuit(seeFigure11-5).Althoughrequiringliterallytwicethe powersupplyof the full H-bridge,the half H-bridgerequiresonly half the numberof driver transistors.This circuit has advantagesover the full Hbridge,asit doesnot requirecomplementaryPNP or P-ChannelMOSFETSto the NPN or N-Channel MOSFET drivers. In this section,I will experimentwith a numberof different DC motors.their drivers. and PIC$ MCU softwarecontrolmethodologies. I am goingto assume that you understandbasictransistortheory and the operation of PWMs. By doing so we can focus on how the PIC MCU canbe usedto control DC motorsand what kind of built-in featuresare availableto take advantaseol
Flgure lf -f.l Full H-bridse circuit
l , e 3 P f C @H C U E x p e n i m e n t s f o r
the Evil
6enius
I specifiedthe particularpartsfor motor driversin the followingexperimentsbecausethesepartsshould (a) be easyto find, and (b) work with virtually all motors.The parts are not optimizedfor specific motors,and you will find caseswherethe motorswill not developfull torque,will drain your batteries quickly,and/orwill get warm.Thedrivers,motors,and PIC MCUs usedin the experimentsshouldn'tbecome uncomfortablyhot to the touch.The purposeof this sectionis to demonstratehow the PIC MCU is usedto controlmotors.not how to desisnmoior drivers.
rrl &!f
t?*! 1V fj
*-"' i*e :i?
5 ,€,
Figure lf-5
Half H-bridgecircuit :
a
ExFeriment 9E-DE MotorDrivenUsingthe CfP PIIJM and U5inga Potentiometer Control I
Prc16F584 2N3904 NPN bipola! transisto!s
{ 't'
2N3906 PNP bipolar transi sto!s
;}|;
4 1 N 9 1 4 ( 1 N 4 1 4 8) s i l i c o n diodes 4 100f) !es istors
DMM Soldeling
ilon
So Ide! Need1e-nose $fi!e
pliers
kit
Programming a transistor to turn a motor on and off is a very simple application for the PIC MCU I would expectthat at this point,you would be ableto createan applicationthat senta high output to an VO pin that wasconnectedto a current-limitingresistorand a PNP transistor.In this application,I want to jump dght to creatinga fairly complexcontrol applicationthat allowsforwardsand reverses, aswell asspeedcontrol of a DC motor usingthe full H-bridgecircuit (seeFigure 11-6).Thedirectionand speedof the motor is specified by the potentiometer.When the potentiometeris
,:,
1 B!eadboa!d-mountable SPSf switch
4.";
i.'
:a;
(see text)
1 fhlee-cell clip
Breadboa!d Wiling
9,,
1 0.01 FF capacitor
1 DC motor
clippers
!*
1 10k breadboa!d-mountable potentiometer
AA alkaline
AA battely batteries
centered,the motor is stopped.Whenthe potentiometer is turnedtoward one extreme,the motor will start turning and speedup asthe potentiometerreachesthe end of its travel.If the potentiometeris tumed in the oppositedirectionfrom center,the motor will turn in the oppositedfuection,startingoff slowlyand moving much fasterasthe wiper approachesthe other stop. This is a fairly intuitive interface and one that will allow you to seethe operationof the H-bridge aswell asthe PWM signalthat controlsthe motor'sspeed.
Section Eleven l ' l o t o r C o n t r o l
257
R{t i) Itc l
!
RC4
I
l\ l9c
RC2
.'l-
5.0
I _]_ -:_ Figurel1-5 DC motor circuit Thc cilcuit (seeFigurc 11-6)wasdesignedfor using the PWM capabilities oI the PIC16F684's ECCP,which requiresRC-5:RC2to interfaceto lour motor drivers andrun tr singlemotor in both directions with PWM speedcontrol.My prototypecircuitwasbuilt on a snall breaclboardasshownin Figure11-7,and I useda smallhobbymotor ratedat 4 volts,which I boughtat an electronicsstorc.The strandedwire usedto connect powerto thc motorwassolderedto clippedleadsso that they couldbe pluggedin directlyto a breadboard. As I indicatedpreviously, oneof the purposes of thisexperiment is to controlthe motorsusingthe builfin ECCPPWM anda potentiometer, whichis polled oncccvery 100n]s for controllingthe speedand dircctionof the motor.A PWM frequencyof 15 kHz waschosen,asit allowsa 6,t,stepPWM control output andstillrunsabovethe rangeof mostpeople'shearing.Generally,a PWM control output of 20 kHz is desired, asit is abovethe rangcof hearingarrdwill not affcctother devices. To producea PWM of 20 kHz, a TMR2 resetvaluc of 48 would haveto be procluced, whichrequircspassingone third ol the valueof thc ADC, ratherthanone-halfasI havedonein thisappli catron. Thc ECCPPWM is quitceasyto setup but does not alwayswork properlywhenPNP bipolartransistors are used.asin this expcriment.The high outpul of the Plcl6F6ll4is lcssrhanthevdd appliedto rhePNP transistor, andwhenthe PIC MCU outputwashigh (whichturnedoiTthe PNP transistor), somccurrent flow remained.To climinatethis cun'cntflow,aswell as any potentialcurrentflow to the NPN transistorswhen
258
Fiqure1l-7 SingleDC ntotorcontrolcircuitusing discretetrqnsistors they are supposedto be off,I madethe pin connectcd to thebaseof the unusedtransistor an input.l'he application codeis calledasmMotor.asm: trasnMotor title a Prc16F68{n
Ehis
Program
-
Controlling
Monitors
a Pot
a
at
DC Uotor Accoralingly. Values 0x80 rnove the motor in reverse while Values than 0r<80 move the motor forwaltls. I4hen the at an extren€. the ECCP PwM lnoves at f,ul1 speed. Hardvrare Notes: PIC15F584 running at the Inter$al CLock
l , a l P I C r ' l' l C U E x p e r i m e n t s f o n t h e E v i l
DC Mo!o!
tA3 less
(RA3) Ehan
qreater Pot
4 MHz Using
Genius
is
f,lom
t r t r t
IIAA - Pot RCs/PAA RC{/PIB RC3/P1C RC2./PlD -
i r r
l&lk€ Prettko 05.01.09
grolo
Cotlmanal Motor Forwalals High (on Lo$) ltoto! Revelae Pt, uoto! Revelse Hish llotor Forwarala Pwlt (on Low)
$ -
1
f4
movf, movwf, lnovlw
ADRESE, ADcvalue 0x80
w
; Readl the
subwf btf,ss
ADCValu€, w SllATus, c
r IreEE than 0x80 t ia ReverEe
CONFIG FCllElN OEF & IESO OFF & aOD OFF & _CPD_OFF & _CP_OFF & _MCLRE_OFF & .PIIRTE ON & _!|D4!_OFF & _TNEOSCTO
movhr
b'01001110'
novlrf
ccPlcoN
Vari..bl€E CBLOCK 0x020 D].ay ADCVaIU€ EIIDC
bBf bEf
STATUS, RPo TRISC ^ 0x80,
3
b8f
TRrsc
^ 0x90,
{
bcf
TRISC
^ OxgO,
5
bcf
TRISC ^ 0x80,
bcf bcf rif monnf
RPo SllAmS. STATUS, C ADCValue, w ccPRlL
goEo
IJooD
t
,
PAGE Iilainlin€ org
0 t ror
nop clrf llovlw
ICD
D6bug
PORTC 7
2
t colqltalaEorB trovrdf rnovlw novwf clrf
c!{coNo b,00001101' ADCONo T!lR2
novhr
b'00000100'
novwf clrf
T2CON CCPR1L
r Enable
T'![R2 as r u8ing t Gen€ralor
r Nothing r (YeC)
STATug, RPo 1 << 3 INSEL ^ 0x80
r RA{
novlw
b,00010000,
, gelect
lrovlrf novlw
ADCON1 a 0r.80 6l
novwf lrovlw novwf bcf
PR2 ^ 0x80 b'000011' TRISC ^ 0x80 SEATUS, RPo
movlrr
b'01001110'
rrovwf
ccPlco!{
movlw aaLlrw btfsc alecfaz goto bsE blfsc
IIIGH DLay
((100000
llotorR€velae! novllr ox?F
t
r EnabLe r wilh
movhr
b,11001110,
nov\rf
ccPlcoN
f,
baf
STAIUS, RPo
baf
TRISC
baf
TRrsc ^ 0x90, 2
bcf
TRISC
^ 0x90,
3
bcf
TRISC
^ 0x80,
4
bcf bcf rlf novwf
sTATuS, RPo sTATuS, C ADCVaLue, w CCPR1L
goto
IJooP
^ 0r.80,
5
for
P$u Folwalals
5, + 256) r DeLay 100 ng
ADc t start i Wail for it r finish
Divial€ ADvaIue / 2 for PliU Value Eaable Pwu Forwarala with P1.A/ PLC lPAB I PLD Activ€ High
r t r t r t r t
Turn PtrIP Tur[ NPN firr! PNP Purn NPN
r r t t
Have the llew ADC Linit wail 100 ms to ResamDle
off Low Sial€ Driv€r off High siale Driver od lligh Siale Drive! oN Low sitle Dliver
i"*
& ;J f&
l a.\ \l/ r\i. b' I
I
U ?
Off Low sitl€ r rurn t PNP Driver
t rurn
of,f High siile
'
NPN
r t t t
rurn On Eigh sial€ PNP Dliver Turn ON Low SidI€ NPN Driver
D!iVET
i , r t
llave tshe Nelr AlC rJlmit Wait 100 mE to Reaarmple
a Dc Motor
usiag
a
to
S e c t i o nE l e v e n J ' l o t o r C o n t n o l
{e
B.,e
Along with writing the application in assembler,I translated it into C as cMotor.c as follows: *inclual€ - control slroto! /* Potenliodreter
t-{ lJ.
€nal
Dlav, f S - 3 co GO
aDcvalue,
Foac/8
, S€tsW) th€ IJlmlt , the Ptglr r 15 kHz Fraquelcy t RC5:RC2 Outputs
I
aa
t Betn€en ADc Pol!'a low ((100000 I sl + 2s6l _t STATUS,z
aDcoNo, AIrONo,
xorwf
uovj.ng
A.Dc clock
r ; t t ' t
!-t
l..
a PWtl
(A!{3 ) A.DC hput
go
, Che€sy 7 Bit of the i Negation ccPRlIr t R€v€lse , Value i Enab].e Pt{!l Revelae wfth i PIAIPAC/PLB/PTD Hish r Active
r Eaabl€ 5uR2
bsf novLw noverf
IJooD 3 nrovlw lna,vwf
A.DC on RA{
X
b
t Eorwarala or t Revelae?
goto llolorRevera€ lilotolForrrarfls : mov f ADcvatue
LIST R=DEC INCLITDE'rp16f 68{. incrl
ADC Valu€
259
lltia Proglam ltonitorE a pot at lta3 (RA3) and moveE a DC uotor Accotdingly. values less than 0x80 nove the molor in leverse whil€ ValueE gr€ater tlran 0x80 nov6 tb€ motor forrraral6. when th€ Pots is a! ar extreme, the ECCP pwlt novea al full Epeeal.
Hartbrare Notes: PIC16F584 ruaniDg at 4 MEz Using the rntertral Clock RA{ - Pot Cormartl RCs/P1I' - liotor FonralalE High RC4/P1B - lilotor R€v€rae PWM (on IJolr) RC3/!1C - lloto! R€verse Eigh RC2/P1D - liloto! Forrdalals PWU (on Low)
NOpO, (D1aY - 0i DlaY < 5655, for // 100 lls betveen NOP O T // sarE)l€s
Dlay++) t
GODOT{E = 1t // R€adI Pob Valu€ (GODONE)t tdhil€ - ADRESE, // Reaft in ADC Valu€ (A.Dsvalue > 0x80) // go Forwarala
ADCValue if
{ CCPRUJ = (e.DCVaIue - 80) >> 1, C C P 1 C O N= 0 b 0 1 0 0 1 1 1 0 t TRISC = 0b011011, // eC5/*C2 OulDuc, RC3/RC4 Input
n[ake gretlho 05, 01.10
]
g
(u .Fl
i.l
rl
t{
o lJ o
x
U CI I I
€1ae & WD1IDIS & PIIRTEN & IICIJRDIS & -CONI'IG(INEIO I'I{PROIECT \ & IINPROITECT A BORDIS & IESODIS & FCMDIS) t
int
Dlayt
char
// ADCValu€i
nain(
)
I.ED T:ime on D€Lay va?iable
t PORTC = 0t CUCONo - 7, ConDaralors // Turn off ANSEIJ-1<<3t // R}'4 (AN3) is the ADC rryrur A.DCONo = 0b00001101t on th€ aDC // Tuln garll,l€ // BLE 7 - IJefl iruEtl.fi€dl // BLt 5 - Use VDD // aLE 4r2 - R?.4 / I Bi,E L - Do not SEar! / / BIE O - !!urn on A.DC A.DCONI = 0b00010000t // select the clock a3 Fosc/8 TuR2 = 0,
\o o\ lJ l"a
I!'tR2
//
Provlales
pwlt p€rioat
PR2 = 6{, / / L5 Wz pvtlt F!€qu€ncy r2CON = 0b00000100t // Enable TMR2 CCPR1IJ = 0t // O DtiEY C-!'c1€ to start whil€(1
== 1)
Off
(
//
Glo in
Rev€rae
^ 0x7F) CCPR1IJ = (ADcfalue CCPlcoN = 0b11001110, TRISC - 0b100111t RC3/RC4 Input // RC5/RC2 output, | // fi ) // eLihw l // Enal cMotor
>> l.t
You should be aware of a few things before beginning this experiment.First, the circuit is meant to work with a wide variety of different small hobby motors. You may find that the circuit doesnot havea very long battery life, the transistorsget warm due to excessive current passingthrough them, or the motors do not produce a lot of torque.As indicated previously,the motor drivers are general-purposecircuits.Therefore by understandingyour motor's parametersand specified power supply,and by using driver transistors with appropriate current, voltage,and resistanceparameters,your circuits will be more likely to perform at rnaxirnum efficiency.The four kickback suppression diodes are not optional, even if you have a very small motor. And, if your circuit acts strangely,you may wish to add a 10 to 47 pF electrolyic capacitor to the PIC MCU's power pins and a 0.L pF capacitor acrossthe motor to help reduce the electrical noise produced by the motor. Do not disassemblethis circuit when you are finished;it will be requiredfor the next experiment.
o H
.Fl
l{ (,
9{
x
til
260
l , P 3 P I C o I I C U E x p e ri m e n t s f o r
the Evil
Genius
ExFeriment 97-DE MotorControlurith
rr:
S im pleT MH OPI-U M
H tl,
i.+ I
P rcr.6F 58 4
t-n
2N3904 NPN bipolar trans istors 2N3905 PNP bipola! trans istors 1N914 (1N4148) si Iicon diodes DMM
100O resistols
Needle-nose I[ire
q
pLiels
clippels
Breadboard
I
0.01 FF capaci.tor
Wiri,ng
1
B!eadboard-mountable SPSr switch
kit
AA alkaline
The applicationcodefor this experimentis called asmMotor2.asm.Along with the reducedPWM interval,I alsoaddeda very simplestatemachinethat alternativelysetsthe GO/DONE bit of ADCONO and r e a d st h ev a l u ei n A D R E S H .I n t h ep r e v i o uesx p e r i ment,I couldpoll the stateof GO/DONE continuously,asthe PWM operatesin the background without any softwareintervention(other than to disableor
. ! t
AA battery
Thlee-cell clip
The applicationcircuit for this experimentis the sameasin the preyiousexperiment(seethe schematic in Figure11-6and prototypewiring in Figure11-7).
,
(see text )
DC moto!
This experimentis a repeatof the previousone,except insteadof usingthe builfin ECCP PWM circuitry I usedTMR0 to overflowevery1,024cycles,providinga timebasefor the PWM. By delayingfor 32 cycles,a 30 Hz PWM is produced.Although in the previousexperiment,I usedthe built-in PWM hardwareto producea signalabovethe rangeof humanhearing,by using TMR0 I have created a PWM signal below human hearing.Severalreasonsexistfor doing this.First,small hobbyand toy motorsoften work more efficientlyat very low PWM frequencies. Another reasonis to allow a basictimebasein the softwareso other eventsor elements(includingmultiple motors)canbe synchronized.This is a very important considerationwhenyou are designinga robot.Finally,TMR0-based timebase allowsthe useof low-costPIC MCUs that don't have built-in PWM generators.
I
10k breadboald-mountable potentiomete!
batteries
-.ft
changethe PWM duty cycle).Another differenceis that the pin valuesof RC5:RC2do not change,but to changehow the H-bridgeoperates,Ichangedthe pin bit input/outputmodevaluesin theTRISC register. "asntMotor 2 - Dc uolor tsitle TllRo TLrrebaaetr
conlrol
uaing
a
Thia Plogram !4onitor8 a Pot aE &43 (RA3) valueB anal rroves a DC llotor Accoralingly. leaE lhan 0x80 nrove the rnoto! in !€velEe greater whiLe values tha! 0x80 lrove the rrotor foiwarals. whed the Po! is at an extreme, Pl'iU nove€ at fulL the Sof,tware ape€dl. Halabrale Notea: PrC16F5g{ ruflring al 4 MHz UBing tshe Intelna1 Clock RA{ - Pot Comtrand RC5/P1A - Motor EornaltlE Hish - Molor Reverse PWU (on lrow) RC{/PIB RC3/PLc - uotor Revelse ltigb RC2IP1D - Uolor Forwardls P$U (on low)
Myhe Preflko 0s.01.10 LIST R=DEC rNcrrtDE np15f 584. incn
_coltI'rc -FcttEN-oFF & _rEso_oFr' & _BoD_oFF & CPD OFE & CP OTF & I'ICLRE OFF & .PI{RTE-ON & WDf OTE & INTOSCIO
setrtionEleven l l o t o n C o n t r o l
26L
a"r
( J
e 'J
,*t"
' , J
Variables CBLOCK 0x020 Dilection iDcstate, ADcvalue PV {Duty, Ptfl{Cycle ENDC t
clrf goto
PAGE Uainline olg
bcf 0
r!f
nop
s"*s €
6
r 1
&.; t !
n t
:1 I
d.r
t
For
ICD
Set
PORTC Accoraling
Debug
rrf
novlw
b,010111,
t
trrovwf movLw movwf novLw novwf, clrf
PoRTC 7 cucoNo b'00001101, ADCONo TllRo
Palameter6 t OperaEing ; lPurn off Corq)aratora
bsf novlw no.trwf novlw monwf movlw
t Enable r uging t Base
bcf
IN'IICON, ToIE
clrf clrf clrf
A.DCSlale PwllDuty P$UCycle
clrf
Dileclion
, Wail fo! i Ov€rflov
TURO to
Not Uoving ats First Start at the B€gi ring lloving Eorwalals
INTCON, TOIF
t waits for t Ov€rf1ow
IN:ICON,
t Reset, andl Wait t Next
I ,
F"*
flt
btsfEc goto baf baf golo ADCR€aal: lrovf fiovrof clrf A,DCDone: movlw Eubwf btfas goto
"F{
l'L,
g{
IIOIF
tDcstat€, 0 LDcR€ad ADCONo, cO ADCStat€, 0 aDcDone
0x80 ADgvalue, w STATUS, C
gtalt
or
fo!
i Move
novf
PliEtDuty,
aulnrf movlw blfsc novlw btfEc novlw bsf movwf bcf
P$UCycL€, b,011011, Dilection. b,100111, STATUS, b,111111, STATUS, TRISC ^ STATUS,
incf
PWUCycle,
f
bcf
PWMCycle,
5
goto
Loop
Backwalals
t Check Eo upalatse tbe t Motor t If Duty > CycLe, th€n
w
Reaal the
t OriginaL i Proceaa i
Fofirarala
i
teaa
vt 0
r TRISC Foll'arats t Fot-walals or Revefse? r TRISC Reverse
C r Turn
off
lilotorB?
R.Po 0xg0 RPo tshe Plgtt t Increnent i CycLe Count , M6ximrll of 32 Stat.eg i i
Finiahetl, Again
IJoop Alountl
<9ic.h> *iaclual€ cuot-ot 2 - Control /* Pot€ntsidretet
Statse A.DC Value
than
Reverse?
0x80
go in
Eh€ VaLue r Conv€r! r from 7 BitsE
using
a
Thi6 Proglam llonitols a Pot at RA3 (!rA3) aad moves a DC Motor Accordingly. Values leEs than 0x80 nove the motor in leverse gl6at,e! whil€ valu€6 than 0x80 nov€ the rnotol fonsarals. A 1 ma looD (proaluceit by I'MR0 ) is u8eal to Droviale a 30 Uz PWU for toy nrotors
A.DC Value
ol
a DC Uotor
Harahrate t{otes 3 PIC16F6g{ running at { MBz Ugilrg the Int€rDal clock nA4 - Pot Cdmand RC5/P1A - Motsor Forwatalg Elgh RC{/P1B - MoCor Revera€ P}ru (on Low) RC3/P1C - lilotor Reverae Eigb RC2IP1D - lloto! Forwartls PWI,I (on lJolr)
rryke Drealko 05.01.10
fi
t*i 262
Value
I createda C versionof this applicationcalledcMotor Z.c.
Reaal ADC?
llotorRev€rse
PwltDuly, f, STATUS, C PtCDlDuly, f
!h€ t Convelt ; f rdr 7 Bita ; to5
enal
ADC Readl , Stalt t Ne:{ts State i
A.DRESE, w Alcvalue A.DCState
lfotorForwarale: novwf PWuDuty bcf STATUS, C rrf bcf, rrf
,
, Cheesy 7 Bi! Negatio! , of the CCPR1IJ Value i Revers€
Timer
gfoEo bcf
Plirllurtsy, f STATUS, C PIgUDuty, f 1 Directiou
Uotorlrpdale:
TMRo aa a Plitlt
monwf bcf
r r r i
ADCValue, w PI{!4Duty SltATItS, C
Fonraitlg
AIrc on AA{
STATUS, RPo b,11010001, , 1:{ prescaler to TMITO OPTION_REG ^ 0x80t 1 << 3 r A,A{ (AN3) ADC fnput ANSEL ^ 0x80 b,00010000, i geLect ADC Clock as i Eosc/8 ADCON1 ^ 0x80 STAT['S, RPo
IrooD: btfss
; llov€
!4otolReverae : novlw 0x7F xoriwf
,
Direction Motolupala!€
l , a 3 P I C @l " l C UE x o e n i n e n t s
fon the EviI 6enius
n
) ( INTIO & WIIIIDIS & PWRIIEN & UCI,RDIS & -CONFIG I'NPROTEC! \ & I'IIPROTECI! & BORDIS & IESODIS & FC!,IDIS) '
elae
{ = ADRESET ADCvalu€ = 0t irDcstate // ReBet stale , // fi
A.DCStale = 0t ADcvaluei = 0t Directiott PWuDuty = 0t = 0t Pllllcycl€
char cha! char cbar cba!
n h.t
Read AlC
//
s
uachine
r,"d
(aDcvalue >= 0x80) Coftlanal? // Eorwaral
tf
t PWUDuty = (ADCValu€ - 0t Direction
-
0x80)
s"*
>> 2t
fn
)
nain ( )
t
F.{ // PORTC = 0b010u1t valueg // PORTC to Conlrol CI{CONo = 7, otf ConDalatsors // \Jt]r ANSEIT=1<<3t // RA4 (AlI3 ) is lhe A.Dc Input
Revelse
t P$UDuty = (llDcvalu€ - 1t Dileclion
^ 0x7E)
>> 2t
, // fr
".fl
if, (0 == Dilection) TRISC = 0b011011; // Enable Forwaral €1Be rRISC = 0b100111; // Enable R€vers€
A.DcoNo = 0b00001101t on lhe nDC // firln .tuslifieit // Bi-E 7 - teft Sanpl€ 5 - use vDD // Bit ll BLE 4r2 - rrA4 / / BLE ! - Do not Slarl oa ADc // BiE O - Tuln aDCONI = 0b000X0000t aa Foac/g // selecE the clock
if
t Bits
F
Bite
H
( Pll!,lcyc1e >= Ir9{!'Duty} TRISC = 0b111111t // StsoP !4oto!s PflUcycle
= (Pwt'tcycle
+ al
! { } % 32,
1.uR0 = 0 i // use T!{Ro for oPTIoN = 0b11010001, // 1:4 Proacal€r
a 1 ma D€lay ) to
uae
rnt€rrupts
EIag
for
1 ms
whl.1€ (1 == 1)
t whiLe ( !TOI!) t r!|Ro to overflow // Wait fo! ToIF = 0t // Reaet f,or Nex! 1 lla D€Iay (0 == .aDcstate) or / / sEart
if
R€adI aDc?
t
GODONE= 1t // gtart ADcgtate = 1,
ADc
// elihw Enal cMotor
5,,i;tr 2
T!!Ro
ToIF = 0t //
) //
This code is much easierto follow than the assembly codeversion.But if you look closely,you will discover that the C code specifyingthe on/off of the motor works differently, and even if the PWM has a duty cycle of 0 percent (fully off), the motor driver will be on for a very short time (just a few g,s)before the softwaredeterminesit shouldbe turned off cornpletely.The reasonfor the difference is primarily an oversighton my part. I discoveredit only whenI comparedthe operationof the two programsline by line after seeingthe very shortpulseson my oscilloscope whenI looked at the operationof the two applications.
S e c t i o nE l e v e n l l o t o r C o n t n o l
263
L; ...-: r."1.
:t
n
Experiment 98-ControllingMultipleMotors urith PIIJMand 852 lnterface
[.1
o
i=r
A
I fil
1 L293D moto!
.-f
&
DC motols 1 Fou!-celI clip
F{
DMM
tn
Needle-nose pliers Wire clippers B!eadboard Wiring
F{
kit
,-|
o
U I
@
AA battely
One of the pointsI madein the previousexperiment wasthat multiple motors and complexcontrol softwarecouldbe addedto the 30 Hz motor controlPWM software.This is due to the relatively large number of rycles the code spendswaiting for TMRO to overflow beforeupdatingthe motor PWM code.In this experiment,a secondmotor is addedto the control codethat executeswhile waiting for TMR0 to overflow and that polls for the BS2instrumentinterfacethat wascreated in the previoussection. Insteadof repeatingthe build of the four-transistor H-bridgeusedin the previoustwo experiments,I
decidedto usethe L293D chip,which consistsof four two-outputlevelmotor driversasshownin Figure 11-8.Thechip includeskickbackdiodeson the outputq so you do not haveto add them to your circuit,and is designedfor driving two motors with an extra PWM output control (pins1 and 9).But for most applications,I simplytie theseinputshigh and control the operationof the motor by changingthe level of the control outputs.The chip runs on a 4.5-to 6.0-volt powerinput (Vcc on pin 16) and canswitcha higheror lower voltage i4put on Mot Powr pin (pin 8) .This makesthe L293D usefulin a lot of applications. There are three things you should be aware of with the chip (1) The 0.7-voltdifferencebetweenVcc and Gnd and the selectedoutput level is due to the bipolar componentsusedin the manufactureof the chip;(2) The chip will dissipatea fair amount of heat when a
ot
nl 'Fl H
P.{ f\
t*i
batteries
P I C 1 2 F 6 ? 5 o r P I C 1 5 F 5 84 - b a s e d BS2 cotunand simulato! inte!face
s
c
chip
(see text )
AA alkaline
p
i{
dliver
1 B!eadboa!d-mountable SPST svritch
"-l {J
o
P 1 C 1 6 F 6 84
Figure l'f-9
Figure ll-8
Dual BS2 motor
264
l , e 3 P I C o l ' l C l JE x p e r i m e n t s f o n t h e E v i l
Dual DC motor H-bridse
Genius
motor is running(causedby the 1.4-voltdrop through the high and low pinsmultiplied by the currentpassing throughthe motors).Thetotal amountof power the chip can dissipatesafelyis 3 watts.It is a good idea to provide copperPCB heatsinkingto the chip via large fill or f'lood areason your PCB connectedto the groundpins to wick awayasmuch heat aspossible.(3) The L293D hashad spottyavailabilityover the past five years,with somemanufacturersdropping shipmentsof the chip while othershavebeenrampingup. The internal kickback diodes make the chip a lot more (alsoknown asthe L293), usefulthan doesthe 75,1410 which is pinout cornpatiblebut doesnot havethe diodeson the outputs. Onceyou havewired the circuit shownin Figure1108 on a breadboard(seeFigure11-9)and connectedit to a BS2 or simulatorapplication,you canbum asmBszMotor.asm into a PIC16F684and test out the oDerationof the two motors.
The BS2 comrnandand responseoperation is quite simple with values0x00to 0x3F being usedfor Motor 1 and values0x40to 0x7Fusedfor Motor 2. Like the previous applications,the middle values (0x20 and 0x60for Motor 1 andMotor 2, respectively)stop the motors,valuesgreaterthan the middle will causethem to turn forward,and valueslessthan the middle will causethe motorsto turn in the reversedirection.Like the previousexperiment'scode,the PWMs built into this application will have higher duty cycleswhen the motor valuesare further awayfrom the middle point. The motor software shown here could be usedasis for a BS2-controlled differentially driven (two motor, one on eachside)robot or be the basisof a differentially driven robot that is controlled using the single PIC16F684.The motor control code and PWM cyclecount incrementtake only Z cycles,leaving a thousandcyclesfor sensorand controloperationsof the robot.
14
X
U
o
,>
H.
:t
tU H l E
\s
taa ! I
w f-, "
ry (J
Experiment 99-Bipolar 5tepperMotorEontrol
H
frr
t$
m
,*&
P I C 1 5 F 6 84 1 L293D moto!
dlive.
chip
1 10k breadboard-mountable potentiometer I
}15 m
0.01 F!. eapacitor
1 B!eadboa!d-mountable Bipola! steppe! (see text)
DMM Solderiog
j.!oo
Four-cell crip
solder
AA alkaline
Needle-oose pliers
Klazy
,3
moto!
K
AA battely
LJ
battelies
1 Four-pj,n 0.1oo-inch header (see text )
Sci sso!s Glue
Ft
Ca!dboa!d
Wire clippers
( ,
o r"t
B!eadboard Wi,ring
kit
Steppermotorsare very populardevicesfor a variety of applicationsbecausethey canbe turned a specified amount,do not requireextemalgearing,and are generally very simple for which to designdriver circuitry.
lu
In this experimentand the next,I will introduceyou to the two mostcorrmon typesof steppermotors,unipolar and bipolar, and then to the driver circuitry and PIC MCU software that will first simply turn them and then
SectionEleven I ' l o t o n C o n t n o l
265
$
tst
l'! t r i !
{:
!J
s3,i rl t!
fft
tr-{ j-: &*i
.r,i
a I
control them usinga potentiometer,asI did with the DC motorsat the start of the section.To help you understandhow the softwareworks,I will first present you with C codefor driving the steppermotorsfollowed by assemblercode.
one or two coils be energizedat any time. Full stepping movesthe shaftby 90 degreesat a time,and only one setof coilsis energizedat any time.
Steppermotorshavea few notablecharacteristics: They consistof four (or more) coilsarrangedperpendicularlyto eachother (seeFigure11-10).Thesefour coilssurrounda magnetizedshaft,whichwill be either attractedor repelledwhen the coilsare energized. To turn the steppermotor, lhe coilsare energizedin a pattern that will causeit to turn in one directionor another.Becauseof the time requiredto energizethe coilsand becauseof the inertia (aswell asany load resistance)of the shaftand reductiongearingplaced on the shaftoutput,the speedof the steppermotor is much more limited than that of the DC motor.The reduction gearing reducesthe movement of the motor output ftom 45 or 90 degreesfor eachchangein position of the shaftto just a coupleof degreesor so to maximizethe torque output of the motor.Along with the slowerspeedof the steppermotor,the needto keepat leastone coil energizedat any one time will draw more currentthan doesthe DC motor. On the plus side,steppermotorscanbe moveda precise amount,and they producemuch more torque than doesa DC motor. There are two types of stepper motors commonly in use.The bipolar steppermotor will be presentedhere and consistsof four coils around the magnetizedshaft (seeFigure11-10).Thebipolar steppermotor canmost easilybe identifiedby four wirescomingout of the body of the notor with pairsof wiresconnected togetherthrougha smallresistance(whichis causedby the coils).The high-currentpush-pulldriversof the Hbridgeare usedto alternativelyturn the two setsof coilson and off aswell asturn them to differentpolarities.In Table11-1,I havelistedthe poladtiesfor the different coils to move the shaft by 45 degreesat a time.This is known ashalf stepping andrequires that
Table 11-1 Half-stepEoil EnBrsizationPatternfor a Bipolar 5tepFer Motor Step
Up-DouJnEoll
East-Wesl Eails
South
otr
South
South
otr
South
North
South
North
off
North
North
otr
North
South
North
InTable 11-1,the North and Southspecifications are arbitrary and are usedto indicatethat the polarity of the coils'magneticfieldschangesover the courseof the sequence. Also note that in Table11-1,I have emphasizedthe text of changingcoil (one coil changes in eachstep). To test out the informationin Table11-1,I createda circuit (seeFigure11-11)to drive a bipolar stepper motor andwired it on a breadboard(seeFigure11-12). With the steppermotor that I used,the connector attachedit to a doubleinline connectorthat could be pluggedinto the breadboard(similarto the onesused in the servoexperirnentselsewherein the book). Chancesare you will not be so lucky and you will have to solderthe individualpins to a singlepin inJine headerthat canbe pluggedinto the breadboard. Before burningthe PIC16F684with the following software,I suggestyou cut a sliverof cardboardasa pointer and Krazy Glue it to the end of the stepper
i.,r i
StepperMotor
:.-r **
ivj
-.:
{ii
j l
il . -oxi i1i
Figure ll-10
Bipolqr steppermotor control
266
l , A l P I C @l l C U E x p e r i m e n t s f o n t h e E v i I
Figure ll-'fl
Bipolar steppercircuit
6enius
PORTC = 0t CMCONo = ?t of,.E codrparalora / / $ri'r ANSEI = 0t // Turn off ADC TRIsc = 0b000011, // RCs,RC2 OutDulB
14 t
t NOP()t for (j = 0, NOP()t
j
< 21000r j++)i
PORTC = StepperTalrle i
Figure lf-le
Bipolar steppermotor testcircuit |
motor'soutput shaft(seeFigure11-12)so that you can clearly observethe movement of the stepper motor. When the circuitis built, you canburn a PIC16F684 with cstepper.c,which takesthe informationfrom Thble11-1and usesit to createa simpletablefor halfstepdriving the bipolar steppermotor. In between steps,thereis a quarterseconddelay,and if your applicationis wired correctly,you will seethe pointer you gluedto the steppermotor shafttuning through360 degrees(a degreeor so at a time).If you do not see this pattern,you will haveto rearrangethe wireson the breadboarduntil the motor startsworking correctly.(Do not desolderand resolderthe leadson the 0.100-inchheader.) *incluale - Tula cstepper.c /* ilhiE
Plogj.aln
is
a slel)pe!
Earakcar€ l{otea 3 PIC15E58{ Rurrdinq at { ltHz wilh oEclllator RC5:RC2 - St.eDDer Uotor Outl,uls
t
+ 1) % It
\o
// efrnw End. cstepper
\CI
The assemblylanguageversion of cStepper.cis asrnStepper.asmasfollows, Knowing that the code would neverbe longerthan 255instructions,I decidedto use a basic,not the general-case,table for the stepperpositions to simplify the coding. tiEle llotor
"aarsteDDe!
-
Prc15F684
Bipolar
steDlrer
Program OuEDutsa a a€w Bigolar g€qu€nc€ once every 250 ns.
b
t{
m (}
asmn. IJIST R=DEC rNcritDE .p15f 584. Lacn
s
Irternal
_coNFrc _EqlEN_oEF & _rEso_oFF & _BoD_og! & _CPD_OTE & _CP_OFF & _!{CI;RE_OFF & _PWRTE_ON& variabl€s CBLOCK 0x20 DIay, i E![DC t
-CONFIG ( INTIO & IIIDTDIS & PVIRIIEN & !{CI,R.DIS & I'WPROTECT \ & InIPROTECT & BORDIS & IESODIS & FCMDIS) t
= {0b011100, 0b010100. 0b000100,0b100100, 0b100000,0b101000, 0b111000,0b011000)t
r
PAGE uainLia€
uop
For
movlw
|
movwf
PORTC
<< 2
start Active Turrr
monwf, bsf, clrf movlw
lt
h{
K o
main( )
t
Ud
p,
Ealahdale t[otseE: PIC16F6g4 running at 4 lGIz usiDg tsbe raternal clock ratelnal Rea€t ia us€al RCs:RC2 - 1,293D gtepDer llolor Control
_IIIDT_OFF & _INIIOSCIO
[]
I
st€Dlrer
uyke Pr€alko 05.01.14
rllzke pleflko 05.01.15
uasigE€tl inl i = 0, jt consl chE! Stepger[able
I
Fr.
controlu
ThLs llotor
lfotot
baseal on "asmstepper.
, //
= (i
lil
o v' H o
,-r
== 1)
while(1
X
CUCONo STATUS, RPo ANSEL ^ 0x080 b'000011'
sectionEleven l l o t o n C o n t n o l
t
,
t
!
ICD D€bug with
Bit
2 : t
off
Collparalors
d E ecute out of, Bank 1 A11 BitE are Digrital RC5:RC2 are Outputa
267
b,t \J
F{
o
$.1 1J
c
o
U
t{
o {J o E ${
0, 0{ g{ 0,
novwf bcf
TRISC i 0x080 gEAltrUS,RPo
clrf
t
i ReturE rt €cution t Bank 0
i Retun i Value
IJooD:
H6r€
novlir
srcH ((25o0oo I 5l + 2561
novcrf movlw aaLlLw btfsc decfsz goto
DIay rJow ( (250000 -1 STATOS, Z Dla!., f $-3
movf call lrovwf
t, w StwitchReaal PORTC
goto
to
for
Next
nain ( )
{
5) + 2s6) t 250 mE Delay
/
= (t
PORTC = 0, CMCONo = 7t otf Compalatora / / \rrD, ANSEIJ=1<<3, // RA{ (A!13 ) ia tshe ADC IDDlrt
+ 1) % 8t
t
i
t i
Stayirg L! InalrucElonE
LooD
gwltchR€ed: aaLkdf
PcL,
atr
f
char StepperTable I I = {0b0U100, 0b010100, 0b000100,0b100100, 0b100000,0b101000, 0b111000,0b01r000)t corlst int On€ng = 83t codsl
riral
255
A.DCONo = 0b00001101t // Eur,r on the ,|IrC iluEtifieil // Bi-t. 7 - Left 5 - Us6 VDD // Bit // Bit 4.2 - nA4 / / BLt- f - Do not Stalt // SiE O - Turn on ADC ADCON1 = 0b0O010000, aa roac/8 // se].ect th€ clock TRISC = 0b000011, // RC5:RC2 Oulputg
b,011100,,b,010100,,b'000100,, b,100100, b,100000,,b,101000"b'111000,, b,011000,
alr
t{ d F{
o 91
..1
!q
I
Once I got the steppermoving consistentlyin one direction, I then expandedthe application so that a potentiometer would control the operation of the bipolarsteppermotor in the sameway asit would control the DC motors.cStepper2.cwascreatedto read the potentiometer wired to RA4 and then to change the dftection and the delay between stepsin the range of257 to 2ms.
Ehis
Prog:.a!
ia
Ol
Halalwsr€ NoreB:
o\
3::lii:::.-"""*s
lJ
c
c, g .Fl
t{
o
9{
X
-
Conlrol
ba6€i[
a gtepD6!
oa nasirst€DD€l
ltotor
Using
2.asm't.
Uotor OuEDuta Coatrol
unsiglneil unaigmetl
& IID4IDIS
& PIIRTEN & IICI,RDIS
& BORDIS & IESODIS
tnt t = 0, J, cha! Perlod,
& FCI.IDIS) t
olly
Move if
gofiFthllg
Ther€
{ (0x80
Lf
< Pefioal)
t P€riod i = (i
c (Periodl + 1) % 8t
-
0x80)
^ 0x7Pt
) //
61se R6verae i e (i
rPeriod' OK - 1) % It
//
POREC = SlepDerlable Uov€ Slepper
//
while DeLay at
,
(J = 0t J < Onelost j++); for P€rioal=gelLoal-1i // elthrd ) /l fL | // elihrt ) 2 / / EEd, cgleppar
I il ,
(0 l= Perl.oal) t{e!r PoaLlioD
{
ryk€ D!€alko 05.01.15
-CONFIG(IIITIO I'NPROTECT \ & I'NPRoIECT
//
ar { MHzwitsh rnt€rnar
RCs:RC2 - Slepl)€r RA{ - Pot€ntidlet€r
loop Foreve!
NOP0, f o r ( j = 0 t J < O n e m s , J + + )t NOPo, GODONE= 1' // starts A.Dc f o r ( J = 0 t j < O n e r n a t j++ ) t P€rLod = ADRESHT // R€adl Velu€ If (0!ra0 != P€riod)
€nat
#lnclutle cgt€9D€r 2.c /* a Pot
//
{
*J
a
( 1 == 1)
lrhile
Saq)I€
&
asmstepper2.asmis the assemblylanguageversion of cStepper2.c and performs exacdy the samefunction. Due to the nature of stepper motors (i.e.,having to delay a set amount between eachstep), I have not included a BS2 interface example.It is quite simple, due to the ability of the code to poll the BS2 clock line while it is delaying between steps.
frl
268
l , e 3 P I C o M C UE x p e r i m e n t s f o r
the EviI
6enius
tcl X l'zt
Experiment 100-UnipolarStepperMotorControl
{9 l-,1
tr.
Prc16F584 2N3904 NPN bipolar t!ansisto!s 1N914 (1N4148) siLicon diodes 100O res istors
fl\ ,-*
r-S
1 10k breadboard-mountable potentiomete! I DMM Soldelinq
Breadboa!d-mountable SPST switch
iron
Uoipolar stepper (see text )
solder Needle-nose $i!e
pI iels
Four-cel1 clip
clippers
Scissors Klazy
0.01 pF capacitor
AA alkaline
GLue
LJ moto!
AA battery batteties
Breadboard
Six-pin 0.10o-i.nch heade! (see text )
Wiring
Ca!dboa!d
kit
The unipolarsteppermotor is subtlydifferentfrom the bipolarmotor in how its four coilsare wired.Insteadof currentpassingthroughtwo coilsat a time,the unipolar steppermotor is designedwith a commonconnection betweeneachset of parallelcoilsthat allowseach coil to be turned on or off individually.The normal wiring configurationof the unipolarsteppermotor is s h o w ni n F i g u r el l - l 3 , w i l h t h ec o m m o nw i r e sc o n nectedto positivepower and the individualcoil wires beingpassedto opencollectordrivers,tuming the coils on in sequenceand drawingthe shafttoward one coil at a ttme. The unipolarsteppermotor is usuallydifferentiated by the nurnberof wirescomingfrom it. Although in Figure11-13I imply that five wirescomeftom the unipolarsteppermotor,thereare usuallysix.Eachpair of coilshasits own commonwire.Somesteppermotors havefive wirescomingout of them;theseseemto be hybrid unipolar/bipolarsteppermotors,whereeach pair of coilsis wired differently.In thesecases, you shouldtreat the steppermotorssimplyasbipolar.If you compareFigures11-13and 11-10,you shouldrealize that the unipolarsteppermotor canbe usedin exactlythe sameapplicationsasthe bipolar motor whenthe commonwiresare disconnectedand the four wiresleadingto an individualcoil are used.
I,
re
The differencesyou shouldbe awareof betweenthe two typesof steppermotorsare few.Becausethe unipolarmotor hasonly one coil activeinsteadof two, asin the bipolar rnotor,it doesn'thavethe sametorque asthe bipolar motor.On the plus side,the bipolar motor control circuitryis a lot simplerto program,simply pulsingeachcoil in sequence. Figure11-14showsthe circuit I cameup with for testingthe unipolarservomotor,and Figure11-15 showsit wired to a breadboard.In Fizure 11-14.vou
$, $*
{n
r+ {u
{s
PositivePower
ht ry !>
CoilContfols
r*
e.j
Figure 1'f-13 Unipolar steppermotor control
Section Eleven l ' l o t o r C o n t r o l
269
can seethe six-pin header to which the six unipolar stepper motol wires are soldered, with the common wires (found with a DMM resistancecheck)being placedin the middle of the connector.Along with soldeling the steppermotor wires to a headcr,you should also Krazy Glue ir cardboard pointer to the shaft of the steppermotol to observeits motion when you tcst it. Testirg the unipolar stepper motor is accomplished in exactlvthe same way as testingthe bipolar stepper motor: cStepper3.c will sequencethrough the coils, hopefully moving the caldboard pointer continuously. Again, if it doesn'1,n]ove the wircs to tltc control transistorsuntil it cloes.A simpler way of testingand decodingthe wiring is to touch the baseconnection (through thc l00O rcsistor)of cach transistor1()the Vcld rail of the breadboard.This will tell you which cir'cuit is wir.edto which pin. And thcn you can begin attachingthen in sequence,startingat:
lnain
*include cslepper 3.c /* This
Progra$
is
Figure lli5 Unipolor stepper motor circltit using NI'N tt ttnsistors as motot' contrel drivers
- turn based
Earalware Noles: PIC15F584 Running Oscillator RC5:RC2 - StePPer
at
a unipolar
Stepper
on " asmsteppe!
4 MIIZ with
Moto!
Mo€or
()
t POR4C = 0; CMCON0 = 7, ANSEIJ - 0, TRISC = 0b000011t
. asm" .
lrrternal
while(l Outputs
== 1)
// // //
r\rrn off conparators ?urfl off ADC RC5:RC2 Outputs
//
Irootrt Folever
{ NOP()i NOP()i
CONFIG(INTIO & WDTDIS & PMTEN UNPROTECT \ & UNPROTECT & AORDIS & IESODIS
= (Outputval Outputval" & 0x3C) ((1 << 5) == qrsnoao'.t, if = 1, << 2i outputval PORTC = Outputval;
& MCLRDIS &
char
outpueval
<< 1t
& FCMDIS)t I
unsigned
< 2 1 0 0 0r j + + ) ,
f o r ( i = 0 r i
05.01.15
= 1 << 2,
) //
// eliht^' E^d cslepper
"asmstepper
3.asm"
3 is
the
of
translaEion
As with the previousexperiment,I wrote codeto control the movementol the unipolarstcppcrmotor usinga potentiometer.The control soltwareis almost idcnticalto thatusedin the previousexperiment with a 2 to 257ms delayin the steppermotor movements. The C languageversionis calledcStepper4.c: #include 4.c - Control cstepper /* Motor using a Po! This
Progran
is
ttardvrare Nohes: PIC16F684 Runnins oscil.l-ator RCs:RC2 - Stepper RA{ - Potentioneter
Figufell-lq
Uttipolorteppercircuit
270
l , a 3 P I C @f l C U E x o e r i m e n t s f o r
baseal oll
at
a unipolar
"asrnstepper
4 MHz with
2.asm".
lnternal
Moto! Outputs Control
the Evil
Steppe!
6enius
if nyke pledko 05.01.15
'
((1 << 1) Outputval // fi
== Oulputval) = 1 << 5t
PORTC = Outpulvalr & WDTDIS & PWRTEN & MCI,RDIS & _CONFIG(IN:IIO ITNPROTECT \ a ITNPROTECT & BORDIS & IESODIS & FCMDIS) r
)
\)tn off conparators / / ""n to"il-rJii"-"o" rnput
ADcoNo = 0b00001101; // t,utn on the iqDC
// Rcs:Rc2 ourputs //
r
< onensr
i
i++)r
1r AtC // Start 0r i < onetnsr i++)r ADRESE' // Reaal value t= Peliod) rhere // Only Move if SonelhinE
(0x80
< Period)
//
Fondards
period = (period - oxso) ^ 0x7Fr outpulval = (outputval & 0x3c) a!
({r
<< o,
== uuEputvar,
ourDulval = t .. zt ) tt"t
>> 1'
,, *..r.rr.
4
asmstepper4.asmis the assemblylanguageversion of asmstepper4.asm. You might be wonderingwhy an intermediatevalue is usedfor storingand shiftingthe PORTC unipolar steppermotor positionvalue.Insteadof: Outputval,
anallw
b'111100'
btfsc iollw movwf
PORTC, 5 1 << 2 PORTC
novwf
OutputvaL
w
r Shift
the Saweal value
r Clear Out Shifteal t Bits r Ro11 Over? r Store Nevr activ€ t Bi! r Save New Set Bi!
uE)
Coil
I.oop Forever
<< 7.i
(
//
rlf 0r
j++)t
you might think that:
{ if
) // ti // elihw E!)d cstepper
rlf
tt P-il- 1 - r,afll .rlr
== while(1 { NoP( ) i (i = for NoP()i GODONE = for (i = Perioal = (0rr80 if
t
,
//
= r << 3i ANsETJ
!= Period) Delay at Ne$r PoBition
)
nain( ) t PoRrc= 0t
//
r4ove Steppe!
f o r ( j = 0 , j < O n e m st Peliotl=P€riotl-1; // elihw
= | << 2i char outputval unaisneal int jr unsiEneal char Perioalr consE int Onems = 83r
CIqCONo = 7r
(0
nrhile
//
- rperiodr oK
outputval = (clutputval & 0x3c)
PORTC, $
analrw btf5c
b'111100' PORTC, 5
iorlw rnovwf
1<< 2 PORTC
Up the Bil
Active
, ,
Shift Coil
i r t t i
rf Bit 5 was Set, Rolling over to Bit 2 Save New gteDper value
is more efficient. as it savesan instruction and a varia b l e .l h e p r o b l e mw i t h l h e s e c o n dm e l h o d r sl h a l l h e voltage acrossthe pin is at the one-halfvdd threshold (i.e.,the thresholdthat determinesif thepin ishighor lor.rand r.rhen it is read).and therefore the value is indeterminate. By putting a larger resistor on the base 6f the driver transistor, there should be a noticeably high voltage at the output pin. But I wanted to keep the circuit as general as possible and provide the maximum current switching possible so I left the 1000 resstor and added the variable.
S e c t i o nE l e v e n l ' l o t o n C o n t n o l
z, lL
Experiment l0l-Fladio-Control Model5ervo Control
1 Prc15F584 (any
1 0.01 ,uE capacitor tYpe) f
10k breadboa!d-mountable potentiometer
''-:
470C) 1o-pin
resi stor
1 10-LED balgraph
di splay
1 Servo connector text )
( see
i::.:j:l
DMM Oscilloscope Needle-nose !:
:,
Wiring
1 Radi.o control p 1ie!s
selvo
1 B!eadboard-mountable
kit
Three-cell clip
When you are fint gettingstadedwith robots,I highly recommendusingradio control servosfor drive motors.Servosare quite inexpensive($10or less,and cheaperthan many DC motor driver kits or gearhead motors),surprisinglypowerful,and very easyto wire into an applicationasyou canseefrom the schematic circuit for this experiment(seeFigure11-16),which I built on a breadboard(Figure11-17).Electrically,all you needis a 4.5-to 6-volt power supply,a line from a PIC MCU to drive it, alongwith a servoconnector built out of a coupleof three-position,0.1OO-inch, inline connectors(seeFigure1l-18). If you are looking to useservosfor driving a mobile robot,they will probablyhaveto be modifiedfor continuousrotation.In 123RoboticsExperiments for the Evil Geniw,I go throughthe basicstepsrequiredto
AA battely
modify a servofor continuousrotation.A quick Googlesearchshouldfind the informationfor your servosvery quickly.Eachmake and model of servo requiresslightlydifferentmodificationqand with several hundreddifferentservosavailable,it would be impossibleto try and list the modificationsfor each one here. The controlsignalpassedto the R/C servois known asa digitallyproportionaLsignal,whtchis quite a mouthful for somethingthat is really a modifiedPWM signal.Theperiod of the signalis 20 ms with a pulse and a duty cyclethat rangesfrom 1 ms to 2 ms,with the time betweenbeinsthe set positionof the servo.
:..
-:
I
-r,
i' :..:
I
i^. I
Figure1116 Servocircuit
272
Figure lllT Servocontrol circuit built on a breadboard
l , e 3 P I C @l ' l C l JE x p e r i m e n t s f o r
the EviI
6enius
.
PAGE Mainline
nop
i
For
:
ICD Debug .
cl.rf clrf
PORTA POR!rC
movlrf movlw
c!,IcoNo b,00001101, A.DCONO
bsf nrovfnr
SEATUS, RPo 0xD1
movwf mov1ff
OPTION REG ^ 0x80 1 << 3
morrwf movllr
ANSEL ^ 0x80 b,00010000,
morr'wf rnovlw monwf clrf bcf
ADCON1 ^ 0x80 b'011000' TRISA ^ 0r.80 TRISC ^ 0x80 STATUS, RPo
clrf
gervostate
i U€e Simple M/C , Stat€
Servo
movLw
0x80t
Start with in Middl"e
Servo
novwf
gervocount
t ,
rnovLw nov{rf movlw aatallw
IIIGE ((20000 / 5) DLay IJOW((20000 / 5) -1
btfsc alecfsz goto
sTATus, Dlay, f S-3
l
t conlDaratols
FiSUtel'f-18 Servo-to-breadboardconnectormade Irom two three-pinin-line connectorssoldered together
Someservosrequirea 1 to 1.5ms pulse,but you should be able to identify thesequite easilyusingthis circuit. And, if you havesucha servo,modifyingthe signal generatedby this experimentis quite easy. In this experiment,I usea potentiometerand the PIC16F684's ADC to specifythe positionof the servo. The valuereturnedfrom the potentiometeris displayedon eightof the 10LEDS built into an LED display bargraph.Thisfunctionwasodginallyput in to debugthe ADC operation,but I left it in becauseI liked seeingthe LEDs move with the servo.Thecode for this applicationis asmServo.asm. naamservo titl€ Prc15F584n ; . i t
-
Cotttlol1ing
lfhia Progiam uonitors a Pot (RA3) and movea a Servo at RiA5 Accolaling!.y. lhe Poaltlon of the Pot.
a Servo
a!
LEDg Inflicate
the
utrk€ Pledlko 04.L2.26 I,IST R=DEC rNcr.uDE "pl6f
58{. inc'
CONEIG _FC![EN_OFE & _IESO_OFF & _BOD OFF & CPD OEF & _CP_OEF & _MCI.RE_OFF E P!'IRFE ON & wrt! oEF & _rMtoscro VariabL€s CBLOCK 0x020 TerE), DLay Servocounl Servos!at'e ENDC
a
A.DC on RlA4
, Enable t IiIRo with i {x PleEcale! , RA4 (}N3 ) ADC , InDuts , i
Select ADC CLock as Eosc/8
i
BA4 /aA3
i AII
As Inputs
PORTC Outputs
.t"
RtA3
Eartl are Not€a: i PIC16F58{ runaing 6ts 4 MHz Using t Interaal Clock t ItA4 - Pot CdEnanal t RA5 - gervo Connection t servoPin PoRTA, 5 #alefine RC43RC0 - Bils 7:3 of LED Oulput r RA2 3RA0 - Bils 2:0 of, IED Output ,
r i
from
r EnabLe
LOOD: bsf cLrf, bcf, bsf btfsc gotso StaltADC: bsf bsf goto R€A'IADC: novf movwf andlw
i Wait for ADC Input , lo be valid
z t i
servoPin
5 Cycle Delay f,or 20 ma
t Output r Sisnal
!!MRo INIICON, ToIF INTCON, TOIE Servoslate, 0
, VJail
Loop
a Servo
for
Ov6!f1o{t
value i calculate r 1 ms PulBe
in
,
Start
t Reatl
iorfto
1 << 5
novwf rlf, novwf €rsapf andLw
PORTA Servocount, Tamp Temp, w 0x0F
r t t r
t
Section Eleven l l o t o r C o n t r o l
ADC
0
ADRESB, vt S€rvocount b'00000111'
w
-' .,...
Reaala.Dc ADCONo, GO S€rvoslate, ADCDone
'
ADC Value
Display lhe a.DC Value Make Sure gervoPifl Stays Bigh
r Neeal Top 5 BitE
273
btfsc iorlw bcf A.DCDone 3 nrovf btfsc aublct
r"€
btfaE gto!o movwf movf
f . :
.i
.|
.:-
b!f,aa golo
STA!!US, C 0x10 PORTC Servoslate,
0
t R€Peat
Se!-vocounl,
w
t Gel Reaal rdth i Servo Value
r Atld
{ .
ai i t
novLw etldl!.w btfsc decfsz goto
]Jow ((18000 -r STAIUS, Z Dlay. f $-3
goto
]JooD
/
+ 255) t vlanh
5)
20 ms LooD
Delay r 5 cycl€ 20 ms t for t ReDeats
],ooD
t{ake 1 t rf zero, t Tahe i! away fron
INTCON, TOIE TMRO INTCON, TOIF !t Servocounl,
lgait for overflow Bepeat tso g€ts 2 m6 Delay
INTCON, TOIF
TMRO INTCON, TOIE INTCON, TOIF
IIIGE Dlay
{s
Bits
Z
sTATgS, 1 0
ServoPin
bcf btfaB gloEo
Top
Finish€al gervo
wiuh
Wait
ovelfIow
for
the
((18000/s)+255)
Thereisn't a lot to this applicationthat shouldsurpriseyou.I useTMR0 to createthe delaysor 1,024 cyclesfor the 1 ms delay,and then I use it twice to create the servopositiondelay.Readingthe ADC takes placein the first 1 ms delay,asthe operationtakes about 15 /r.s.So there is no chanceof it taking longer than the delay,andthis makesthe servocontrol operation completelys€f-contoined.(Self-containedoperations will be discussed in the next experiment.)The threeTMR0 delaysend up lastinga total of 2 ms, which meansI simplyhaveto delayfor an additional 18ms to get a total PWM period of 20 ms.
Experiment 102-Multiple5ervoControl Softr-uare5tructure
=J 1 Prc15F684
:*' *-*
1
;
(any
0.01 pF capacito! tYpe)
10k breadboald-mountable potentj.ometer 470() 10-pin
resistor
srP I
1.0-LED bargraph
dispLay
Servo connecto!s Radio DMM
1
Osci lloscope
.=: l;i
Needle-nose pliers Wiring
control
Bteadboard-mouotable SPST switch three-cell clip
kit
servos
AA battery
3 AA batteries
: '
# 4
As I saidin the previousexperiment,servosare very easyto wire into a circuit.To add a secondservoto the previousexperirnent'scircuit,all you haveto do is add . an additionalservoconnectorasshownin Fisure 11.18.
274
In addition,the additionalcodeis surprisinglysimple, especiallyconsideringthat the secondservooperates completelyindependentlyof the first.
l , P 3 P I C @l l C U E x p e r i m e n t s f o n t h e E v i l
Genius
Servo2counl, ENDC
Servo2slat€,
Servo2Dlay tl
PAGE UainLine r
*?4
nop
Figure ll-19
Two-servocircuit
The codefor this experiment(asmservo2.asm)is a modification of the single-servoapplication, with code addedto hold the servoat one extremefor 600ms, move it to the other extreme,hold it therefor 600mq and then move it back to the original extreme.This operationis carriedout usinga softwarestatemachine that is built into the 1 ms initial pulsedelayof the servopulsgjust like the potentiometerreadingfor the first servo.Asboth servooperationstake 2 ms each, the final delayis reducedto 16 ms,so the loop (and eachservo'sPWM) periodremainsat 20 ms. rraamservo 2 titLe f ldr a PIC16F684rr i t r i r i
Controlling
two
a Servos
![hia Program ltorrLtors a Pot at RA3 (RA3) anfl nov€a a gervo at BA5 Accortlingly. LEDa Intlicate the PoEition of the Pot. A aecond aerro, coanected lo RCs will nove back p!€-Drogranrleal anil folth undl€r a ginp1e routine.
Hartbrar€ l{otea: t PIC16F68{ ruuing at { UEz Using the t r I|tternaL cLock RA4 - Po! CotElanal r RAs - S€rvo 1 Corrnection r servol.Pin PORra, 5 #alefine Rc5 - Servo 2 CoEnection r PORIE, 5 #define Servo2PiD RC4;RCo - Bila 7:3 of LED OutsDuts r BA2:RAo - Bits 2r0 of, LED OuEpul r
t ,
Myke Pletlko 04.L2.26 I.IST R=DEC IIi|CLUDErt916f694.inctr
_coNFIG _CPD-OFF _wD4!_OFr
& &
EC!|E!{_OEF & _IESO_OFF & _BOD-OFI' & CP OTF & _MCIJRE_OFF & _PWRTE_ON & INIOSCIO
Variablea t CBIOCK 0x020 Te![I), Dlay ServolCoun!,
clrf clrf movlw monwf novlw novwf
PORTA PORTC 7 otcoNo b'00001101, alcoNo
bsf movlw
STATUS, RPo 0xD1
t For
ICD
,
llrra
off
,
Elable
D6bug
t*, CodE)alators llDc
on Riall
1 :
mor of movlw movtdf, clrf bcf
I'MRo !d.th 4x , Enabl€ i Preacale! OPTION_REG ^ 0x80 1 << 3 r RArt (.BN3 ) A.DC hput AliIgEL ^ 0x80 b.00010000, r se1€ct A.Dc clock as t Foac/8 ADCON1 ^ 0x80 b,011000, r RA4/AA3 Aa Inputs TRISA ^ 0x80 TRISC ^ 0x80 PORTC Outputs r All STATSS, RPo
clrf
S€rvolgtate
lrovlv
0x80r
rrovwf
gervolcouat
cllf novl$
gervo2stsate
movlrf
gervo2Dlay
movlw movwf movLw adltlLw
EreB ((2oooo / 5> + 256> Dlay Low ((20000 / 5l + 2561 -1f,or ADC Input t wait t to be Va]-ial STATUS, Z Dlel', f DeIaY Lo<'E) S-3 ; 5 C!'cle t f,or 20 lla
monwf movlw mor cf movlw
btsfac atecfsz goto
LooP: bEf
t , i r
0x20
r stsay in ; DUU InS
gervolPin
TllRo clrf bcf INTCON, ToIa bgl INTCON, ToIE btf8c S€reo1statse, golo ReatlADc SlaltADC I A.DCONo, GO baf gereolstale, bEf goto ADCDone R€adADC r movf ADRESH, $ gervolcount nov\sf aaallw b,00000111, LorLw
1 << 5
mo"lrf rlf movwf swaDf
PORTA gervo].counts, Tenp TetDp,
use SimpL€ state M/c gtart wilh Miildl€
t Oulput , sigmal
*
servo
in
fo!
c-,,, ir"
{U
cn /n 11
a Servo
Overflow
\-, q
0
t
sEarE
.-fr F3
Arrc
0 r Reaal LDC Value
r DisDlay
the
t KeeD Servo
r Neeal Top
ADc ConlroL
5 Bits
w
Section Eleven [ ' l ot o r C o n t r o I
!I
g€rvo
Po6ilion
, vfaits for
w
F-r
275
aaal].$ btf,ac iorlw movwf bcf ADCDone: rnovf
0x0F STAIIUS, C 0x10 PORTC S€reolgtate,
0
t Repeal
Servolcount,
w
i
goto servo2Done gervo2stale, lncf novl$ ot<020 genrozDlay novcrf g€rvozDone goto Servo2gEate 0:
r Aald Top Bil
Reatl
Get
g€rvo
with
i Value
FI
o
f{ JJ
g
o
U
o ${
0)
(n o F-f
P{
.Fl
{J F{
btf,Bc movhr aubllr
STATUS, 1 0
Z
btfaa goto novwf bcf movf,
INTCON, TOIF $-1 T!m.o INTCON, I0IF gorvolcount,
btfsa golo bcf
INACON, ToIF $-1 g€rvo1Pl.n
novlrf bcf btfaa goto
lltRo IN:!CON, T0I! rNTcoN, T0r! $-1
bBf
g6rvo2Pin
r If zero, Make 1 , Iake lt away frofir
w
, ,
t t
clrf TllRo bcf INTCON, TOIT bsf INICOII, ToIE g€rvo2gtat€, eovf xorhr 0 gTATttg, z btfac g€rvo2state_o goto laorlvr 1 ^ 0 btfsc STATUS, Z gervo2gtat€_l goto xollhr 2 ^ tblfac STATUS, Z g€rvo2gtat€_2 goto s€rvo2gEat€_3:
I
I
f\
o Fl
{J
g 0,
E
'rl
tt 0) 9r
X
bcf STATgg, C gervo2Dlay, rlf noverf Tetqp rlf rerE, f rlf TetE, f rlf TetE, f lrovf t6tqr, rtr gTArVS, C blfsc novhr or.FF novwf Servo2counl alecfsz Servo2Dlay, goto Servo2Doa€ cllf Selvo2slate novlw 0x2O gefiro2Dlay lrovlrf gervo2Done goto servo2gtate_1: bcf rlf r[ovwf rlf rlf llf novf btsfac novlrr aulchr novwf alecfsz
gTATug, C gervo2Dlay,
0
w
i
gervo2 g€rvo
!ou!
lgith
for
t WaLt
Overflow
coale
s€rvo2count s6rvo2Dlay, gervo2Done
novlrf incf gtoto
s6lvo2D].ay S€rvo2gtate, Servo2Done
Baaea[ on
fo!
2 slat€s
r llulliDly
blz 15
f i
At
Extrem€
f
0x10
gervo2Dlay nrovwf g€fvo2gtete, incf Servo2Doner nrovf s€rvo2counts,
i llove to ,. Extreme
Oth€r
f w
i i
Get R€aal vith VaLue
btfsc novLw
sTATug, z 1
sublw
0
btf6s goto novwf bcf llovf,
r!q!co!{, TorF S-1 TllRo IN!!CO!{, !!oIF Servo2count,
btfas goto bcf
rN:!coN, TorF S-1 servo2Pin
novwf bcf blf,aa goto
T!{Ro INIICON, !!oIF INIICON, ToIF 9-1
movlw novwf novlw
HIGH ((16000 | 5l + 2s5l Dlay l.oll ((15000 I 5) + 255, -1 t want 20 na
adtUw blfBc STA!!US, Z alecfEz D1ay, f g o t s oS - 3
Exlleme Store
f
goto
At
Other
!{ake 1 lo i Lf. z.ro, Negatioa Elror t Avolil array frorn t Take it
IJooP
w
for Ctv€rflow t weil i R€trreat to g€t 2 ns i DEIEY
t ;
Finished gervo
r I4Iai!
for
witsb
tshe
overflow
LooD
r 5 C!t'c1€ Delay 20 mE ; fo! i Repeat
l.oop
Extrdte enA
w
t cioLng to t Extrdn€
oth€r
r lrultiDly
b!'
t Al
16
Exlrqle
r Negate il t Olh€rwige
This application demonstratesthat you can create surprisingly sophisticatedoperations in the PIC MCU even when you have a limited amount of time to create them.The secondservostatemachinerequires around 33 instruction cyclesto control the servo;about 30 times fewer cyclesthan are available.With many robot applications,it isn't unusual to seea variety of different functions "tucked inside" the servo delay loops and using the PIC MCU's built-in timers.
Stor€
f
{rl 276
S€firo
Otr€rflolt
ger,uo
t Oth€FdiE€
Poinl
Orisinal
t !4ove !o t ExEl.dr€
1
oligirel
t Wait
0x10
gervo2cou,lt gervo2Dlay, gervo2Doae
at Extrqle
f
s€rvo2s!ate_2: lrovhr OxFr novwf dlecfsz goto novlrd
t wait
, Al
th€
, eoing to i E rlr€ne
t At
TenD T6nD, f Tern9, f T€tqr, f T6q), rt S!!Al[oa, c oxEF 0 g€rvo2count S€rvo2Dlay,
qlnLsh€al gervo
t Wail
Fl
x
r WaLt for Overflow t ReD€al to g€t 2 na t DeLay
clrf alocfaz goto lrovlv
f
1 , , e 3P I C @I ' l C UE x p e r i m e n t s f o n t h e E v i l
Genius
ffi
Experiment103-Tr-uo-seruo FlobctBase uJithBsa lnterface
!,,
ar
iv &!!
s-? P r c 1 5 F 5 84 0. 01 /rF capacito! type)
(anY
\ I,J !*{
Servo connecto!s
2 Radio control
selvos
1 Breadboa!d-mountable SPST switch AA battely
Three-cell clip
P I C 1 2 F 6 ? 5 o ! P t C 1 6 F 6 84 based BS2 coftnaod simulator interface
AA battelies
:I
1 Breadboa!d
DMM Osci Iloscope Needle-nose pliels Wiridg
w
kit
In the previoustwo experiments, the full eighfbit valueof the ADC wasusedto specifl the positionof a servo,and this workedquite well.As will be shownin this experiment,the BS2interface,asdesigned,cannot sendan eight-bitpositionvaluealongwith a command value,which limits how the controllingse os can move.Along with the restrictionon absolutenumber of bits that canbe sent,thereis alsoa restrictionon whendatacanbe sentto the receiver.Thisfurther reduceshow datacanbe sentto the servos.In this experiment, I will demonstrateone way of solving theseissuesand discusshow to decideon the best methodoI implementing this[unctjon in your own applications. Using the programbaseof the previousexperiment, I changedthe applicationso that if a BS2command camein whenthe servoswerebeingwritten to, the commandwould be ignored.If the servocommandwas processed while the servoswereactive,the pulsewould be extended,which would resultin an unexpected movecommand.In Figure11-20,this is indicatedby the shadedWindowsin which receivedcommandsare accepted. The problemwith this methodoccurswhen the BS2commandis active,the PIC MCU softwarehas finishedsendingthe controlpulsesto the servoqand a low BS2clockis encountered. The protocolusedto sendthe datato the servo-controllinsPIC devicemust
be ableto sensethat the commandis not comDleteand shouldbe ignored. The basicBS2command-interface softwaredoes handlea goodportion of this functionby terminating receptionif a timeout happenswhile waitingfor additional clockpulses.In additionto this basiccapabllity,a methodis requiredto determinewhetheror not the datais valid and to feed backto the BS2an indicator of whetheror not the commandhasbeenaccepted. The way I solvedtheseissueswasto sendonly a responsecommandto the PIC16F684, with certain restrictions. The first restrictionis that asa response command,bit 7 of the eightbits sent,is alwaysset.If it is low,the commandwill haveto be ignored.Because thereare two servos,a bit mustbe allocatedto specily which servothe commandis beingsentto (I usedbit 8 of the incomingdatapacket).Finally,to ensurethe datais valid,the lastbit mustbe zero (the reasonswhy will be explainedin a moment).Thisreducesthe number of positionbits to five and providesthe servoswith onlv 32 differentoositionstates.
ra f 5 I
;
r-qJ !
:
*"q'*
! i
*E
&: servotL Servoz
Figure l1-?0
i;,
fl
fl
Servoavailable
SectionEleven I ' l o to r ( o n t r o I
271
nl
d
na +J ta
o
e6
o ${
The reasonfor making the least significant bit zero is to handlethe casewheredata is partiallysentwhen the data-readwindow becomesactive and someof the bits are read.After sendingeight bits, the BS2 will put its data pin into input mode,but the PIC MCU will still be reading the primary command data, and its data pin will be in input modealso.Becausethe PIC MCU data pin is pulled up,a 1 would be receivedasthe leastsignificant bit, which is invalid. Therefore the PIC16F684 controlling the application would reject the command. I decidedto usethe responsecommandinsteadof the straight eight-bit command becauseif the received commandwasinvalid,the PIC16F684would not respond(becausethe commandhad bit 7 reset)or becausebit 0 wasset. In the casewhere eight valid bits werereceived,the PIC16F684would attemptto respondwith the eight times the servo-positionvalue sent or with 0xA5 to indicate that the commandwas (i.e.,anythingother than not received.These responses eight times the servo position) indicate to the sending BS2or BS2 simulatorthat that the commandwasnot receivedand the servopositioninformationhasnot changed. This method, while seeminglycomplex,worked very well on the prototypecircuit (seeFigue 11-21)used with the asmBS2Servo.asm softwareand connectedto
]To Servo 1
Figure ll-al
BS2 two-servocircuit
a BS2 simulator. If the position information was invalidly received,the LCD display on the BS2 simulator would either have an invalid value or a value of 0xA5. When deciding how to implement a communications protocol like this one, a number of issuesshould be considered, and,asI will discussin the next section, a number of different options should be reviewed.In Table 11-2,I have listed four options for implementing a BS2 command and their comments.While the methodpresentedhereisn't what I would considerthe best,it was the easiestto implement with an unmodified BS2 simulator on a workbench.
(,
aI o
F F{ II
fn 16
Table 11-2 EomparlngDlfferentMethodEof sending servo PositionBaia from a BSa or simulalor ODerationSeauence
Eommentg
Expandthe data packet
16-bitdata word from BS2
Add a "handshaking"line from the servocontrollerto the BS2
After se o commandscomplete,enable "Bs2Receive"pin until5 ms beforenext set of servopulses
will requirecustomsoftwareinsteadof shiftin and shiftoutcommandsThe resultingwaveformwill not be compatiblewith existingsoftwa.e. Disable"Bs2Receive"5 ms beforenext servopulsesto
Sendfive-bit servopositionalong with servoand resetbit 0
Sendservoposition,expect position* 8 returned
avoid changing software timing. Eliminates reset bit 0 and gives a maximum of seven servo position bits. Adds requirementsfor an additionalpin to be used. Method usedhere:OnIy frve positionbits but couldbe usedfor mobile robot d vingse os.
Sendtwo packetswith eight bits 1.Sendhigh four bits of servoposition Longestpacketlengthbut properly receivedfour bit of positiondata for specifiedservo 2. Sendlow four bits of servoposition valuescould be savedto avoid resendingdata.Thisis 3, Sendrcsponsecommandto verify servo the most difficult method to test on the workbenchwith positioninformationreceived the BS2simulators
{.}
H
.r{
t{ P-,
X
278
l , e 3 P I C @I ' l C UE x p e r i m e n t s f o r
the Evil
6enius
Section
Twelve
SolvingProgramming ProblemE in PIE@ Microcontroller FssemblgLanguage Thereis a certainirony with the first pointithe point of the exercisewasto help the studentbetter understandhow to programthe PIC MCU in assembly language. In the previoussectiongthe PIC MCU instructionsand basicprogrammingbuildingblocks werepresentedand shouldhavebeenfairly easyto work throughsuccessfu lly.The programming assignmentslistedhere,althoughusingthe skillsdeveloped in the previoussections, force the developerto choose the bestinstructionsand codesnippetsto implement A good test of your ability to developassemblyJanthe applications. This uncertaintycan be daunting. guageapplicationsis to attemptto developprograms The bestway to becomemore familiar with PIC in assemblythat performfunctionsthat are normally MCU assembly-language programmingis to actually programmedin highJevellanguages. The classof prodo it.This meansyou shouldsimplystartwriting code. gramsthat might be most effectivefor this experiment It may not work properly,but asyou think throughthe includestraditionalmathematicalprogrammingprobprocessof putting down instructionsthat carry out spelemsand conversions that don't requirea lot of learncific tasksand seethem execute,you'll learn from your ing to understandhow they work, but may requirea mistakes. You'll learn how to recognizethat it isn't bit of thinking to solvethem effectively. working,be ableto identify the instructionsthat are The problemsandsolutionslistedin this section producingthe wrong result,and then changethem so wereoriginallydevelopedfor grade12 (senioryear) the applicationcodeperformsthe task that you high schoolstudentsto leam about assemblyJanguage wanted.Theseskillsdo not comefrom readinga book programming.The assignments themselvesare quite and following an exampleiyouhaveto force yourself simple.None requiremore than 50 assemblysource to comeup with somecodeon your own and get it codelines.Eachstudentwasgivenone of the assignto work. mentslistedbelow and the taskof researchingthe The MPLAB IDE combinesthe editor,compiler/ requirementand then comingup with the "best" soluassembler, and simulatorin one packageand is a very tion for it. Despitethe advancedlevel of the students powerfuldevelopmenttool that you will haveto and the simplicityof the final applicationEthe students becomefamiliar with. So far in this book,I haveintrohad a surprisingamountof difficulty comingup with ducedyou to its basiccapabilitiesand givenyou a few the solutionsto the assignments. hints on how to useit for applicationdevelopment,but I believethe reasonsfor the difficultiesare asfolyou'll haveto learn how to useand customizeit so it lows: works mostefficientlyfor you.None of the applicationspresentedin this section(and,asI haveargued, . Uncertaintywith PIC MCU assemblylanguage none of the applicationsin the book canbe accomANdthE MPLAB@IDE plishedwithout taking advantageof the MPLAB IDE . Difficultytranslatingmathematicalconcepts simulator). into programmingalgorithms Tianslatingmathematicalconceptsinto program. Inexperiencein evaluatingprogrammingalgoming algorithmsrequiresan explicitunderstandingof dthms both the requirementsand the potentialsolution.For you will haveto do someresearch theseapplications,
279
L.
. r-l {J
d U
.Fl ,-|
9{ .l.1
dJ r-{
5
E ..1
m I
{J
bt
. r.l
kl
and be ableto understandwhat is beingpresented.I recommend keeping the mathematicsand programming textbookshandyand usinga searchenginelike Google to researchdifferent explanationsof the mathematical concepts Do not fall into the trap of using only one sourceof information. Although one source may be good for someinformation, there will definitely be better sourcesfor other information. And as with any research,don't treat everythingyou find (whetherit's from booksor the Internet) asbeing100 percent correct, Check your sourcesand get more than one sourceif possible. When you understandboth the application's requirementsandthe theorybehindthe solution,look for multiple waysof implementing the solution. Use this asyour basisfor determining what is best.When I am given a task, I try to come up with three different waysof accomplishingit. Chancesare one solution will becomeimmediately obvious,but if I pushmyself to look for multiple solutions,I'll either come up with a better solution,or an improvementto your original solution. Before going on to the assignmentsand their solutions,I wanted to saya few words about what makesa solutionthe "best" solution.Tryto avoidsimplistic like "the shortestprogram"or "the measurements fastestprogram,"becausethey don't reflectthe dynamic nature of real-world application programming. Instead,try to articulate your requirements as clearly aspossiblein a defined area as a requirement continuum,likethe one shownin Figure12-1.By definingthis area,you'll be ableto more clearlyand easilydefineexecutionspeed,amountof program memory,and variablesthat are availableto the prob-
Code Size Smallest Progaam
'Best"Solution SolutionArea Meeling Requirements
Speed 'f Figure ?-'f Besttriangle
lem.The solutionsthat lie outsidethis areacanbe immediatelyrejected,and the bestsolutioncanbe more easilyidentified. Before working through each experiment of this section,I suggestyou try to come up with your own solution to the problem (even going asfar aswriting your own solutionandcomparingit to mine).In most of the experiment write-ups,I have presentedmultiple waysthe problemcanbe solvedaswell assuggested someadditional experimentsyou can write. By doing this,you will get a better understandingof how the solution works and you'll becomemore familiar with programmingand the PIC MCU assembly-language MPLAB IDE. Chancesare you'll alsocomeup with better solutionsthan the onesthat I cameuo with.
! a
Experiment 10U-Eieht-Bit Multiplication r-uitha l6-8it Product
{tr O FI {J
multiplication asrepeatedaddition and add the multiplicandmultiplier numberof timesasI showin the examplebelow:
0,
trasnMultlDly tsitle aalttition.
c
g
t Thia l)logram uses leDeateal litultiplication. r impledleat
"l.1
t-l
rrcl Equival€nt
(,
9.{
x
1 - uulEiply
The fist assignment,multiplying two eight-bit numbers togetherto form a 16-bitproduct,canbe accomplished a number of different ways.The most obvious way of doingthis is to go back to the definition of
280
(!ftrltip1ier
aaLlition
to
Codle;
Proaluct = 0t = valuelt uultiplie! = valu€2t llultiplicantl $hj.le
Repeat€al
UEing
!= 0l
l , P 3 P I C @l ' l C l JE x o e r i m e n t s f o n t h e E v i l
ll
15-Bit
//
Proaluct value
aalal Each velue
Genius
t
Proalucl = Ploaluct + ltultiplicanal, // Jrtltl DlulEtpltcandl to Proilucts = !4u1tiD1ie! - 1t Multil)].i€i // Decrement MuLliplie! Couat //
|
lrhtle
iof (1 -=
!1,
ll
Halfl$are No!€a: PIC16F68{ runalig
FiniEh€d,
at
Loop
{ MEz in
Eor€ve!
Sinulator
lryk€ Plealko 04.08.18
8'1100' ldu1tip1i€r 8'11000' ltultiplier 8'110000' tluLtiDLier + 8'1100000' !,tultiplier
LIST R=DEC INCIJTDE I'p16f 58{. incn r variaSlea cBr,ocK 0x20 Ploaluct:2 UultLDlicanal,
, !'inlEheal Resul! i valuea for t Pfocessingr
Multil)lier
org
of
Multiply
1
0 r hitiaLize t valiebL€s
clrf I[ov1tr novwf, Inov1lr rnovwf llovf, btfEc goto LooP: atlikdf btfac incf tl€cfBz golo EnfllJoop: goto
Proaluct + 1 47 I'lultiplIe! 35 Multiplicanal l.tulti91i6r, f STATUS, Z Enflloop Proalucl,
f
STATUS, C Proaluct + 1, f uultiDli€r, f
, Valuel
<-
47
, Value2
<-
35 == 0?
, MultiDli€r i
Yes,
Protluct
= 0
t Aildl Multiplicanal Protluct i 15-Bit
I,ooD
UultiDLier t Decrenent i andl RepeaE !=0 , while
s
i
= 8'1100'
<- Bit
0 of
= 8'00000'
<- Bit
1 of
= 8'110000'
<- Bit
2 of
<- Bit
3 of
= 8'0000000'
to
r,ooD
5ection Tulelve
X
'6
o
y,! f-.,
r* ry
<- Plduct
, F
50)
= tlultipLie! x !tultip1icanal - ( (MultiDlier & 0x00F) + (Uultiplier 0x0F0)) x ( (Multiplicand & 0x00F) (l{trllip].icand & 0x080) )
& +
and then multiplying them together usingrtrst, outside, inside,last (FOIL). The program that I cameup with is "asmMultiply2.asm." This lastprogramrequiresabout 12timesthe number of instructionsasthe previousexamplesand one more file register byte for the Temp variable.What it hasin its favor is that it always execltes in 104instruction cycles. The conditionalassemblystatements(i.e., the if, else,and endif directives)selectbetweensetting the PCLATH register for the table jump or delaying a cycle so no difference existsin how the code executes basedon whereit is located. Despiterequiringmanytirnesmore instructionsand not being substantially faster than the shifting
S o l v i n g P r o g n a m inn g P r o b l e m s
rc Ffi }J'
{q l r
I
s
r.. ,7,
A
F l r
end
This solutioncouldbe consideredbestby some measurements becauseit requiresonly 15 instructions. But a fundamental problem existswith this method: The number of cyclesneededto multiply two values togetherrangesfrom 10 to 1,539dependingon the value of multiplier. For some applications,this is not a problem.But for many applicationEespeciallythose involvedwith real-timeoperations(suchasrobots), this variability and potentially long execution time couldbe a significantproblem. When you first learnedto multiply,you may have doneit like the exampleapplicationhasdone it, but after a while,you useda more sophisticated methodin which the multiplicand was shifted to the left accord-
ftl
$
"asmMultiply3.asm"showshow this is implemented. If you were to test the secondapplication with different multipliers, you would discoverthat it generally executesin 90 to 110 instruction rycles.This is a huge improvementin speedand predictability,with only six instructions(andno file registervariables)addedto the first example. I wantedto seeif I couldimproveupon the execution speedof the secondmultiplication example by multiplying larger digits.Four bits, or hexadecimaldigits,seemedlike a naturalprogression, and a table was built with the products for all the possiblefour-bit multipliers and multiplicands.With this table in place,I then multipliedthe two eight-bitnumbersby breaking up the multiplier and multiplicandso that they look like the binomialexpansion: Proaluct
finisheal,
<dot> 1 (ser) 0 (R€set) 1 (Set) 0 (Reael)
B'0111100, (Deciral
ENDC PAGE , Maialiae
ing to the multiplier digit by which it is being multiplied.Thismethodis actuallyvery easyto implement in PIC MCU assemblyif you assumethat eachdigit is a bit. The productof a multiplier digit (or bit) and the multiplicand can be either the multiplicand or zero, and shifting the multiplicand by the multiplier digit is accomplishedby simply shifting the multiplicand. For example,to mulriply 12 (8'1100') by 5 (8'0101') in binary,it would look like:
28L
,-, "
t?3 F
,-, "
ta
,-,.
tJ
ltr
:, "-4
ru
multiplicationalgorithm,you shouldrememberthis methodbecausethe theorybehindit canbe usedfor processorsthat have a built-in eight-bit multiplication instruction(suchasthe Microchip PIC18seriesof microcontrollers). By usingthe methodologyshownin this example,you can create a 16-bit multiplication routinethat executesin just a few instructions. After creatingthesethreeapplications, we cannow askthe question:which one is "best"? For virtually all
applications, the secondexample(asmMultiply2) would be consideredbestin termsof executionspeed and instruction optimization. The last example would be consideredbestonly for applicationswherethe constantspeedis requiredor whereit wasknown beforehand that sizeof the multiplier and multiplicand neverexceeds15 (requiringno more than four bits).In the latter case,the eight-bitproduct would be found in a constant 13 cycles.
$*{
a
ExFeriment 105-Bivisionof a 1E-Bit Valuebg
a
\&;
an E i g h t-B iVa t lue "aamDivide litle arl g Bit Valuerl
'"H
!i
. *., a : 1
i
{JJ
rJ
Programmingfor divisionroutineshasmanyof the samecharacteristicsasprogramming for multiplication. There are severalwaysof doing it, and each methodhasdifferentcharacteristics that make them bestfor certainapplications. In this experiment,Iwill look at a numberof differentwaysof implementing division operations and comment on their effectiveness.The routinesthat are presentedhere are for positive,nonzero integers.I will discussmaking these routineswork in the generalcaseat the end of the experiment. If multiplicationcanbe describedasrepeatedaddition, then,asits inverseoperation,dlvisioncanbe describedasrepeatedsubtraction,subtractionbeing the inverseof addition.A simpledivisionroutine can be built from a subtractionroutine that repeatedlysubtractsthe divisorinto the dividenduntil the dividendis lessthan the divisor.T\e quofunt is inuementedduring eachloop,and at the end of the routine is equalto the numberof timesthe divisorcanbe taken away from the dividend. When the dividend is lessthan the divisor, it is passedback to the calling routine asthe remainder.A sampleprogramthat implementsdivision in thiswav follows:
1 -
Dividle
a 15 Bil
r r t t
ThiB program finalE tshe quotienl redlainaler for iliviatins a 16-bil value value frodr a! 8-bit by repeateil subtraclion.
r
'C"
Equlvalent
anal
Cot[€:
= Divialend = 123{5t Rdrainale! = 0; la 15 Bita // Ouotleat Ouotient = 47, DlvLso! is 16 BitE // Dllflaot while
( Remalntl€r
>= Diviaor)
{
- DivLEolt = Reneinaler value // Take avay Divlsor Quotient=Quotient+1, // Incr€neat ouotients j // et L}rw Remaintl€r
//
Quotienl
while
and Diviit€ntl
a!€
correct
(1 == 1), //
Ealthrare Note6: PIC15F58{ runaing
Finished,
at
Loop
Foreve!
4 v,J, z Ln Simulator
!&.ke Predlko 0{.04.13 IJIST R=DEC rNcrJIrDE np15f 5811.lnc" t valiable6 CBIJOCK 0x20 R€[lainaler:2, Divialenat : 2 DiviEo! Temp ENf,IC
Quotient:
2
:,4
282
valu€
l , e l P I C @H C U E x o e r i m e n t s f o n t h e E v i l
Genius
bl'
PAGE r !!al|rll.ae org
of
Diviale
0
novllr
high
123{5
t Inilialize veriables
novwf trovwf rdovhr novnf nrovwf, movhr mov f
+ 1 Divialead R€maiudle! + 1 low 12345 Diviatenit R€[rainal€r {7 Diviaor
clrf clrf
Quoli€nt Quolient
+ 1
Diviileloop! movf R€lEj.ntl€r
+ 1,
novlrf rnovf aublrf bEfa5
TedE) DlvLaor, w Re$ainater, w STATug, C
alecf btfac
TdE), TdE),
r If USB of (Redlaintte! l= 1 ; - Divisor) r then Subtract if set tshen t EIse, t Finiah€dl
DivialeEnd
tnovwf
R€eaiuale!
movf movwf
T€rlp, w Reneinaler
+ 1
incf
Quotient,
f
btfsc incf
STAIIUS, Z + 1, ouotient
goto
Divitleloop : $
Diviso! r gubtract anal r from Rdlainil€r t E e e i f > = 0
; If Carr!. Set, Lolt r Bt t€ of R€rEintter
f 7
goto
DivialeEnil goto
rtr
t t
Save ResulEE sulctracEion
i Increm€nl t Quotienl
of
Eh€
f
r FLalEheal,
]JooD
€nil
When you look throughthe diyisionby a repeated subtraction subroutine,you'll seethat I subtract the divisorfrom the dividendto seeif the resultis negative (andthe dividendcanthen be referredto asthe remainder).Ifthe resultis positive,this resultis saved asthe new dividendinsteadof calculatinsa new dividend. Repeatedly subtracting the diyisor from a number is potentially the slowestmethod of implementing division,justasrepeatedadditionis a fairly poor way of implementingmultiplication.Division canbe implemented in a similar manner to multiplication by fhst shifting the diyisor up so it is greater than the dividend and then shifting down and testing to seeif the shifted divisoris lessthan the dividend.If the shifteddivisoris
lessthan or equal to the dividend, then the divisor is taken away from the dividend, and the shifted amount is addedto the quotient.I find it is easierto understand how the algorithm works by coding it out as I havein "asmDivide2.asm." This rnethod and code for diyision is probably the most efficient and suitable for virtually all applications. Even though it requires twice the number of instructions asthe repeatedsubtractionmethodrequires,it executesreasonablyquickly and accurately. Going back to your grade schoolmathematics,you probably remember there is another way of dividing onenumberinto another:Thatis,write the numberas a fraction and multiply the inverse of the denominator with the numerator: A dividedby
B = A / B = A x
ll
/ B)
And althoughyou may rememberit, you may not seeits applicabilityimmediately.ThePIC MCU's processordoesnot havethe floating-pointnumber capability required to calculatethe reciprocal of B (or 1/B).Thisis true,but a positivenumbercanbe producedif, insteadof dividingthe divisorinto 1,it is dividedinto a much largernumber-such as256.This would turn the previousequationinto:
['J
X
u
s
rl
F. '.a tv 11
# O
tn t?
**r"
v.
A divided by B = A / B= tA X {1 / B)l x 1 2 5 6 / 2 5 6) = l A x ( 1 0 0 / B ) l x 2 5 6
Although this is an improvement,you may also be wondering why I would go through the extra work of dividing the divisor into somenumber and then multiplying the reciprocal of the divisor by the dividend.The answer:This method makesthe most sensewhen you are working with a constantdivisor. Calculating the reciprocal of B can be implemented by the assembler's built-in constantcalculator,and once the reciprocal has been calculatedasa constant,it can then be multiplied with the dividend,asI showin "asmDivide3.asm." This methodusesabout60 percentof the instructions of the full division routine and executesin less than a quarter of the number of cycles.Note that divisionby 256is accomplished by simplytaking the upper byte of a two-byte number.This routine is simply not asaccurateasthe other methods;no remainderis produced and the quotient is typically off by 5 percent. This method is suited for applicationswhere the divisoris a constantand known,and the dividendgoes through only the division processingstep.Situations where this division routine is best suited include convertinguserand sensorinput datafor storage/ processing.
Ht
pl lJ
{p\ I
,
w }J.
*
pr H IR
5ection Luelve
Solving Programm i ng Pnoblems
283
Remember,the casewherethe divisoris zero is generallyconsideredinvalid.In many processors with built-in division circuitry if a divisor equal to zero is encountered, an error is flagged.Asnoted at the start of this experiment,none of the threemethodsof division shownhere will work for this case(and will either neverend or causea build-timeerror). To check a single-bytedivisor, you can sirnply run the value through the PIC MCU's Algorithm,flogic Unit (ALU) statuscheckand go to a flaggingroutine if it is zero: Dlvlgor,
f
Ru! DiviBor through slatus check withoul chaaging conlentsE of IIREG If Zero flag a€!, jump to z€ro Diviao! hanaller
.flt btfsc
fi :-!
iu L-' I r'l
goto
sTArus,
z
DivisiorByz€ro
To check a 16-bit value, you can OR the two bytes tosetherandseeif the resultis zero: novf ionrf btfsc golo
Diviso!,
w
DiviBor + 1. STATUS, Z DiviaionByzero
r T'wo Byteg , = = 0 2
of
Divisor
w i If Z€ro fLag a€!, t Jull9 to Zero Divisor handler r
=+ Quotient =Remainder
Figure la-a
Division signs
Finally, you may have an application that hasto handlepositiveand negativedividendsand divisors. For thesecases,Iusethe Division SignChart shownin Figre 12-2.Before executingyour division routine, mark flagsindicatingif the dividendand divisorare positive or negative,convert the negativesto positive values,executethe divisionroutine,and,upon exit, changethe quotient and remainder to negativesif appropnate.
r-f Iu
4
Experiment 106-5quaringa NumberUsing FiniteBifferenceTheorg
i
{'*{ "6-r fil
"r".; ,-! d1 !*{
Whenyou are dataprocessing, you will discovercases whereyou needmathematicaloperationsother than multiplication and division. You might be thinking of sine functions and logaritbmic operations and shuddering at the thoughtof trying to calculatevaluesfor them in the simplePIC MCU's processor. But remember,
thesecalculationswere performed literally for centuriesbeforethe inventionof the disital "comDuter"or handheldcalculator. I have put the word computer in qtotations in the previous paragraphbecauseit was the name given to individualsthat wereresponsiblefor calculatingvalues computers.Tltese people spent literally months working througha sedesof calculationsto comeup with the answerto a problem.As you would imagine,the major problemsencounteredby doing complexmathematical operationsusinghumansincludedthe time requiredas well asthe accuracyof the final result.The seemingly simpleoperationof producingsineandcosinevalues for a book of tables for navigation wasfraught with many problems,due simply to human error, that often resulted in the lossof ships and lives.
g&l
284
l,e3 PICo llCUExoeriments fon the EviI
6enius
In order to minimize the amount of time reouired to perform calculations(and the opportunitiesfor errors), a number of different mathematical tools were developedover the years.One of the most powerful tools wasgiven the namefinite differentinl theory,it which simple operationswere analyzedto find easily recognizabledifferencesbetween calculation values. The most-often-usedexample of how finite differential theory works is the calculation of squares.Looking at squaresmay seemlike a strangeplace to start, but it will make more senseat the end of this experiment. To show how finite differential theory works,considerTable 12-1,in which I have listed different integers,their squares,and the differencesof the squaresto the valuesof the adjacentsquaresYou can seethat when I have calculatedthe differencesin the values between squares,they can be expressedsimply by adding two to the previous difference. It should be obvious that by simply knowing that the squareof zero is zero and the squareof one is one, that you can calculatethe squareof any integer quite quickly.The code that I cameup for calculating the squareof47 is namedasmDifferenceand is listedhere: "asnDiff€!€nce tl.t1€ DLfference Theory,'
-
squa!€s
u6ing
Firile
Table 12-1 Intege|5, Their Squares, and the Differenceg BetLUeen Them lnteger
Square
0lfference to Previous
Dlfference ta DlfferEnEe
0
0
N/A
N/A
1
1
1
N/A
2
4
3
2
3
9
5
2
4
16
7
2
5
25
9
2
1l
2
6 7
49
13
2
8
64
15
2
9
81
17
2
10
100
19
2
PAGE , uahlin€
rcrr EquivaL€n!
a
Cofle:
(Va1u€
// Nuriber to Starts WIth // Currents Square value rdlth 1 anal Add / / fjt att // Diff€rence l= 0) gquale for nveLuen // calculate
{ = Square
Sgua!€
Diffelence Value-
-i
//
€Iihw
+ DLff€reac€i ugflat€tl squale // calculale * 2t = Diff€lence ll Add to !h€ Diffor€Dce //
)
, rshile
(1 -=
Decr€deDt
lh€
Value
Hardhf,ale ltotes: PrC15F627l ruD.ling
Finishedf,
Loop
Forever
{ li'tHz in
LISr R=DSC rNcr,ltDE "plSf Regiat€rB
, varlables CBLOCK 0:120
o\
ra t
0 47 r hitialize value Squale + 1 Squale + 1 Diffelence 1 Diff,e!€nce
ailthrf lrovf btfsc incf atl&d trrovlw
squa!6, f + 1, Dlfferenc€ STATUS, C + 1. Differeae€ + 1, f Squar€ 2 i t Diff€r€Dce, f STATIIS, C * 1, Difference value, t t t IJooD
w
varielclea
Inc:aeage W 2
5
q
p, to
z
g
3 c o
Diff€r6nc6
Ft
f Decrdr€nt qounter
th€
value
Finisheal,
IJoot)
Siaulator
eDtl
627a. inctr
!, h
F'
i RaturD Her€ until == 0 , lvalue! i Atldl "Dif,feronce" i 'rgquar6'r to get i ita nelr valu€
t uyk€ Prealko 04.04.14
O
Difference
Diff,er€nce,
gtoto at
n F. 3 o p
CN
movf,
aiLlwf btfsc incf decfaz
o
I
LooD !
Counter
1)t //
lrovlw rrovwf clrf clrf clrf niovlw novwf
x
ts
thia
Valu€ = {? Square = 0t = !, Differeace while
of
t
-
VaIu6, Square:2 Dif,f,er€ac€r2 ENDC
olg usiag Eitrit€ Diffeleace Theory, Plogram findls the gque!€ for (ririth lhe given 8 Bit hteger 16 Bit Result).
FI
In addition to squaringnumbers (finding the value of a number to the power two), finite difference theory can be usedto calculateother powe$. You may want to spenda bit of time reading about Babbage'sDffirenceEngine to tnderstand how other powers are cal-
5ectionTurelve S o l v i n g P r o g r a m m i n gP r o b l e m s
285
cos (x) = 1 x 6/6! + ...
culatedand maybeto try to comeup with an application to do it on your own.Hint:As you go to larger powers,you will discoverthat more than one differencevaluechangesfor eachnew integer. Onceyou are comfortablewith usingfinite differencetheoryfor calculatingpowersof numbe$,you can usethis knowledgeto calculatedifferentvalues.The seriesformulaslistedherewill helo: sintx/ x 7/'l|
-
x
-
y'/Jt.
-
+ x )/ 2 1 + x j / 3 ! + i
x
+ ...
/3!
r / l -
- I )
(x x
+ x a/4! -
x'/21
l x - 1 )
2 / 2 +
1J'/3
/5'-
+ ...
Experiment 107- F ind t h e Sq u a reF l o o to f a 1 6 -Bi tN u m ber are the nunber of oaldl nuibera, sum is less t'han or equal to the nulllber the square rooE is calculauea for. This is the Difference r.n
F6!
value
I canhonestlysaythat the only thing I did not understandin high schoolmathematicswashow to manually calculatesquareroots.Looking back,I suspectthat it wasdueprimarily to my poor understandingof how repeatingalgorithmsworked (I had not yet learned any programming)and secondarilytomy reluctanceto learn the materialbecauseof the V on my calculator. Unfortunatelyin mostsimplemicroprocessors and microcontrollers, no built-in squareroot instruction exists-which meansthat when I haveto implement thesefunctions,I wish I had paid more attentionin high schoolmath. When facedwith the challengeof calculatingthe squareroot of a value,I usuallyfall on what I know finite differencetheory.It canbe usedto find the squareof a value,so by reversingthe process(subtracting the differencefrom the value)and recordingthe numberof iterations,the squareroot of a numbercan be found. title lhe
"asmsqRoot 16 Bit
Eintl
th€
square
takes aalvantag€ of sguare roots that
Root
i !r-1an+
^^.1a.
= 12345r = 1t
Digitcount odd = 1,
being
of lhe Finite Program.
//
val|ue
// //
squafe Root value Difference value
Eo Square
Root
q'hi1e {
t
)
(Oald <= value) // Take Away Difference >Renainder // until valu€=value-odalt Odd=odal+2t the Diffelence // Increase - Digitcount Digitcount + 1t Square Root Val.ue // Incren€nt // elihlt
i while
(1 == 1)t
//
r Earflware Noles: PIC16F684 nrnning i
al
Finisheat,
4 vr.lz in
Loop
Forever
Sinulator
, Myke Prealko , 0{. 04,13 IJIST R=DEC I N C I J ID E " p l 6 f 5 8 4 .
inc"
r valiabLes CBLOCK 0x20 value:2
of odit:2
value"
r ThiB proglam property of t
286
2 -
reverse Squariflg
vrho,a
the
i , i i r
value the Square Root is to be founal ProceBsing variables Sguare Root of the value
ENDC
l , a 3 P I C @l l C l J E x p e r i m e n t s f o r
the Evil
Genius
PAGE r llainline
of
olg
tion operationis eliminated,makingthe application both smallerand faster. The methodshownhereworksreasonablywell,but an arguablybetter methodwould be usingNewton's methodof zerofinding.This methodis basedon the function:
sqRooE
0
lrovlw
high
novwf rlovlw movwf
+ 1 value Lorn 123{5 value
ctrf
oald + 1
novlw novwf clrf
1 oild Digitcount
Loolt: novf subwf
variable i Initialize t to have lhe Square r Root Fountl f,or it
123{5
i R€Peat Uer€ until - oaLl value , calculate i !ilot6, R€auLt Storeal i Back in nvaLuen
@at + 1, w + 1, f valu€
novf subwf, btfEa ilecf
Odat, ra' value, f, STATUS, C + 1, value
blfac golo
+ 1, value SqRootDone
movhr
2
adtlrf bEfac Lacf
dd, f gTATuS, C odd + 1, f
incf
Digitcount,
goto
Loop
sqRootDon€
f, t If MsB of nvalu€n i Value iE Negative
?
i
3
the valuea
f
t
Cio to Nunber
the
Next
sets,
oaltl
value Incremenl of Ehe Square RooE
r comlrl€teal , Einish€al, IJoop
entl
If you comparethe equivalentC codeto this assembly code,you'll noticethat thereis quite a big difference;the assemblycodecalculatesthe valueminusthe difference(Odd) andstoresthe resultin "Value" beforecheckingto seeif "Value" is negative(the most significantbit is set).The correctC equivalentcodeis: ( (value
while
( odd
= oitd
DisitCount ]
//
- odd) > 0) = valu€ Itnlil // Take Away Dif,ference // Retlaindter is Lees than zero + 2t th€ Difference // Incr€a€€ = Disitcount +1, square Root vaLue // Incren€nl
elihw
I did not note this difference in the original code, because, asI havesaid,if you are new to C programming,the ability to embedassignment statementsin conditional statementsand check their valuesis not intuitively obvious By calculating the value for "Value" insteadof doingthe compare,a full subtrac-
Section Luelve
x
ru o !-t
r".
f(x) =G' -A t rnitialize t Differ€nt
H
WhereA is the originalvalueand G is its squareroot. Whenflx) is equalto zero,it shouldbe obviousthat G is equalto the squareroot of A.To calculateG, the approximationformula:
5 CI tst
c, = t(A/G)+ G1/ 2 is used.G' (G-prime)is the next valueof G and is calculated by dividing A by its squareroot and then averaging the difference with G The formula is executed repeatedlyuntil G and G' are essentiallythe same. Table12-2showshow this formula is usedto calculate the integersquareroot of 12,345(the samevalueas the examplecode).For the initial valueof G, I usually use1/: of the valueto find the squareroot ol The closer you make the initial value of G to the actual squareroot of the number, the fewer iterations are required to find the actual squareroot, but any value other than zero canbe used. In Table12-2,you canseethat eightiterationswere neededto calculatethe squareroot of 12,345,but two issuesshouldbe noted.Fhst,althoughthis methodis quite simple,it doesrequirea divisioncapabilityin the processor, which will add to the sizeof the squareroot routine. This is not a major problem, at least not comparedto the other issue.And second,when I calculated the valuesfor G' in Table12-2,I useda calculatorand roundedup fractionalvalues.If you wereto createthis Table 12-2 NEurtons Methodfor EalculatingIntegersquare Floots G':
1
4115
2
2059
2059 '1032
3
1032
522
4
522
n3
6
r59
118
7
118
111
111
111
S o l v i n g P r o g n a m imn 9 P r o b l e m s
I
r' P
;.)
n
U2 p H
T !
159
5
,a
ftF/6t + 6l/2
6
Iteration
\t
287
applicationin assemblylanguage(or evenin C), you would haveto somehowperform this rounding operatron. Unless,of course,you usedthe floating-pointcapabilitiesof the PICC LiterMcompiler,asI havedonein csqRoot.cand csqRootN.c,which I createdquickly to testthe PIC MCU's ability to perform a squareroot with a floating-pointresult.In csqRoot.c,I usedthe built-in C sqrt function: *includle <math.h> *incluale csqRool. c - Te6t /t zunctiOa
fi
PICC Irit€
square
llyk€ prealko 05.01.19
tlouble
l"{
s tr
SquareRoot,
NsqualeRooti
main ( )
{ Nruiber = L2345.0, // EstabLiah = Nunber / 3; Nsqua!€Root // cet seetl alo
tsh€ Nunber value
{
Root
= Nsquar€Root; = (SqualeRoot + (Nunber / Squa!€RooE ) ) (Squa!€Root != Nsquar€Root ) t
SquareRoot NsquareRoot
This Drogram wiLl sinply e:<€eut€ a single square root futlctlotr to s€e holr btg it is atral how long il takes to execute.
flt
Nu!ibe!,
) while
(1 == 1),
while tnyke Drealko 05.01.19
I
//
/2t
E'rd csqRoolN
f{
aloubLe !funber,
()
nain
(
q,
Squar6Rooti
Surber - 123{5.0, // Est.lrlish the Nunber SqualeRoot = Eqlt (Nunb€r) i / / GeE j.Ea gquar€ Root !'hile
(1 == 1),
,-rl )
-**
//
Enal csqRoot
andin cSqRootNc,I cameup with a simpleimplementation of Newton'smethod:
tEd #iacludle llincludle csqRootN. c - use /* gquale Root
! :
f*"
Nelrtson. s Metboat to
Thig Drogram wiLl sinply Rool Functi.on until the the olal.
Execu!€ N€!rton,6 new valu€ is tb€
Einat
Squate same as
cSqRoot.crequired585instructionsand 37 bytesof variablememory althoughcSqRootN.crequiredonly 292instructionsand21 bytesof variablememory.This is an improvementin sizeof abouthalt The question you shouldbe askingis why isn't Newton'smethod usedin the C sqrt function?The reasonseemsto be that Newton'smethodis quite a bit slower.When I pluggedin differentvaluesto find their squareroots,I discoveredthat Newton'smethodcould take asmuch as300percentof the time that the sqrt function took. This is anotherexampleof how different code,performing the samefunction will have different operating characteristics. The standardC sqrt function takes up considerablymore spacethan Newton'smethod, but is quite a bit faster.Although I shouldnote that eventhoughit's faster,the averagecalculationtime is on the order of 7 to 9 milliseconds. In either case, the squareroot functionwill take up a substantial amountof programmemory,so its usemust be chosen judiciously.
i:**
i
l
'r{ { r I i,l
'r,*,a
288
l , e 3 P I C o l l C l JE x p e n i m e n t s f o r
the Evil
Genius
Experiment lOB-fonvertinga Bgte into
4'
Three Decimal,Tr-uoHex, or Eight Binarg R5Cll Bgtes ( i = 0 r t < 8 r i + + ) //
for
(
all
I,ooD lhrough
,t\
( (Ted[) & 0x080) != 0) Digit Iil = r 1,, ll BiE seE eLEe Digit ttl = r 0 , t
,.,",
//
Blt
ReaeE
//
shifr
in
//
Done,
].ooD Folever
TeaII) = T€4P <<
When I first introduced you to programming the PIC MCU I usedthe high-levelcapabilitiesof the C programming languageto facilitate converting numedc data to ASCII.Theseoperationsare quite easyto do in a highJevel language,but you might find it daunting to write them in assemblylanguage.It may be surprising to you to discoverthat creating thesefunctions is assemblylanguageis not very difficult and is usually quite a bit more efficient than writing them in C. The trick is recognizingthat ASCII valuesare numbersand canbe manipulatedin just the sameway as regularvaluesare manipulatedin assemblylanguage. For example,if you had a numeric value of sevenand wantedto convertit into the ASCII charactercodefor 7,you couldadd sevento the ASCII charactercodefor 0. If you had the value of sevenin the WREG, you could convert it to the ASCII character code for 7 with the sinsleinstruction:
Like in C, a character'sASCII code is substituted whenthe character,enclosedin singlequotes,is encountered. The first program,asmByte2Bin,convertsa blte valueto eightASCII bit values(1 or 0) by looping througheachbit and testingthem to seewhetheror not they are set or reset.In this program(like in the others),I sta the conversionwith the high-orderbits so they can be seeneasily in the MPLAB IDE simulator's File Register display. tit'].e
"asnlBlt€2Bin
-
Nuliber
to
"C" EguivaleDt T€rE) = Ntrmbe!,
a Eingle €ight
Save
the
==
nhile(1
1)t
Harflware Not€6: PIC16F584 ruDnins
at
4 MHz in
n
gimulator
I
l$rke Preflko 0 { . 0g , 2 9 IJIST
R=DEC
rNcrrtDE np15f 584. lnc" i variabLea cBrJocK 0x20 Diqit: 8 TdE), i E![!rc org
*"*
0
movlw
123
monwf
Tedll)
movlw
Digit
novwf
FSR
novLw novwf IJoo9: llovlw
variablea
r Nl[iber
8 i '0'
btfsc TsE), aaldLw 1 novwf INDF llf Tern9, iacf FSR, f tlecfaz i, f goto Loop
t Use n123n to i Ploglrem
Test
t FSR to Poinl t variable
to
i lvants to
trlanl
to
tsbe
nDigitn
Do 8 Bi.ta
gav€
Either
IJIJ '0'
ra Bit 7 of "Tedl!)n sets? Yea, Conv€rt WREG lo '1' flodr'0' gave the AscII Digits ghift up teateil Tenp bit Point to the Next Digit R€peet 8x
Nurlber
r Finiaheal,
Loop
For€ver
enal
Convertinga byte'svalueto hexadecimalis also quite simple due to the swapf instruction built into the PIC MCU's processor. This instructionswapsthe two
5ectionTulelve S o l v i n g P r o g r a m m i n gP r o b l e m s
|*1l
ef-3
ASCIII
Codle: //
v-"
Nev Bits
iof
//
goto This agDlicatioD conv€rls (Byte) va1u6 into 8-Bit ASCII Binary characterE.
dfr
8 Bits
if
l
r?*
289
*'1\
nybbles (high four bits and low four bits) to facilitate converting thesefour bits to a hexadecimalvalue using a subroutine.The most obvious method to convert a byte to two hexadecimalASCII charactersis to use a tableasI do in "asmByte2Hex1:" tsill€
"aatnBtt€2Hex
1 -
Nurlbet
to
aex
ASCIII
fhia aDDlicalion converEE a Eingle g-BIt (Btrt€) Value ilrto Ttdo AgCIr Il6x cberactera uaing a table. trCtr Equival€nt
U bl
sl (g
tn
HexTable \4, ,
[]
E
== 1)r
Ilaralware Notea: PrC16F58{ running
//
at
Doae,
4 lOIz in
SimulaEor
uyke Prealko 04.08.29 LIST R=DEC INCLITDE np16f 584. inctr
{u P l-{ t
r Variablea CBI.oCK 0x20 Digil:2 Ternp E![tc ors
t Nu'trbe!
variabl€s
0
l
U t,
o0 1:}
t Uae "123" i Program
movlw
123
movlrf
Terq)
awa{rf call novDrf
Terq). w HexTabl€ + 0 Digil
t Get
lrovf call novwf
Tetq), w He:.Table Digit + 1
r Get
qoto
s
r Finiahedl,
lhe
lhe
!o
trigb
l,olr
Tesl
the
lRibble
lwbble
|{
P L.
CI H 'l-{
k (U
X
r-1
analllr atLllw btfac aatallw
:fil
Loop Forov€r
.l.{
t{
A potentially more efficient method of performing this convenion is to calculatethe ASCII hex character algorithmically,replacing HexTable in the progrlam above with the following subroutine:
t1,,
{r0,,
= E€xTabl€ [ (Nuriber >> 4) & o:
whif€(1
enfl
Getlle:.:
Codle:
\9"
Digitlol Digitlll
incf PCIATE, f novwf PCL _He:rTabl€: "0123{56789A!CDEF' dt
0x00E 5 STATUS, DC 7
''' -'
Btrte2E€x: nonwf alrapf anallw aa|-llw btfac aaLlLw
T€nE) Tedp, w 0x00F 6 STATUS, IrC 7
aaltlld
.0,
movDrf incf
INDr INDF,
novf atralLw aattllw btfsc
TerD, w 0x00F 5 STAmS, DC
H€xTable:
290
Return H6r. ASCII Char for I,srwbb1e in WREG ifuEt want lower { Bitss ia th€ Ee:< Dlgit > 9?
i Yea, Move value to chalE t DigiEa
frdl
This codeteststhe valuein WREG to seeif it is greater than or equal to 0x00A, and if it is, addsthe difference betweenthe ASCII character codesfor 9 and A. Oncethis is done,the ASCII charactercodefor 0 is added to convert the numeric value to an ASCII character.To test out the operation of this subroutine,create a new program called asmByte2Hex2 and replace HexTable with GetIIex, and then test it out. In terms of efficiency,I would generally use GetFIex over HexTable becauseit can be located anlrvhere in the PIC MCU's mernorywithout concernand is short enoughthat you couldconsiderplacingit in line rather than making it a subroutine.For examplg a generalcasebyte to hex conversioncould be written as and takes about the samenumber of instructions as calling the HexTable to convert a Nybble once.
LooD Eo!€ve!
H€x ASCII Char r Return I,slwbble r for clrf PCLATH r ltr WREG ( (_Ee:(!able if & 0x100) != 0) baf PCI.ATH, O enalif ( (_EexTable if & 0x200) l= 0) bsf, PcLArH. 1 entlif if, ( (_E€xTabIe & 0x{00) != 0) baf PCLATII, 2 eDalif, andftp 0x0F want 1ow€r { bits r ilust aaltlLw Iow _HexTebL€ i Calculate the cor!€c! r offa€t gTATgS, C blfac
i r t i i
novwf incf
1 , 2 3 P I C @l ' l C UE x p e r i m e n t s f o r
INDF INDI',
f
f
the Evil
i i i i t r
Convelt Value in WREG to lwo Hex clFlact€ra at location pointeil to bV ESR Do High Nybbl€ Eirats > 9? Nybble
i t i i ; t t i t r
Yea - r,uE ln trAn to range Convert Eo ASCII Characler Save ASCII Cha:.acter Point lo t'he N€xts DeBtinalion Byte Converts the lgNt'bbL€ Do High Nybble Firsl > 9? Nybbl€
nFr
r t r i , , , i
Yes - Put in nAn to ralge Convelt to ASCII chafacte! gave ASCII Character Poiat to lhe Next D€stination Byte Retun to Caller
nFn
Genius
The GetHex subroutineis a good exampleof working with a singlenybble(four bits) and usingthe digit carry (DC) flag insteadof the standardcarryflag. The lastprogramthat I am goingto presentfor this experimentis the conversionof a byte to a decimal value (asmBin2Decl.asm). To find the hundredsand tensdigits,I repeatedlytake awayvalues(divisionby repeatedsubtraction)and add the quotient to the ASCII charactercodefor 0 to producethe correct characten.After taking awayhundredsand tens,the remainderis the numberof decimalonesin the number,which is simplyaddedto the ASCII character codefor 0.
This isn't a terdble methodof convertinga byte to decimal,but it could be improvedby noting that the leastsignificantdigit is the sumof the leastsignificant nibble and 16 timesthe mostsignificantnibble.The asmBin2Dec3.asrnroutine takesadvantageof this property and goesone better:insteadof adding16 timesthe high nibble,it addssix timesthe high nibble to the low nibble,and it addsthe 10{imesvalueto the high nibble.The codeitself is almosttwice the length of asmBin2Dec1,but it executesin a constant38 instructions.
ExFeriment 109- Produce the Even ParitgValuesfor a Bgte
One of the dyingtechnologiesof computerintedacing is RS-232.This serialinterfacewasone of the first methodsof connectingcomputersand peripheralsand requireda numberof differentskillsto implementsuccessfully.In123Robotks Experiments for theEvil someof the issuesregardingcreatGenlas,I discussed ing the voltagesneededfor the data transferand how systemsare connectedtogether.In this experiment,I want to look at how the error correctioncodewascreated and seehow efficientlyit canbe done. The traditionalformat for an RS-232datapacketis shownin Figure12-3.It containstwo bits after the data:thestopbit is an indicatorthat the datapacket hasbeensent,and givesthe senderand receivertime
to processthe currentbyte and preparelbr the transmissionof the next one. The secondbit, the parity bit, is usedto detect whetherany one of the tlansmittedbits wasreceivedin error.This bit, whensummedwith the total of all the previousbits will resultin either an evenor odd value. Thereare five diflerent typesof parity:mark,space, even,odd,andzero,in which a 1, 0, evensum,odd sum, andno bits (respectively)are sent.In mostmodern communications, the no parity bit is mostoften used If a due to the reliability of moderncommunications. it is most parity bit is requiredfor error detection,then often evenbecauseit is calculatedasthe sumof all the bits that havebeenreceivedin a packetand shouldbe an evenvalue(i.e.,bit 0 of the sumshouldbe zero). the most obvious The followingprogramdemonstrates way of calculatingthe evenparity bit-the valueof eachbit of a byte is summedtogether. titLe vaLue
"asmParity fo!
This aDplication for even pariuy each bit. "c'
Equivalent
Tetnp = 123' Parity
1 -
Ev€n
Calculate
Pality
a Byte" calculat€s a bt'te by
the surmiflg
Coale: //
Set
lhe
Byle
= 0t < 8r i++) //
Reaal through
each
bir
t
Figure la-3
RS-232datapacket
5ection Tuelve
( (TetnP & 1) == 1) Parity=Parity+1, Temp = Temp >> r, | / sm}rift- 1 Bil // iof if
Data ,
S o l v i n g P r o g r a m m i n gP r o b l e m s
Down
291
Parity=Parity&1.
== 1)t
while(1
Ilarakf,a!€ NoteE: PIC16F584 rurlltrq
.[J
u q, r{
*a
.a )
ffi nl
b . r'€
{l}
at
a gingl€
//
ParlIy
ia
//
Done,
Loop
{ MHz in
Bit
A B
Eolever
glmulalor
Myke Plealho 0{.04.07 LIS! R=DEC INCLITDE "D15f 58{.inc"
Figure f a-q
i Variablea CBLOCK 0:.20 TemD, i ENDC PAGE olg novlw novwf movlw movwf clrw
IJooD: btfsc atlfll\o rrf fl€cf,az goto
a bit of experimentation comesin handy.Remember that a binary adderconsistsof an XOR gateand an AND gate(seeFigure12-4)in which the sum (S) bit is the XOR result of the inputs. So if we want to add two valuestogetherandget the single-bitsum,we simply requirean XOR gate.
0 123 T€[ut 8 i
TerE,, 1 T€sl!), i, f Loop
0
,
hilialize
i i
Use WREG a6 Palj.ty Coutrter
VallabL€s
i Lootr> Ilele for Each t LSB of, Value S€t?
Bit
f t R€p6aE for
andlw
1
r Only
goto
S
i
eacb
IJSB iE
Finigbeal,
bit
Parity
Haff adder
Bil
Iroop Forever
enfl
This methodworks acceptablywell,but is another casewherea bit of knowledgeor binary numbersand
In asmParity2.asm,this function of the half adderis exploited (along with shifting bits) to produce a parity bit in the samenumber of instructions,executingin one-sevenththe numberof instructionsand usingone lessfile register variable than the original. Despite improving how the parity calculation softwareworks,asa tool,it's pretty limited.Theparity bit will detectonly onebit in error in the packet.With two bits,the parity bit will indicatethe data is correct. Additionally,when an error is detected,the incorrect bit is not indicated,nor is there any correctioninformation included.Thesefunctions are critical features of modern error detection/coffectcodes(ECC) used in high-speedcommunicationsand peripheral interfacins.
?
,
Experiment ll0-5ort a List of l0 Eight-BitValues Usingthe Bubble-Sort Fllgorithm
# +-'
After the time and effort spent in Section4 describing different waysto implement a bubble sort in C, you may be hopingthat I won't havea lot to sayaboutcreatinga sort in assemblylanguage. You'll be happyto hear this is true:Theassembly-language bubblesort (shown as follows) is a quite simple and faithful translation of the C languagealgorithm
{,
tr H
!d!". a-6
laq
292
l , e 3 P I C @l l C U E x p e n i m e n t s f o r
the EviI
6enius
,'aanbsort
lit].e
t ThiB program Sort 10 values t
1 -
ua€s
"Cn Equivalent
r for r
(i = 0r SoltliBt
solt
!h€
10 8-Blt
Bubble
sort
gotso
valu€5" Algorlthm
INDF,
tlecf addwf
FSR. f INDF, f
FsR, incf outsaitlel,oop_skiD
i < 10r i++) = Reaflvaluei [i] // R€ad in lhe
Een Byte
, i t
f,
i ELrats = Eirat r - Filat)
Heldwa!€ Notea: PIC15F584 rururiag
t Finisheal,
I
t ats th€
4
uHz
ia
+ (Seconal tl,
Increlrents
i, rtr goltl,iat
Enal of
novf aaLllw aubwf btfss
ESR, rt STATUS, Z
golo tlecfEz goto
OutELtl€IJoop i, f InsialelJoop
t Don€ 9x?
goto
$
; fo!€ve!
r Return Gelvalue3 at
ffi ld
-
f,
i t
llfr
,
sortlJt8t [j + 1l Seco al = g€confl (secoaal - EiIEE)
H
'jn
VaLueg
, f o r ( l = 0 r i < 9 i i + + ) // Outaial€ Sort LooP , f or (j = 0, J < (9 - i ) t j++) i l/ IttBiale Sorl LooP t (SorEr,iBt [i] > SortLial if ti + 1l) t // l|ave to SrtraD valuea r { + 11, T€mD = Sorll,islli r gortli8t r [i + 1l = Sortl,ist [i] = l[edl!), SoltlJist t lil
; t
subwf
to
Coale 3
Outsial€loop_skip
the
VaLue
for
lDtlex Liat?
at
bh€ rJiats?
tbe
End of
LooD
- Done
the
"i"
€
( (_Gelvalue & 0x0100) != 0) baf PCIJAIIH, 0 edttif ( (_cetsvaIue & 0x0200) l= 0) if PCIATII, 1 baf, enflif ( (_cetvalue if & 0x0{00) != 0) PCIATII, 2 baf, entlif aalallw 10$ _GetvaLu€ r GeE Offsets in 255 i AaLlr€aa Block btfac STATUS, C Pcr,alrfl, 0 incf mon$f, PCI. the ilumD inlo r Pelform r the Ta51e Getvalue: 10, 100, {, 15, 75, 150, 47, 2, 25O, ilr 475
!8ike
Prealko
r 0{.0{.05 IIST R=DEC rNctnDE np15f 58rl.incn , valiabl€s CBLOCK 0x20 Sortl.iBt | 10
; IJist Sort€dI
of
valu€s
!o
be
ENDC PAGE , Mainline
orlt
of
Bubbl€
Sort
- I"bfk€
I t t
(*;
tf,
a \ r
s
0 enal
clrf novlw novwf loaalloop: novf ca].l movwf incf, incf movf sublw btfsa goto
i
by loaaling i Starl , SortsLial , Setup FSR f,or IDdir€ct t Aaltlreaaingl
gortT,ist
I'd like to note a couple of discussionpoints. If you code,you'llsee work throughthe assemblyJanguage that it is essentiallya straight translation from the C languageprototype with one difference.When I coded the application, I discoveredthat when subtracting the current array value from the next, I could use the value in the WREG (Sortlist[i + 1] - Sortlist[i]) to simplify swappingthe data between the two array elements.
ESR r Retsurn H€re UntiL Loaaledl r Valuea i, w qelvalu€ INDF FSR, f i, f i, rt 10 STATUS. Z Loaalloop
movlw 9 novwf i IDsiflel.ooD ! tlovlro Sortlisl
r t i i
"i' cets the valu€ for gave ia LLat Point to Nexts EIemenC rncrenent counte!
SorEr,iatli t !Io,
Do n€xE
t Wants to
aubwf
INDF,
blf,Bc
STATI'S,
looD
one Thlough
tso tsh€ start i Poiat t th€ Liat i Use FSR as Inal€x
FSR movwf out a ial€LooD : rNDF, w novf FSR, f incf w C
aLl
t i r r i r
Point to the Next El€[l€nt + 1l sortlJiststj sortlJists Ijl If cerry Re6€1, sortl.ist Ii I >
9x
of
lJiat
+ 1l'
= SoruJiststi + 11 = sortlJiat [i + 1l + 1l - Soltti8tlil - gortliaEli + 1l + 1l + SoltIJiEt = sorrlLBr Iil
- $REG - (Sorllist -
tv
w L'
F fn
ti
] Solll,iststi
\34
lil
H
Similarly,with Sortlist[i], the value in Sortlist[i + 1] couldbe substitutedinto it by simpleaddition: sorrl,tatsf1l,
t9 {
9-.r
ginulaEo!
if
i r
'-t
= SortliBt[il + WREC = sortlistlil + (sortr,Lstli Sort'I.isl tiI ) = Sortlistli + 1l
5ectionTuelve S o l v i n g P r o g n a m m i n gP r o b l e m s
+ 1l -
293
fr
s "*.4 1.4 rft
.3J
3.,; ai
Thisoptimizationallowsfor swappingthe contents of the two array elementsin four instructions.When I originallywrote the code,I used10instructionsto swapthe valuesin the elementsusingtranslatedC code. Yearsagoon the PICList,the questioncameup regardingthe bestway to sort a short array.My immediateresponsewasto comeup with a loopingbubblesort routine like the one above.Somebodvcameun with a simplemacrothatembodiedlh..orpu,. und swapcodetogetherand createda simplebubble-sort program,which ran througheverypossiblecompare and swap,asI havedone in "asmbSort2.asm,,, which usesthe "CompareAndSwitch"macro: conpare.Bnalswilch locat CASship novf, Firstvalue, sub\of btfsc
=f:
geconalvalu€, STATUS. C
rnaclo
Firstvalue,
Secondvalue
i Is g€condvalue Value?
w
> Eilst
w ; If Carry Secontl >=
Set. then Firsts
gotso CASSkip r WREG = Seconalvatue - Eitstvalu€ = ELrEtsva1ue aaldkrf Firstvalue, f t FirstvaLue + (WREC) = sulndf Secontlvalue, f i Seconalvalue - (WREG) Seconalvalue cASSkip: €ndm
The secondprogramruns somewhatfasterthan the originalandis goodasa demonstrationtool for the squaredorder of operationsof the algorithm.For an arrayof two elements,one compare/swap is required; for threeelementqthreecompares/swaps are required; for four elements,six compares/swaps are required; and for five elements,10compare/swaps are required. Unfortunately,the numberof instructionsrequiredby this methodsoonbecomesthe limiting factorin its adoptionin usingit. For sortinga maximumof threeor four elements,this couldbe a very efficientbubble-sort method,but its usefulness diminishesaslarAerarravs mustbe sorted.
,': {Ji
Experiment111-Encrgpt and Decrgptan FSCIIZString Using a Simple SubstitutionFlgorithm
.t; t*{ :"el
traamEdcrypt
titLe Decrtzpt
;-!
anal ASCII
i l
1 - Ulrke Stringn
-
Encr!'p!
alal
Thia aDDlicalion coaverta a String of Characters sloleal ia th€ Eile Reglsters anal then al€cr]Dtss lh€sr using a glannetrical (Ror13). convelEioa table
?,r!
rrcr' Equivalent
!
Codt€:
DataSt,ring
Data encryptionis a fascinatingtopic and a numberof programsare availablefor the PIC microcontroller that implement data encryption standard (DES) and other modernencryptionalgorithms.Simplesubstitution algorithmscanbe implementedsurprisinglyeasily in PIC MCU assemblylanguage,asI will showin this experiment. iii
.r*
& ,tt
The basicoperationof a substitutionencryption algodthmis that one characteris substitutedfor anotherfrom a tablein which the charactersubstitutrons are symmetricql When the substitutedcharacter is placedbackin the table,then the originalcharacter is returned.Thisoperationis demonstratedin the following application:
!34
for
(i
= 0,
i
< at!1ea(Datastllng) t i++) / I E^ctyT,E th€ String = Encrt pt (Darastring Datastring[i] til ),
for
(i
= 0r
i
(Datagrrins) r i++) // DecrlT,t th€ Slring = Eacrypt (Datastlins Ii1 ) t
< srrlen
Datastlinslil ( 1 == 1)t
!.hil€
//
Harahtra!€ Notes: PIC15E68{ ruDning
at
Done,
4 ltlz
in
IJoop Eoreve!
Simulatsor
r.lyk€ Pledko 04.0{.05 LIST
R=DEC
tui f!
r .'r 294
l , E 3 P I C @l l C l JE x p e r i m e n t s f o r
the Evil
6enius
INCUTDE "D15f68{.
enalif aaltllw btfBc incf monwf,
inc"
i Variables CBI,OCK 0x20 DataString:12 ENDC
TIITKEPREDKOtr,
.It
novhc movDrf Inj'tIJoo9: incf
of
EncryDtioa
0 -
Datastling
1
r getup FSR lo ; tlre Datastring
Poj.nt
tv
O
UPPERCASE ' EETIE}I charectser i ascrr PCLAIIH clrf , getsuP PCLIITE for r Ta51e R€aal ( (_Encrl,I)t' if & 0x0100) != 0) bsf PCLAAA, 0 eadif
f
PoLnt
,
lo
lh€
i
novl,w
Dat.agtring
t Now, EncttE i string
rnovwf FsR lldcfl.!)t Iroop : novf INDE,
w
the i sto!€ t At Enal of
i t t t t r t r r
call Or'Wf
Eucrtz9t INDF
incf
FSR,
movf
INDF,
btfBa goto
z STllrUs, Eacrtz9tlJooD
novllr
Dataslring
f w
novwf FsR Decrl.9tlJoop : movf MDF,
€€ts rnalex
Nenl
Inlo
charac!€r gEling?
l
i i t t t r r
w
r ReD€at , gtring?
novwf
IND!
incf,
FSR,
movf
INDS'
btfaa goto
SfaTUS, z D€crylrtlooD
goto
I
f
the
to Gel charact€! Encrypt llo the sylln€tlical Decrygt Put back lh€ EncrlTrtedl Character Poinl to the N€xt
\t
Encril'l
the
to Get chalacts€r Encryl)l llo th€ Encryptsi.otr Itt back lhe Encryplefl Charecter Point to th€ Nex! Charac!€r Regeal to End of Slring?
, Now, D6cri'pl , StrLlg
call
string
to
r Finiaheal,
Enal of
Loop
t Subroutides
bEf
( (_Ercr!,Dt & b6f PCIATH, eualif ( (_EacryDr if & bEf PCLATH, enall.f ( (_Encr!'Dl if & bgf PCIJATII,
0x0100) O
r setup i TabLe l= 0)
0x0200) 1
l= 0)
0x0{00) 2
I = 0)
PcIJAlrIl Reaal
for
qv
,-t
PCI,AIIH,
1
enalif if ( (_Encrl.pt & 0x0400) != 0) bsf PCIATH, 2 endlif adtllw adaLw btfsc incf movwf _thcfy9t: alt
(0 -
r 9--!
\A')
_Efct:zpt
i i
w
Zelo Baa€ the charactera
sTATuS. C PCITATE, f PC! trNoPQRsruwqxYzABcDEEGlrriIK!!,l"
g I tRct'!13
eaal
(character
Character else Character
rrl 5.{
This applicationfirst loadsan arraybuilt with 11 file registerswith the stringof uppercasecharactersto encryptanddecrypt.Thecode,which is representedas "C" Equivathe Datastringinitializationin the header lent Code,is the standardmethodfor initializingan ASCIIZ-stringvariablearray.Using the ASCIIZ format,the lengthof the stringcanbe ignored;it is simply readuntil a byte with the valuezero is encountered. This feature minimizes the number of file registers requiredto initialize,read,and write aray elements. Next,eachcharacteris passedto a subroutinethat finds the characteroffset to the characterrelative to A, and the character in the Encrypt table at this offset is returned. The characterretumed from the Encrypt table is in the ROT 13 format in which A is changedto \ B is changedto O, and so on.This is a very basicand popularsubstitutionalgorithmusedmostlyfor demonstrationpurposes. wasgivento a high schoolstudent This assignment who cameup with the following algorithmicversionof the Encryptsubroutine: if
PCLATH
f.r.
(( Encr,lT)ts& 0x0200) != 0)
if FSR,
Dalaslringl FSR, it hitstring INDF 0 STATug, Z IaitsIJoop
if
!o
FsR
novhr aubwf call NOVWf io!1w btfss goto
clrf
X
l'rt
Lt
PAGE r ltainline org
14
_Inilstring STAfrus. C PCLATB, f PCL
>= 'N') // cha:.ectser ld-Z, change to A-u = Charaqler A-U, Change to N-Z // Chalacler - rA')' = charact€r + (\!I'
This code either subtractsor addsthe difference betweenthe ASCII charactercodefor N and the ASCII charactercodefor A. You are probablyaware that the difference between the two is 13 (assuming
1 6
K Ld4
ffi
q
t&
{ d |d
a.4 e?'{ r.&
*3
&*
r-&' t-d
Fr. !n lr.{
SectionTurelve
S o l v i n g P n o g r a m imn g P r o b l e m s
295
that thereare 26lettersin the alphabetand the break is halfwaythroughthe alphabet).But by keyingin the differenceasan arithmeticstatementthat the compiler/assembler hasto processmakesit easierto see what'shappeningand minimizesthe chancefor keying the wrongvalueor changingit inadvertently. It isn't difficult to convertto PIC MCU assembler, but the codeis somewhatcumbersome. not to mention quite hard to follow.In the followingcode,I haveindicatedthe valuewithin WREG to make the oDeration of the functioneasierto follow: Erlcrypt: sublw btfsc goto
\ ltl' STATUS, C
, WREG = rM, - WREG r Skip if Carry Re6et , (WBEG> rM') r Carry Se!, WREG is
ROTl3TJess 'M'
subht
-
('N'
-
'a')
goto ROTl3Done ROTl3LeEa: 'M'
sublw
+ ('N'
r $ I R E G- \ M ' - ( ' N ' . rA,) _ (.r{, - I,IREG) r W R E G= W R E G - ( ' N , , -'A' ) t WREG <= \r!1',
-
\A')
ROT13Done:
t W R E G= . rA,) _ t W R E G= i -'A'' r WREG =
Aalal
'M' + ('N' (.M, - WREG) W R E G+ ( r N '
Nuniber
Bublw
Nuniber
r r t r t
WREG = Number WREG WREG = Iilunber - WREG) (I{Enb€r $IREG = WREG
So by usingthe sublwinstructiona secondtime,the valuefi'om which the WREG wasoriginallysubtracted canbe removed.and the valuein WREG canbe changedfrom a negaliveto a posilive. Insteadofjust leavingthe codeasis,I decidedto spenda few minutesand seeif I couldsimplifythe conversionprocessby eliminatingthe two pathsand looking for a valueto add to the subtractionresultin WREG The subroutineI cameup with follows: Encrlrpt:
the r Elrcrl.l't r UPPERCASE ASCII
sublw
'N'
btfac addlw
STATUS. C -2 * (.N, -
sublw
'a'
296
r Carry Reset t > \M' .a')
subfw addtw
'N, -2 *
sublw
'A,
(rN'
-
\A')
if
$IREG
, carry Se!, , Doi\'n rN' -
lrove ro .A' Values
r Retsurn
Eneoaledl
the
r r r t t t , ' , t t
WREG = r!I, - WREG W R E G= - 2 , N . + 2 , A , + ( . N , - W R E q ) W R E G= - ' N ' + 2 ' A ' $IREG $IREG = rA' - (-'N' + 2 'A' - WREG) WREG= \A' + lN' + WREG 2'A' !\IREG = WREG + ('N' - '4' )
For the casein whichWREG contains'N'to'2,' the codeis asfollows: sublw sublw
\N, \A'
ROT13 (VIREG)t
Interesting,if the sublwis executedtwice,you end up with the originalvalue: Bublw
I replacedthe originalEncrypt subroutinein the asmEncryptl.c routine,with the new versionabove and calledthe applicationasmEncrypt2.c.Thiscode, althoughobviouslyvery efficient,is hard to follow and understand.Thebestway to examinewhat is happening is to considereachcasein which WREG contains a valuefrom A to'M' or a valuefrom'N' to'2.' For a valuebetweenA and'M,' the codeexecutesas follows:
WREG = r!r' - WREG , t IIREG = \At - ( 'N' r ViIREG) i IIREG = WREG + 'A' t WREG = !"REG t 'A' )
{'N'
-
If you comparethe two methodsof computingthe ROT13value,you'll seethat the resultsare the same.I don't think I would get a lot of argumentthat the second versionis more efficientat computingthe ROT13 value,althoughit is not obvioushow I derivedit. I would like to saythat I havea simpleprocessfor coming up with this type of optimization,but I mustconfessthat eachcaseis different.To comeup with the optimizationfor the ROT13 Encrypt function,I stafiedwith the desiredend points (the final valueof WREG whenthe contentsof WREG are lessthan or equalto 'M' and whenthey are greaterthan 'M'). Next,I went to my teststate(the sublw'N' instruction) andworked at finding an addlwinstructionthat would negatethe'N' throughA operation. Pleasedo not assumethat optimizationsare beyond your graspor that they cometo me becauseI have more experienceprogrammingand working with the PIC MCU than you do.In explainingthe operationof the instructionsof optimizedcode,I havepedantically listedthe registercontents,listingtheir valueasI algebraicallysimplily them.If you follow this methodology, you will find that you too will comeup with very efficient codethat meetsvour requirements.
l , a 3 P I C o l l C U E x p e n i m e n t sf o r
the EviI
Genius
tql
112-Eeneratea FibonacciNumberSequence X Experiment rd
o
Eight hundredyearsago,the Italian konardo Pisano Fibonaccilooked at the problemof how rabbitsreproducedand how the growthof their populationcould be plotted.Postulatingthat rabbitscouldproducea litter oncea month,after they weretwo monthsold, Fibonacci cameup with a sequenceof numbers that is the baneof computersciencestudentsmore than three-quartersof a millenniumlater. Startingwith onepair of new born rabbits,the population of rabbitsin the first year canbe listedas: L,
This sequenceis normallydescribedasthe resultof a recursivefitnction As I mentioned previously,recursive functions perform part of a specified operation and then call themselves to completethe operation.I discouragethe useof recursivefunctions in PIC MCU programming(of all types,not just assemblyor C) becauseof the lack of an arbitrary-lengthprogram counterstack. Without the possibilityof recursion,the problem becomesquite simple,with eachvaluein the sequence beingdefinedby the statement: = Eibti
"asmribonacci titte 24 TermE" Sequence for
the
cleat€
15 bil wolhLng with i D€noastrate lhe Nunb€r Arraya to calculate i for 2{ E€rms. Fibonacci E€riea ; t
"C"
tinl , ,
EquivaLenl
Coale:
Fibt241;
Fiblol
= Fibtll
//
Sequenc€
49 Byle-Fibonacci
//
].t Eirat
Two Valuea
-
1l
+ Fibti
-
2I
that can be checkedby applyingit to the sequenceof the previousnumbers, The requirement for this application is to produce the Fibonacci rabbit population growth valuesfor two years.Looking at the examplesequenceabove,you canseethat the valueof the thirteenthmonth will be approaching255,which meansthat in order to store the populationvalues,you will haveto use16-bitvariables.The general form of the addition is: . .
Add high bytes Add low bytes
.
If low-byte sumis greaterthan 255 (carry bit set),incrementthe high-bytesum
(1 == alt
//
i llaralware Not€a: PIC15E584 rutraing ;
Finisbeal'
at
{ uEz
$
ts
I F
r
x 0,
IJoop For€ver
in
3 o
|-...
, for (L = 2i i < 24t i++) - 21t - 1l + Eistt = Fibli Fiblil r / / cet Each value , r whl.l€
f-r.
;fl
1
are
rt
H l\)
Elbanacci
1 3 , 2 1 - ,3 4 , 5 5 , 4 9 , L 4 4
t-,2,3,5,8,
Fibtil
In my solution,I havesetup a 24-element,16-bit array,in which eachmonth's element value is stored and usedto produce the value for later elements.The solution to the problem usesthe FSR index pointer register to keep track of which element (and which To byte of the element) is currently being accessed. changethe FSR,I useincf and decf (incrementand decrementinstructions,respectively),and I add explicit valuesto the FSR.
SimulaEor
o o
i , !,l].ke P!€ilko ,04.08.31
}l. LIST R=DEC INCL(rDE'915f
584. inc'
, variableE cBrJocK 0x20 Erbr2*24 i,
Sloring t Array values i Fibonacci
TerD:2 ENDC PAGE org
0
c l r f
E l b + ( 0 r 2 ) + 1
clrf mov].w movwf mo'\tttf,
Fib+ (1 *2)+1 1 Fib + (0 * 2) Fib + (1 * 2)
t Inltlalize t Two A.rray
5ectionTurelve S o l v i n g P r o g n a nmi n g P r o b l e m s
1El El€dlenta
z s 5
tt (D ry V2
o
to .a
o o o
297
ql f.t
(u
.a ts r..l
x F
f-1 r{-{
novlw
2A - 2
movlrf
i
novlw
Fib
novrdf IrooD ! alecf mov! movwf tl6cf movf movwf alecf movf
lilumber of Eldlents to
+ (2 * 2)
t Point t Start
r*{
"}J
ASR. MDE, T€a\D ESR, INDF, E€[rI, FSR, INDF,
- 1l , Point ro Fibti i anal Save in Tettp
f w + L f
I,J
.r{
fr"{ & I
aatalwf movf movwf Lncf &ovf novwf incf
FSR, Tetnp, MDF FSR, TqE IIIDF FSR,
alecf,sz goto
i, f lJoop I
= 0x03DB (ln ReverseByteOrder) Figure la-5
f w
r Aatdl Fibli t Telqt
-
2l
Fibonaccivalue
to
T€aI) + 1, f FsR, f INDF, rt Tetnp, f sTtTUs, c Tetry + 1, f
atldlrf tlecf novf aalabrf btsfEc incf
goto
6n
to the of tbe Arlay
FSR
In Figure 12-5,I havecircledthe sixteenthelement of the Fib array.The element'sfirst addressin the zerobasedFib arrayis found usingthe formula: i Store r Fibtil
!s{
AiLI
TerE) in
Address = Array (Elenent - 1)l
f
SEa-rL Address
r
12 x
w f + 1,
w
f ,
Repeat
i
Finiaheal,
(24 -
2)x
trooD
€ndl
When you run this application,one of the biggest problemsyou will encounteris trying to determine whetheror not the answersare correct.Lookins at the File Registerwindowin MPLAB-IDE (seeFigure l25), you may havea difficult time pickingout the highervaluesand translatingthem into their decimal eouivalent.
So,to find the first byte of the sixteenthelement,the first addressis 0x03E(assumingFib startsat file register address0x020).This value is savedin Little Endian format (low byte at low address,high byte at high address),and the valueis 0x03DB-even thoughit lookslike 0x0DB03.Convertingto decimal,this value is 987(whichwasfound by evaluatingthe expression[3 x 256] + [13x 16] + 11),exactlywhat is expected. I'm goingthroughthis calculationbecause, like C pointer values,MPLAB IDE doesnot showthe contentsof an array (especiallywith elernentsthat are 16 bits and greater),and to seewhat they are,you will haveto employa bit of ingenuity.For the mostpart,I recommendyou avoiddata structureswith operating valuesthat requirethis amountof work to understand, but in somecasescalculatingan addressand convertins the valuemanuallvcannotbe avoided.
rr] r"{
Experiment 113-Findthe LargestEommonFactor of Tr.uoEieht-BitNumbers
F-l
c) g
To round out the section,Iwant to leaveyou with an application that can be expressedreasonablycrisply in the C language.However, translating the function to assemblycanhavea numberof uniquechallengesthat will needto be addressed. Finding the largestcommon factor of two eight-bit numbers is very difficult when translatingbetweenthe two programminglanguages directly.Substitutingdirect translationsof the C assembly languagestatementswould havepotentiallymade
".1
t"{
q, g{
X td 298
l , e 3 P I C @f l C l JE x p e r i m e n t s f o n t h e E v i I
Genius
the application more difficult to write and executeefficiently. The task of finding the largest common factor of two numbersis not particularlydifficult,althoughit requires a number of steps.The ftst is to find all the factors of each of the numbers.This is done by repeatedly dividing eachvaluewith incrementingdivisors until a divisorthat producesa remainderof zero is found. When the remainder of zero is found, the quotient of the value and the divisor (which is a factor of the value)must be savedasthe new valueand the processrepeatedto find other factors.In highJevel languageprogramming,this is quite easyto do,but in programming,codingthe division assembly-language routine requiresextrawork. However,this extrawork canmake it is possibleto perform the routine only once,simplifythe program,make it shorter,and make it executefaster. Becauseof the needfor divisionroutinesand storageof the differentfactorsof eachvalue,I usedtwo uniquevariablearraysthat are indexedusingcounters. Using a high-levellanguage, this is easyto accomplish, but in the mid-rangePIC MCU, it is more difficult becauseonly one indexregisteris availableand becausethe addressfor eachvalueneedsto be recalculated.Tosimplilf workingwith the index registerwith multiple arrayqsomeplanningis required-planning to make surethat the index you are both readhg from andwriting to is the lastindex accessed so multiple recalculationsare not required.
t
i = 2 r i - L i ((1 != value) while && (valu€ // Final the Factors if
llaralware Noles: PIC15F58{ running et { MEz in Resel is tied tlirectly !o vcc PulLup/ Progra.lring Haralware
int int lnt int
//
,
5ectionTurelve
r+
== 0
}J
s tJ
Proce€s of
trin
I Save?
3::l F"r.
Faclor
enal GetFactota
nain( )
(
int
i,
Jt
rt
= 195t = 22{t
Nunber1 Nurbe!2
v
(llulrbell, FacEorlliat) // Get FactorB GetFactors(lilurber2, raclor2Lists) cetl'actols
t
ftl
i
r
= 1t IJargeslFactor lJargeEt Factor // CaLculat€ (i - 1, (i < 15) && (0 != Faclorll,ist for i++) for (j = 1r (j < 15) && (0 != Factsorllist tiI ); j ++) (Factsorll"ist til == Facto!2]Ji8ttjl if ) // Ha''e a colEron Factsor | * = LargestFactor LalgeatFactor Factorllist IiI t = Faclo!2l.isl racto!1liEt Ij I =0t [il // fi ,
lbe
simulatsor via
N\rnib6r1, lirufiber2 t Eactorlliat [15] t Eactor2r,l.at I16l t large6!!actort
o
H
lthile
Iil!'ke Pr€flko 0{.09.01
Faclo!
// fi' l i++, // !,ook at Nexl vaLue // elihw ] (1 l= value) if to // RemaiDing Prille = value; Factorr,ial [jl ia Final // Re$ainate!
cdnron
Filst for two 8-bil s€l the factors nuribers adtl uae th€[l to findl the lalge5t factor. Thia is a atirect usage of cdrron rncn Equivalent' Coale' of the aEs€[lbly lansnras€ v€rsioD
Restalt
o
Fr, 5
!= i))
(0 == (vaLue % i)) o! value/i // rf Renainate! tE is a Eactor | // value=va1u€/i; // Eake Awey Factor = it FactorlislIj++l to the IJists // Add Factor //
FI X r-t
t
in the assemblyJanguagecode that cannot be representedin the C languageversionof the application.
the largeat ![t,I!be!s',
) a lillrniber
aactorliat [0] = 1t for (i = 1r i < 16r i++) tshe Faclorl,iat I / I'litlalLze = 0t FactorlJiats lil
The assernblylanguageresult for this experiment is "asmlcFactor.asm"and its operationis bestillustrated using"clCFactor.c".Obviously,many subtletiesexist
#lncluale <9ic.h> - Get cr,cBactor /* Factor of 2 8 Bit
(irlt Faclor',ist[] va1ue, int of / I FLatl AlrJ lhe Factora
cetFactora |
,
//
E^d
(1 == 1), // Finished,
til
);
t'rJ
Hr
H {
c
IrooD Eorev€!
cr,cFactor
The efficienciesof the assembly-languageversion over the C versionbecamevery apparentwhen some measurementswere taken of the two applications.The versionexecutedin one quarterof assemblyJanguage the numberof cyclesof the C version(4,800to 1.5,275 accordingto the MPLAB IDE Stopwatch) and also took up one quarterof the amountof spacetaken by the C languageversion(92 instructionsto 367instructions).The improvementin the numberof file registers
S o l v i n g P r o g n a m m i n gP n o b l e m s
T J
299
x
s
3 ff o
Ft
(f)
usedwasnot asdramatic(the assemblyJanguage versionrequires72 file registersversusthe 88 requiredfor the C languageversion).From theseparameters, you might arguethat the assembly-language versionis four timesbetter than the C languageversionand is clearly the "best" of the two. The assembly-language versionwould be the bestif speedand sizewere the criticalrequirementsfor the application.If developmentcostwasan important requirement,the C languageversionwould win, hands down.Rememberthat the designof the algorithm, which I coded in the C languagebefore attempting to write it out in assembler, hasto be donein eithercase, and if a highJevellanguageis used,the codecansubstitutefor documentation. In this case,you are not developingcodethat implementsthe samefunction twice.And, in the caseof makingchangesto the code, if the sourcecodeitself is usedasdocumentation,the documentationfor the applicationis changedautomatically.Finally,the C languageversioncanbe transferred to otherprocessors with a minimum of conversioneffort.If the applicationwascodedin assemblylanguage, it would haveto be rewrittenin the appropriateassembler. This lastpoint is known asthe portabiw of the code.By definition assemblylanguagehasvery poor portability acrossdifferentplatforms.
.
Find the eight-bitmean and median of a list of 10 numbers.
.
Producean eight-bitrandom number usingan LFSR and an eight-bitseed.
.
Use structuresto add two real numbers together.
.
Sort a list of numbersusinga bit-map.
.
Reversethe charactersin a string. Find the Y:0 crossingpoint for an equationin the format Y = Mx3 + B. Find the day of the week for a given date.
. . . .
Compressan ASCII string (i.e.,replacerepeating valueswith a singlecharacter). Implement a simpletranspositioncipher.
Along with keepinga list of possiblequestions,a quick Googlesearchfor "ProgrammingProblems"is a usefulway to find additionalquestionsto work tbrough. In July of 2004,this searchyielded over six million hits.The following selection camefrom the top of the list and offers many useful and appropriate questlons: ACM InternationalCollegiateProgramming Contest/EuropeanDivision www.acm.inf.ethz.ch/ProblemSetArchive.html o
For Eonsideration tbt
iJ . t'i
*..i ,l:
li {.ii
':*
.r* lt-: ,f1
tt f)
Teacherqmore than anybodyelse,understandthe importanceof creatingdifferentassignmentand exam problems.If a setof problems(suchasthe 10in this section)wereusedfor morethanoneyearin programming course,chancesare goodthat solutionswould becomeavailableover the Internet in time for start of the next course.Thisis unfortunatebecausethe purposeof thesequestionsis to help the studentunderstandproblemrequirements,developan algorithmfor the solution,andfinally presentthe resultaspart of the project.Themarksare really secondary. The problem:It's difficult to comeup with new questions. I find it usefulto keep a runninglog of questionsthat I think of during the year.I write down all sortsof thingsthat I comeup in my day-to-daywork. Someof the problemsin my currentlist that could havebeenconsideredfor this sectionincludethe following: .
For a set of X,Y points,find the equationfor the trend line.
.
Multiply two numberstogetherusingBoothe's alsorithm.
:"r,,
300
Varioussampleproblems American ComputerScienceLeague www.acsl.org/samples.htm High schoollevel programmingproblems Department of Mathematicsand Computer Sciences, WesternCarolina University problems.pdf www.cs.wcu.edu/cscontest/2@/zou ProgrammingProblems,15th Annual Computer ScienceProgamming Contest Problem SetArchive http://acm.uva.es/problemset/ Severalhundredproblems,advertisedasbeing typical to exan/project problems Universily of California.1999Programming Contest www.cs.berkeley.edu/-'hi lfingr/programmi ngcontest/f99-contest.pdf Somebasicprogrammingproblems
l , e 3 P I C @l l C U E x p e r i m e n t s f o r
the EviI
6enius
Sect ion Thirteen
TipZaps@Flobot (rated tols Ieast 10V)
at
47 /.rF electrolytic caPacr.to!s 0.1 pF capacitor (aoy type) 0.01 pF capacitor Radio Shack Zipzaps remote control ca!
DUM
1 ZipZaps Pe!fo!mance Booster Uplrade Kit
Breadboa!d
1 Plcr6F68 4
Solde!ing
.I
ilon
solde r
38 KHz IR TV lenote control !ece j.ve!s
RoLarY hand. tool (Dremel tool) with carbide disk cutsl a^+,r
^
r,r
MAx?55
I
I I
Tvro-J.ine, 16column LCD
1 1N5817 Schottky diode
high-speed 9/64-inch bit dlill
2 LEDs
Needle-nose
5 IR LEDS
20- to Black
pliers
24-gauge
rrile
Light-dependent resi.stors
wire
10k resi,stors
Red wire Wile-wlap Permaneot Ili!e
rrile
1k j.esistols
malkel
4.7k lesistors 470f,) lesistols
clippels
Breadboard
100O lesistols
Wiling
10k breadboa!dmountable potent iometer
kit
Scisso!s Xrazy Glue Five-minute
100 pF electrolytic capaci-
epoxy
Over the yearg I have gotten at least two dozen emails from people who want to come up 'ri/iththeir own copiesof establishedproducts becausewhat's already out there is so expensiveand they feel they could produceproducts at a fraction of the establishedproduct's
14-pin, machined pin DtP socket Tvro-piD, tightangrle stlaightthlough connecto! rightFour-pin, angle straightth!ougtr coanecto! Tero-pin, straightsocket thlough Four-pj.n, straight-throu9h socket Prototyping
PCB
Breadboardmountable SPDT switch (E-Slritch EGl903 Recormeoded) Breadboardnountable mcrnentaly On push button sfin heat-sh!ink tubing Thlee-cell AA battety pack AA al,kaline batte!ies 6-32, nylon
2-inch bolts
5-32 oylon
long nuts
price. My only experienceswith retail products are with the Tab Electronics Build Your Own Robot Kit and the Tab Electronics Sumo-Bot Kit, and they have beeneye-openingexperiences. In comingup with theseproductqwe agonizedover featuresand partsto
301
try and meetthe requiled pricepoint. I very quickly learnedthat the productcostshouldideallybe onesixth,and no more than one-fifthof the retail price. The costdifferentialis due to shipping,warehousing, packaging,advertising, warranty,nonrecurring expenses costs,and profits for both the manulacturer and retailer.Using this rule of thumb,I am amazed that Radio Shackcan sellthe ZipZapsorremote-control carsfor $20.00. The ZipZapsremote-controlcarsare a lot of fun to play with. If you haven'thad the chanceto at leasttry one out in the store,you shoulddo so immediately.Figure 13-l showsthe completepackage,a car and remote-controlunit that doublesasa charger.The car hasa 1l.2V NiMH batterythat canbe chargedin about a minuteand allowsthe car to run for threeor four minutesat full speed.The car is capableof runningforward and backwardand canchangedirection;some earlierremote-controlcarscould only movelbrward and backwards, and turn in only one directionwhile in reverse.Radio Shackoffersa wide rangeof different bodiesfor the kits,alongwith variousaccessories, includingperformanceupgradesAs you play with the ZipZaps,you shouldbe impressedwith its robustness. It handlescrashinginto objectsvery well and evensurvivesthe mostextremeactivities(performingjumps, runningotTtables,and so on) without complaint.It's a pretty amazingpackagewhenyou considerthat they cost$3 to $4 to manufacture.
Fiqure l3-l The Radio ShackZipZaps@car with remotecontrol and charger
302
I am actuallysurprisedto discoverthat nobodyhas exploredthe idea of wing the ZipZaps asthe basisfor a mobilerobot chassis, whenusingother larger remote-controlcar chassisasthe basisfor robots, whichis very common.Looking at the ZipZaps,I can comeup with a few concems,namely: .
1.2-voltoperation
.
Limited operatingtime
. .
Smallsize Minimal payloadcapability
.
Surprisinglysophisticatedmotor and steering driver circuitry (and complexcircuitry overall) Ternarysteering(three states:left, right, or straight)
.
Takingolf the body,the Zipzaps is very compactly designed.Youcanpop off the circuit board'splastic coverand get a better idea of the electronicsthat act as the radio receiverandthe motor/steeringdrivers.You may haveneverseen,and haveprobablyneverworked with, the surface-mount componentsusedin the ZipZaps' electronicboard (seeFigure 13-2),which may minimizeyour confidencein modifyingthe circuitry.All theseconcernsare legitimate,and usingthe ZipZaps asthe basisfor a PIC MCU controlledmobile robot may seemunlikely,but asI will showin the experimentsthat follow,the ZipZaps is designedusing traditionalmethodologies. You can hack one into a robot over the courseof a weekendfor suryrisingly low cost. An importantaspectof hackingthe ZipZaps into a robot hasbeenthe work that hasbeenperformedin the previouschaptersand the skills and knowledge that work hasdeveloped.As I work throughthis sec-
'f3-? Figure TheZipZaps electronicsseemsmall and difficult to work with, but can be usedas a basis for a surprisinglysophisticatedrobot.
l , a 3 P I C o l ' l C UE x o e r i m e n t s f o r
the Evi I
Genius
tion, I will be addingrobot featuresto the ZipZaps chassisthat havebeenpresentedand prototypedearlier in the book;in fact much of the incrementalcode that is addedwith new featureswascut and pasted With a simdirectly from thesepreviousexperiments. ple basestructurefor the software,usingthe establishedcodebaseI wasableto createa very set of robot functionsfor the ZrpZapsrn sophisticated just a few days. I really had a lot of fun working throughthe experimentsin this chapterand I think you will too.But beforeyou start cuttingrp a Zrpzaps for your own robot, I suggestthat you spendsometime reading
throughthis sectionand rereading(and redoing)the and presentedthe variousexperimentsthat discussed control,software,and interfacefeaturesrequiredfor the robot.You may not be ableto find all the partsI used(althoughthey are pretty generic)or, due to you may find that they work difassemblydifferences, ferentlyor haveto be tuned in a differentway.By readingthroughthe sectionfirst and makingsureyou understandhow everythingis supposedto work, you will minimizethe amountof work neededto complete iirst the robot and maximizethe chancesfor success on timeat everystep.Havinga differentperspeclive the robot,you will likely comeup with somethingeven better than what'spresentedhere!
- Char acterizing the ZipZaps Experiment 1I t-.1 Tool
Box
Radio Shack ZipZaps lemote-control ca!
DMM
ZipZaps Booster
Soldering
Pe!formance Upgrade Kit
Needle-nose pliers
20- to
Before we canstart designingrobot hardwarefor a Zrpzaps remote-controlcar,it's important to underof the motor driversand the standthe characteristics informationthat we want to steeringactuators.The collectincludeswhich circuitsare usedto ddve the motorsandthe steering,what voltageis appliedto them,and how muchcurrentthey consumeduring operation.Todo this,you will haveto probe the ZipZapsvery carefully,asyou will be desolderingand resolderingsomewires.This is somewhatfine work, and you may want to take my resultson faith. Although you will be doingsimilarwork in the next now is a goodtime to get coupleof experiments, startedand get somepractice. I want you to know Justasa note of reassurance, that duringthis step(and the following steps),I broke a numberof wiresfrom the car chassisto the PCB.I wasableto reattachthem,andthe ZipZapsran fine afterward. The first order of businesswasto solderon 2- to 3inch lengthsof wire onto the red wire and black wire connectionsof the PCB.It is difficult to showin a photographwhat wasdone becauseI attachedthe wire to the backsideof the PCB (assumingthat the sidethat hasthe wires,shownin Figure13-3,is calledthe front).
iron
So lde r 24-gauge wire
Thesewireswill be requiredfor the next experiment. While holdingthe driving wheelsof the ZrpZapsoff the table (no load condition)and with the wheels stalledagainsta tabletop (worstcasewith the motor essentiallyshort circuited),I measuredthe voltage (whichis the batteryoutput) acrossthe two wiresas givenin Thble13-1.The minimal voltagedrop seen from nothingrunningto runningand stalledis an indicationthat the motor driversare well designedfor the motor and that the batteryhassomeexcesscapacity. Next. I wantedto look at the motor driversthemselves. With a bit of searchingwith a DMM, I wasable to infer that the motor driver circuit looks something like Figure13-4.Thisis an innovativemotor driver to us, designwith two control linesand is advantageous asI will showin the next coupleof experiments.Totest the motor driver,I first measuredthe voltageacross the motor (at the yellow and blue wires)for the conditionslistedin Table13-2.I then measuredthe current passingthroughthe motor for the sameconditionsby desolderingone of the motor wiresfuomthe PCB. WhenI wasfinished.I solderedthe Inoloru ire backon. The motor ddver shouldbe fairly easyto interface to a PIC MCU. The only problemyou shouldbe aware
5ection Thirteen Z i p Z a p s o R o b o t
303
Table 13-2 Motor Parameters Valtage FEross Mator
Cuffent
Condition No Load.Motor Running
V 1.20
25nA
Motor Stallcd
0.65V
l{10+mA
Throush Motor
Table 13-3 steering Drivef5olenoid Parameters
Figure l3-3 side"
Close-upviewof ZipZaps PCB's "front
of is the needto maintaina constantcurrentfrom the PIC MCU to the transistor's base.This will requirethe changingthe driver transistor-base currentlimit resistorto a valuethat will providethe sameamount of basecurrentaswasavailableto the transistors originally. Again, the motol driver seemsto be well designed with dre ability to handlethe currentproducedby a stalledmotorcondition. After seeingtheseresults,I decidedI wantedto usethe motor driver circuit built onto the ZipzapsPCB. Next.I wantedto characterize the stceringactuator electronics. After a few minutesol probingthe PCB,I cameup with thc circuitsltownin Figure13--5. EachoI the two solenoidcoilsof the steedngmechanismare drivenby the singlebipolarNPN transistors with the
Condition
Voltage Rcross solenoid
Current Through Solenoid
No turn
0V
omA
Turning/Solenoid Active
1.20V
60 mA
parameterslistedin Thble13-3.Like the motor driver, the steeringgearshouldeasilydrive a PIC MCU I/O pin.The currentJimitingresistanceshouldbe changed againto makesurethe sameamountof currentpasses throughthe baseof the steeringdriver transiston. While doingthis characterization, I ran into two problems.First,the PCB is smalland usessurfacemount technology(SMT) components, which are harderto rework than the pin-through-holecomponentsthat you are usedto. Patience,planning,and a small-tipsolderingiron are all that is required.Second, it wasdifficult workingwith the steeringgearsolenoid wires,asthey are extremelythin magneticwires and will pull themselves from the PCB whenyou are solderingadjacentcomponents.They can be resoldered easily,but you will haveto noticewhen they are missing,andyou will find that they canbe difficult to manipulate.
Table 13-1 BattergVoltageat DifferentDrivingMotor states trondition
Voltage
Motors.SleeringOff
I . 3 6V
MolorsRunning. No Load
1 . 3v0
StallcdMotors
1 . 2V 6
So l o noi d Coil
st\48T3906
Control (s2A) from Radio
st\,4 8T3904 (s1A)
SMBT39O6 (S2A)
Control from Radio Sl\ilBT3904 (s1A)
Control from Radio
Figufe l3-q
Mobr driver
304
l , P 3 P I C @l l C U E x p e r i m e n t s f o r
Figurel3-5
SMBT39O4
(s1A)
Steering driver
the Evil
Genius
Experiment ll5-Plf
ryl
MCUPor-uer 5upplg
h,
,TT Radio Shack Zipzaps !emote-cont!oI car
**, a-{ -*) fTr
P I C 1 6 A 6 84 MAx756 1N581? Schottky
diode
I,EDS
t! i r
10of,) resistor 100 pF electrolyt ic (lated at capacito!s Ieast l0v)
DMM Needle-oose pliers
0.1 pF capacj.tor tYpe)
Breadboa!d Wiring
kit
The f st thing I had to do in the processof gettingthe ZipZapsrcbottogether was come up with a schemeto power the PIC16F684that would control the robot. This actually tumed out to be a fairly painlessprocess, althougha coupleof operationalissuesregardingthe selectedchip andits usewith the PIC16F684had to be investigated.To summarizethe experiment'sresults, the addition of a PIC6F684power supply went very smoothly,and I learned a bit more about the PIC MCU andhad somethingsto think aboutin later robot projects like this one. If I were to look at the Zipzaps Robot from a perspectivethat otherpeoplecouldeasilyunderstand,I would note that it is poweredby a single1.2-volt rechargeable battery.If you look at the PIC16F684(or, indeed,any PIC MCU) datasheet, you will discover that the minimum voltage on which they run is 2.0 volts.For the Zipzaps robot PIC MCU to run at that speed,either I neededto add an additionalbattery or a step-uppower supply.The suggestionof addinga stepup power supplymay seemlike overkill,but adding anotherbattery had nothinggoingfor it; not only did it require spacethat was unavailablein the chassis,but the battery usedin the Zipzaps is heary (which will decreasethe performanceof the robot),and I would have to come up with a specialchargingc cuit for the two additional batteries. To go with the step-uppower supply,I had a number of requirementsthat it had to meet beforeI was comfortable using it. The requirements were: .
Noiseimmunity-I didn't want motor/steering electricalnoiseto affect the operationof the PICMCU.
*.-"&
(anY
I ,
0.0L pF capacitor
.
.
.
Smallsize-The control chip could be no larger than an eight-pinDIP, and the number of support componentshad to be very minimal. Reasonablerun time-The robot would run for a reasonableamount of time before requiring recharging. Able to survivePICkit programmingbackdriving. Backdrivingis the term usedto describe the forcing of an overvoltagecondition on a chip's output. Backdrivingtypically becomes very wastefulin terms of power and can damagesomecircuits.
ffi LI {
I
w
'L; g
Using a switchmodestep-uppower supplyeliminatesmany of theseconcerns.The capacitor filters and inductor energy storagevery effectively filters out electrical noisebetweenthe motor and the circuitrypoweredby the step-uppowersupply.There are a plethora of differentstep-uppower suppliesto choosefrom, which madethe task of choosinga small,efficient deviceeasier,althoughit still took quite a bit of time for me to settle on the Maxim MAX756. This chip is designedfor poweringelectronicsusinga single1.5V or 1.2V battery which is exactlythe situationwe have here. To validatethe operationof the MAX756 and make sure it would be appropriate for the Zipzaps robot, I built the circuit shovmin Figure13-6.Thisis a fairly standardapplicationof the MAX756, usingvaluesand componentsrecommendedby the manufacturer. The first test wasto seeiI the ZipZaps baltery could run this chip and haveit power a reasonablesizeload.The circuitin Figure13-6providesa simpleLED (requiring
5ection Thirteen Z i p Z a p s o Ro b o t
305
Elj
ht
*?"€
:x ldi-t
about 10mA) and the cFlash.capplication,which flashesan LED betweenRA4 and RA5. The application ran the first time, but did not run after that.Using my DMM,I discoveredthat the voltageoutput of the MAX756, with all its heavycapacitance,took a very long time to go below500mV-just enoughto put the PIC microcontrollerinto an invalid state.To fix this problem,I enabledthe brownoutreset circuitry in the cFlash.cprogram's configuration fuses andrenamedthe applicationZipFlash.c.Asa side note,all the programsin this sectionstartwith "Zip" for easyfinding,rather than the traditionalc or asm.If I didn't want to enablethe brownoutresetcircuitry,I could have put a bleedresistorof 4-7k or more across the PIC16F684's Vdd andVsspins,which would drain the capacitorswhen powerwasremoved. *incluale - 9irp1€ zl.pFLash.c /* an IJED on ZipZaDa, Prc15E584
c program
llhia Program ia a motllfi€dl 2. crr . witb Brolrn Ou! Delect Active RlA4 - IJED Poaitive RA5 - IJED lil€gative
F X
i
i
r---!
a q
vergiofl
to
of
FIaBh
',cFlash
Cofilection connection
royke Dr€alko 04.11.25
coNFIG ( MTIO & lvE||tDIS & PWRTEN & UCI,RI'IS IJNPROTECT \ & I'IIPRCXIECT & BOREN & IESODIS & FCMDIS) t
&
nain( )
(
PORTA = 0, Cl'lCONo = 7, ANSEIJ - 0; TRISM = 0t TRISAs = 0i
Lll
e*€
== 7l
!rhi1€(1
// // //
Turn off ComparatorB Tulr off Alc Make RA4/8A5 outsputs
ll
Loop Eorever
{ for
t'*
for
f I I
) I
(i (j
= 0r
i
< 255r i++) // Si,ryrle 500ms Delay = 0r i < L29? )++lt
RAo = RAo ^ Lt // elihw // E'l.d. zipFLash
/l
T oggle
rJED state
"}{ The applicationwasbuilt on a breadboard(seeFigure 13-7),and after enablingbrownoutrest,it ran fine and did not seemto affectthe operationof the ZipZapschassisand PCB (which,other than the addition of wiresfrom the battery'spositiveand negative connectionEwasunmodified).The batterycouldbe
306
Zipzaps
Figure 13-6 ZipZapspower supply testcircuit
chargedfrom a remotecontrol while pluggedinto the power supplycircuit.And when the batterywas charged,it not only chargedthe ZipZaps' batterybut alsopoweredthe MAX756 and the PIC16F684to which it wasconnected. With the MAX756 power supplyand PIC16F684 circuit addedto the ZipZaps chassis, I found that the PIC16F684's LED would flashfor 10 to 11 minutes (abouthalf the time the unmodifiedZipZapswould sit on the tablebeforeloosingenoughchargeto the radio receiverto stopbeingableto move).With the radio receiverand wiring still present,I found that the motor would run, without any dragon the wheelqfor about4 minutes,about the sameasthe unmodifiedZipZaps. The conclusionI reachedhereis that any task the robot is performingshouldbe completedin 2 minutes or so,to make surethat it doesnot run out of power.If you werein somekind of contest,you would haveto make surethat you won in 2 minutesor less.Otherwise you would loosefrom lack of batterypower. Essentially,all the requirements outlined here are met with the MAX756 step-uppower supply.Looking at the voltageoutput from the MAX756 usingan oscilloscope,no indicationwasgiventhat motor noisewas beingpassedto the PIC16F684.TheMAX756 is an eight-pinpart with five supportcomponents, which madeit appropriatefor usein this application.The runningtime of the robot did not seemto be negatively affectedby the additionof the MAX756, PIC16F684, and LEDs to the load poweredby the ZrpZaps rechargeablebattery The only issuenot addressedin this experimentis whetheror not the MAX756 cantoleratethe 5 volts appliedto program the PIC16F684in circuit. This is an important requirement for the application,asI will discussbelow,andit is not mentionedin the MAX756 datasheet. To be on the safeside,a silicondiodewill be usedto isolatethe PIC16F684's power supplyfrom the MAX756's output.The following experimentswill determineif this will affectthe operationof the other componentson the Robot'sPCB.
l , e 3 P I C o l ' l C UE x p e n i m e n t s f o r
the Evil
Genius
14 X i-s
Experiment 115-Plf MCUElectronicsPfB
o
tt
F..
1 Radio Shack ZipZaps remote-COntrOl Ca!
3 o
1PrC16F684 1 MAX756 1 1N5817 Schottky
di,ode
1 LED i.00 pF electlolytic (rated capacitors least 10v)
DMM Needle-nose
0.1 p,F capacito! tYpe)
pliers
(Dremel Rotary hand tool tool) with carbide disk cutter Electlic
dliI1
e/er-inch
high-speed
14-pin, machined pin DfP socket (see text ) Tno-pin, right-ang,Ie st!aight-through conltec-
dlill
6^
Four-pin, !igbt-ang'le straight-throug'h connectol
i '^6
Solder Black
fwo-pin, througrh
wire
Red wile Y[ire-wrap
hd
Prototyping text )
KrazY GIue
6-32, bolts
epoxy
With the powersupplytested,you are now readyto start hacking into your ZipZaps car and turning it into a robot. In this experiment,you will be putting in nylon bolt attachment points for the PIC MCU PCB aswell ascreatingthe basicPCB cfucuitwith the power supply andPIC MCU socket.Thistaskis not goingto be easy, andyou will haveto plan for the future experimentsto make surethat enoughspace(and holes)is available for mounting additional hardware.As I work through this experiment, I will try to indicate the issuesthat you shouldbe mostawareol The prototypingPCB usedfor this experimentcan reallybe of any type,but I usedone with predefined power and ground tracesand horizontally connected holes.This simplified my wiring somewhatalthough it restdcted me in other areasfor which I had to comDensatewhenI addedadditionalhardware. Youdo noi
f)
PCB (see
2-inch-long
6-32 nylon
nylon
L'J *-, ,,
nuts
rr
haveto usea prototypingsystemlike I used,but you shouldread the restof this sectionto understandwhat prototypingPCB you want to useand how it is going to be mountedto your ZipZapschassis. Positionthe prototypingPCB over the Zipzaps chassisin sucha way that the PCB will hang over the chassisevenly.Do not positionthe PCB so it is above the empty spacein the chassisbetween the battery and the steednggear.Themountingbolts for the PCB will be gluedinto this areaand ascloseto the steeringgear aspossible.When the bolts are gluedin, it is important that the chargingcontactsand hold-downholesare not affectedin any way.If they are hindered,you will not be able to chargethe Zipzaps battery using the remote-controlunit. With the marksin place,find the centerof the PCB at this Doint and drill two e/er-inch holes 0.250-inch
5ection Thirteen Z i p Z a p s@ Ro b o t
L J
K
straightsocket
Four-pin, straig'htthrough socket
wi!e
PermaneDt malke!
Five-minute
I
H
Wire clippers ra'i
(anY
H P Ol
0. 01 pF capacitor
bir
c^l
at
5
*
307
*
Ff
n
,-t
P, {a li
ry
R lrr{
t ,
m
U A
w U
,Fl
g
o t{
{J
U
(} FI
rd p U
x
U H
A
I \o rl r{ $
c 0, E .Fl t{
o
9{
X
frl
away from the c€nter.ff the prototyping PCB is fully drilled (as mine was),drill out two holeq four holes apart. Rememberto keep the PCB centered over the ZipZaps chassiswhen you are doing this. Once the holes are drilled, run the nylon bolts through and screwthem down with some of the nuts. At the end of the boltg loosely screwon a nut and put Krazy Glue on the open face of the nuts at the end of the bolts.Carefully (making sure you do not trap any of the small steeringwires) push the open face of the nuts againstthe bottom of the chassisThe bolts should be solid to the touch in 30 secondsor so.The Krazy Glue actsasa mild solvent to the plastic usedin the ZipZapqso leave the assemblyin place for an hour or so for the Krazy Glue and chassisplastic to harden. When the Krazy Glue has hardened,remove the bolts and cut the bolts down to 1.25inch (3 cm). (You will probably have to loosen the nuts holding the bolts to the PCB first.) Insert the bolts into nuts,cover the nuts ald the baseof the bolts with 5-minute epory, and wait for another hour for the epoxy to harden. When the epory has hardened,run two nuts down the shaft 1A inch (1/zcm) and Krazy Glue them in place.Once the Krazy Glue hashardened,you can place the prototype PCB on the bolts and tighten it down when you want to test the robot. With the bolts in place,you will now have to cut down the original ZipZaps PCB.This is being done for two reasons.Fhst, you want to avoid any kind of contention betweenthe ZipZaps driver and the PIC MCU. And second,you want to make spacefor the two bolts you just installed. Before cutting the PCB with a Dremeltool and carbidewheel,I locatedthe four resistorsusedfor current limiting on the PCB and drew an indicator line on the PCB above them (see Figure 13-7)using an indelible marker. Cut the PCB along this line carefully,making sure you do not damageany of the marked resistors. Once the ZipZaps PCB has been cut, solder wires to the positive (red) and negative (black) wires leading from the battery to the PCB.Thesewires will go to a right-angle connector to be soldered to the bottom of the prototyping PCB and will need the straightthrough connector soldered to the other end. Next, solder wire-wrap wires to the endsof the four-motor driver and steering driver resistors(seeFigure 13-8). Thesefour wires will be soldered to another straighttbrough connector,which will go through another right angle connector and the bottom of the prototyping PCB.The ZipZaps chassisis now ready to be controlled by a PIC MCU! When I attached the PCB to the robot, I did it with the solder tracesup.This make soldering components quite a bit more difficult, but it ensuresthe PIC MCU power and motor/steering driver connectorsare easy
308
Figure l3-7 Mark cuttingline abovecuruentlimiting resistorsand belowblack blob
to solder and their whes do not snagor rub against sharp wires on the bottom of the PCB.The machined pin socketthat wasspecifiedfor the PIC MCU was identified becauseit can be soldered to the PCB from the topside (instead of only from the bottom side,asin a regularDIP socket). The circuit that you will be wiring to the PCB is the basicpower supply with PIC16F684(without the two LEDs) in Figure 13-9with the bottom right-angle connector usedto supply the 1.3volts from the Zipzaps battery.Again, it's important to plan ahead;due to my wiring placement,I put the MAX756 and its related discretecomponentsat the front of the robot, which left the rear of the PCB for the PIC16F684. When you have completed the assemblywork, your robot chassiswith PCB should look something like Figure13-10.You shouldstill be ableto put the ZipZaps chassison the Zipzaps charger,and it should work normally (i.e., the charger'sLED should start at red and changeto green when the charging operation hascompleted).Ifeverythingis correct,after taking
Fisure 13-8 PCB connector
l , e 3 P I C @l t C L JE x p e r i m e n t s f o r
the Evil
Genius
Zipzaps
' iI .
Fieure 13-9 ZipZapspower
the ZipZaps chassisandPCB off the charger,an LED placedagainstRA4 andRA5 (cathode)shouldstart flashing.Thereis no on andoff switch,the MAX756 will stop providing3.3-voltpower whenthe input voltagehasdroppedbelowits threshold.This shouldgive your robot a minuteor two of basicoperation,which shouldbe goodfor testingmostapplications. I found that althoughthe connectorswere quite reliable,the solderjoints and wiresfrom the battery and motor to the ZipZapsPCB would easilybreak. Ideally,the prototypingPCB would be permanently attachedto the ZipZapschassis(asis the original product PCB),but this is very difficult to do and still be ableto work throughadding(and debugging)the differentperipherals. Make sureyou plan how to con-
:-11 Figuref 3l0 wirhpnrrinlty ZipZnps chassi.: assembled PCB attached
nect and disconnectthe prototypePCB to the ZipZaps chassisso that the wire solderjoints receivea minimum of stress.If you don't,you will find that the wires will breakperiodically.You'll be left scramblingto figure out the causeof the problemand then fix it, with the wiresbecomingshorterover time. This is probablythe mostdiflicult assemblyexperiment in the whole book.Rememberto think about whereeverythingis goingnext,and try to keep everything aswell centeredasyou can.A few momentsforethoughtwill saveyou a lot of grief later.
5ection Thirteen Z i p Z a p s " R o b o t
309
Experiment ll7-lH TV FlemoteControl
Prc16F684
r{
38 KHz tR TV lemotereceivers coltrol
$'1
1 fno-1ine,
4r
1 10k lesistor I
16-column
LCD
100C) lesisto! 10k b!eadboard-mountable potentiom€ter
t'l
4? pF electlolytic capacrto!
Needle-nose pliers
al
B!eadboard
+J
Wiring
0.01 pF capacito! type)
kit
(anY
B!eadboard-mountable (E-Switch SPDT switch 8G1903 leconmended)
G.}
Breadboard-mountable momentaty on pushbutton
F.
Thlee-cell, pack
AA battery
AA alkaline
battelies
f-r
ffi H
I like controllingrobotsusingan infraredTV remote control;they are cheapand the coderequiredto read the data is surprisinglysimple.Other optionsinclude RF or soundcontrol,but thesetend to be expensive and"fiddly" comparedto IR control,especiallyconsidering that IR control is generallyhandledby the robot'scontrollingPIC MCU. In this experirnent,Iwill demonstratethe code and circuitry required to read an incoming IR signal and display it on an LCD. The IR signalproducedbyTV remotecontrol comesout of the receivermodulelooking (seeFigure 13-11).TheIR signalfrom the remote-controlcodeis
modulated with a 38 kHz signal that is only active whena low is desiredin the receiver'soutput.For hobby robots, I like to use the SonyTV codes,which consistof a PacketSrat followed by 12 bits in the format shownin Figure13-11.Thetiming of the different featuresof the waveform is basedon a 550rr,sT clock and consistsof differentmultiDlesof this time base.
"1"Bitl "0"Bit
0)
-:-T;.5
.r-l
ti &r".
Start(4T) Figufe
'13-'f'f
Synch "i'
(1r)
"0'
I
(1r) (2r)
IR remote-control codes
Figure l3-la
IR Rx testcircuit
{d I F{
310
l , A 3 P I C o l ' l C UE x o e n i m e n t s f o r
the Evil
6enius
Table 13-1 Codes LJEedbg the 5ong TV lFl Flemote-Control ZigZaDs Robol
B.ut!* 0x010
.PIP"
oxDB0
"2"
0x810
"Enter"
0xD10
"3"
0x410
"Display"
0x5D0
0xC10
"Mute"
0x290
0x210
"Recall"
0xDD0
OxA10
'Alrow Up"
0x2F0
"1"
'5" "6"
0xAFO
0x610 "8"
Ox2D0
0x110
'Arrow Left" 'Arrow Right"
oxE10
"9" '0"
0x910
"Menu"
0x070
"Power"
0x490
"Guide"
0x764
0x490
'oK"
0xA70
OXCD0
To read and displaythe IR incomingsignals,I came up with the circuit shownin Figure13-12.This is a modificationof the originalLCD displayexperiment's circuit,whichnow includesan IRTV receivermodule with the requiredfilter capacitorand resistor.The C programming languagecode for driving the LCD was translatedinto assemblerasasmlCD.asm,which can be found on the PICkit's CD-ROM.The actualcode that readsthe incomingIRTV remote-controlsignalis calledasmLCDIR.asm.Note that to simplifythe time delayqI createdthe Dlay macro,which will delaythe operationfor somesetnumberof microseconds. When I ran asmLCDIR.asmon the circuit shownin Figure13-12,I cameup with the codesin Thble13-1 for the different buttons on a universal remote programmedto output SonyTV codes.These different codeswill be usedfor controllingthe ZipZaps robot in the following experiments.
m t?t h+
J
g# *"€
r'*
i..*
# i-Et
0xC90 "Ch+"
0x090
'Ch-"
0x890
! ht qr.'
llB-Motor and SteeringEontrol Experiment
ry fli ,"{
Radio Shack ZipZaps remote-control ca! chass is Ptc16F584 PrototYpe Previous
PCB flon the exPeriment
4. ?k les istors 470O lesistors
{ !.s
ru
DMM Needle-nose Ilire
pliels
clippers
Soldeling
ilon
solder Wire-rirap
wj,re
With connectionsfrom the original Zipzaps PCB to the prototypePCB in place,the next stepis to make the motor and steeringconnectionsso that the PIC MCU cancontrol the motion of the ZipZaps chassis.
The connectionsrequirecurrent-limitingresistorsto ensurethe motorsand solenoidsare driven with approximatelythe sameamountof curent, that they perform asdesigned,and that an excessive amountof currentisn't flowing.Thisis an importantpoint because the PIC MCU will be driving high signalsat 3.3volts insteadof the 1.3V measuredon the oiginal ZipZaps. To calculatethe new currentJirniting resistorg I voltagedrop was assumedthat the base-to-collector 0.7V, and usingthe known basecurrent-limitingresistors.I couldcalculatethe exDectedbasecurrents.
5ectionThirteen Z i p Z a p s @R o b o t
311
*"3.
5C I
q , e*
.}
For the steeringdrivers,the basecunent is:
Zipzaps
t':r\ t,:,
v=lateering*3.3k = (1.3 - 0.7) isteeling
/ 3.3k A = 0.18 nA
To maintainthis basecurrentwith a 3.3-voltoutput:
i.{
t'1 f
v = isteering x Rsteeling Bst€€ring = (3.3 - 0.7) / 0.18 rnA = 14.{k
i
iJ, f'j
.; -{
With 3.3kalreadyin seriegan additional11.1kof resistanceis requiredfor the steedngsolenoiddrivers. Similarlyfor the motor drivers,the basecurrentis:
Figure l3-13 Zipzaps motor
a ! v = r l . f t t x z z u
,i:
i.".., = {1.3 - 0.'7) / 220 A
+-,)
= 2.'73 nl+
if]
To maintainthis basecuffent with a 3.3-voltoutput: - {
?
t-; ltl
R . . " " , r " n= ( 3 . 3 - 0 . 7 ) = 950O
F.!
,.:r l
':. : l rl,,.i
/ 2.'73 rnA
With 2200 alreadyin seriegan additionalresistance of 7300 is requiredfor the motor driversto be controlled by the PIC MCU With thesevaluesin mind,I testedan additional 10kfor the steeringdriversand 680Oresistorsfor the motor driversaswell asno additionalresistanceat all points.Totestthe actionof thesecircuits,Iconnected the transistorbases(with seriesresistors)directlyto 3.3volts.When the calculatedadditionalresistorswere in place,the motors and steeringsolenoidsseernedto work exactlythe sameasthey did with an unmodified ZipZaps.With no resistances in place,both the motors and the steeringsolenoidshad a lot more power.In an effort to find somebalancebetweenmore power and
Figure l3-fq ZipZaps robot prototyping PCB with motor and steeringtransistorbasecuffentJimiting resistorsconnectedfrom the PIC MCU socketto the backsideZipZaps PCB connector
burningout the motors,driver transistors,or depleting the batterytoo quickly,I found that 4.7k and 470f) werethe optimal additionalseries-base current-limiting resistorsfor the steeringand motor drivers,respecIively.T\e ZipZapsrobot prototypingPCB (seeFigure 13-13)wasupdatedappropriatelyand wired according to Figure13-14,and it ran usingthe softwarepresented in the next expedment.
i'i':
. !.t
i].
il
3L2
l , e 3 P I C @I I C U E x o e ri m e n ts f o r
the EviI
6enius
Experiment 119-BasicTaEk-Eontrol Softurare Pc/
Prckit"" 1 Radio Shack Zipzaps remote-control ca! chas sis P I C 1 6 F 5 84 Prototype
starier
Tool
Box
#def,ine Rc2 r #define RC3 t *define RC4 r RC5 r i r r
Earlier in the book,I demonstratedhow to run a motor with a fairly low frequencyPWM. I'm goingto takeadvantage of thatwork with the ZipZapsrobot because I wouldlike to usethe PlC16F6lJ4's builfin PWM lor modulatingI/R output.Theresultis ZipBase.asm, which hasa 30 Hz PWM lrequency,and provides32 PWM duty cycles,aswell asup to 1 ms betweenPWM stepsfor implementingsensorand control functions. To test out the connectionsto the ZipZaps chassis aswell asto get an idea of how long the batterywould lastwith a PIC MCU runninga stepped-upbattery voltage,I addeda numberof actionsthat take place over a 25-secondrepeating/l/e to demonstraterunning forward,forwardwhile turning right and left, stopping, and goingbackward. "zipBase
title t r i , r
-
zi.pzags
Robot
Ease
coale"
This Program Iroops orce every ns anil upalates the zipzarls Motor PI'iM (30,I{2 P!'Dt). The application also keeps lrack of the current time for the application.
.
FLia
t
heavily
.nn1,ida+i^n
ia
ba6eal on "asmMotor
2.asm".
Haralware No!€s: t PIC15F584 rurrnirrg at 4 MIIZ Using , Intelnal Cl,ock t RiA0 - Lef,t Light Senso! r RA1 - Rigbt Light Sensor r RA3 - Rear IR sensor t RA4 - Reverse Motor Control t PORTA, 4 #alefine ReversePin AA5 - Forwardls Motor Corrlrol t
PCB
kit
['orwardsPin PoRTA, 5 - Rigrht steeringr solenoid TurnRisht PoRTc, 2 - Left Steering Solenoid liurnl,eft PoRTc, 3 - Line FoLl.owing IR PWM - Object Detection IR PI4U
li{yke Predko 0s.01.25 LIST R=DEC rNcr,uDE "p16f 58{. inc rr CONFIG FCITEN OFF & IESO OFF & -BOD.OFF & CPD OFF & CP OFF & MC',RE OFF & PWRTE.ON & IIIDE OFF & ITiITOSCIO
variables cBr,ocK 0x020 RTC:2 r 55 Second RTC Directionr PWMDuty, PWMCycle t PWM Movemen! r variables Flag ENDC ;
Flag r #alefine
Bit Definitions F1ag, AppRun
#alefine
A)pReset
Tinecheck novl.w xornf btfss goto tnovlw xorwf btfss goto enalln
the r
alag,
Macro TvaLue, fiIGE Tval"ue RTC + 1. rt STATUS, Z lilotv€cto! LOW Tvalue RTC, w sTATus, z Notvector
if
Application
0
i
Set
1
i
Set if application Reset Coale to Run
Notvector
FAGE Mainline org
0
nop clrf,
r For PORTA
5ection Thirteen T i p Z a ps o Ro b o t
ICD D€bug
t Assune is Low
Everything
5r5
ft! !
'>
novwf, Ilovllr ovwf, clrf
cMcoNo b,00000001, a.DcoNo TuRo
H c,-J
F,t-l 3 I
I
EnabLe
STATI'S, RPo b,11010001,
movwf lrovlw
novwf bcf
OPTION_REG ^ 0x80t b,00000011, r t ANSEL ^ 0x80 b,00010000, r t A.DCONI ^ 0x80 b,001111, r TRISA ^ 0x80 b,110011' , i ERISC ^ 0x80 STATUS, RPo
bcf
MTCON,
cllf cltf clrf
Flag Pl[{Duty PWUCycLe
cLrf
Dilection
movwf novlv lrofisf novLw
Loop: btfss goto bcf
ToIF
INTCON, r0lr $-1 MTCON,
llDc
1'!lR0 aa a P!l!l
ADC Clock
Enable
l{otor
Enabl€ Bita
gtse€ring
as
tfufler
anal Wait
for
Check to Upflate llotor If Duty > Cycle, then Off,
sublrf movf iorftd btfac
PWUCycle, PORTA, w 1 << 5 Directl.oa,
xorlw btfac andLw movwf
(1 << 5) + (1 << 4) t TRISC Revelse STATUS, C b,001111, Uoving , Notbing PORTA Value i Save ltotof
incf
RIC,
blfsc incf
STATUS, z RTC + 1, f
incf
P$Dlcycle,
f
bcf
Plglqcycle,
5
!h€
w
f,
t Going Fornarda or i Forwarala
i Incredreat , CLock
IrooD t Finiahetl, A.rounal Again
TestApplication Software:
t i r t r r t r
-
Test
Motor/Sbeering
Thi6 Program ia a baEic teal of lhe ZipZaDs Robot llotors anal St6€rlng, Th€ cofiuranats ar€: 1. Dlove f,orwatta for 5 S€conala at 10 Secoadg 2. llurn Right at 11 gecoatlB for 1 gecondl 3. firrn l.ef,l at 13 g€conflB f,or 1 g€conal 4. Stop at 15 Seconala f,o! 5 Secoatlg 5. co in Reverae al 20 gecontla for 5 geconalg 6. Rese! RrC andl Regeat at 25 Seconala
Haralware NoleE: i PIC15F584 runnl.ag at { UItz Using t rnl€lna1 clock t nAo - Left lj.ght Sensor r nA1 - Right IJLght sensor t RA3 - R6ar IR genaor , ItA{ - Revera€ llotor Coatlol t *tlefine R€versePln PORTA, rl RiAs - Eorwarala l{otor Contsrol t EorwardtsPin PORIA, 5 *tlefin€ RC2 - Rlght Steeling sol€Doial r TurnRight PORTC, 2 *fl6flne gteeling RC3 - Left Sol€noid r Turnl€ft PORTC, 3 #alefin€ RC4 - Lia€ Following IR PWM r RC5 - Obj€cl Deleclion IR ItwM r
r r
lbe
MYk€ P!€dko 05.01.25 LIST R=DEC INCLI'DE n916f 68{. lncn
ReaMme
i Notse. RoLls , 5 5 a
over
a!
FC!IEN_Orr & _IESO_OEF & _BOD_OFF & *coNFIC -CPD OFF & CP-OT! & _IICIJRE_OFE & _PWRTE_ON & _t{Dt[_oFt' &,INTOSCIO Valia.blea CBLOCK 0x020 RTC:2 Dir€cEion, PlcuDuty, i
ftr
lhe FVIM i Inclenent r eIc1e counl , Ma:limrm of, 32 i qfclea
##** - Pul other sensors Here ###* - Put in Rdnole Contlol Poll E€le l++#+ - Puts in seEsor State lttachine - rJigh! sensola (1 Pull per 32 cycles *##* -
td-l SJ
##**
"Zil)ulrchk titsLe cE)erationtr
TuRo tso
PVlMDuty,
0
##**
Put oDeratinq IJogic Here (1 Per 32 cyclea) /Ne€ds sel FIag - Check "llDDRea€l' lo ge€ if ApDLicatioa is to be Restart€al - Relrot€ conlroL (uov€ or Dir€ct SloD) ReEets trAlrpRuan FIeg .Recall' - Reatole Contfol Sets ,,ApDRunn t.lagl
€nil
BitE
novf
rtr
##**
-
looD
NoE Uoving at Eirs! gtalt at tshe B€gLaning lloving Forwaltls
t Reaet t Next
#**#
to
Selecl Foac/8
for r wait t Overfloqt
r t r r
, r r r , r r r
RAo/RA1 (AI{0/}N1) ADC InputB
for r Wail t OverfLow
ToIF
on llao
i 1:4 Preacal€! t ll,lRo
r r r i
Uolorlrpdale:
!r*
,
baf novhr
movwf movlw
, \l
co4Daratora
r ugitrg t Base
*{
e{
i
**#* *###
314
Pwucycl€
r 55 Seconal RTC i PvtM ltov€ment ; variablea
Elag ENDC FLas Bi! Def,initiona , AppRun F1ag, *d6fine
1 Sdrlp1€l8 crrcl€s] - Object (1 P€r 32 Cycl€a) Sensing - IJine S€nsing (1 Per 32 Cycles)
l , E 3 P I C @l l C U E x p e n i m e n t s f o r
the Evil
0
r se! if, t ApDlicalion i Run
Genius
c.rn
+ilef,ine
AppRes€t
Macros t Tinecheck novL$r xonrf, btfss golo movlw xornrf btfss goto
r
Flag.
Macro rvalu€, HIGB walue RTC + 1, w STATUS. Z Nolvector LOW lvalue RTC, st STATUS, z Notvector
1
r Set if Reset , Applicatiofl r coale to be Run
Notvecto!
i
cLrf
PoRTA
clrf novlw
PoRTc 7
movwf movLw
CMCONo b'00000001'
novwf cLrf,
ADcoN0 Tl,tRo
For
ICD Debug
r Assume ; Everjrtshing
is
r Elrable r RAo
A.DCon
TMRo as a r using r Pwll Base
STATUS. RPo b,1L010001,
movwf movlu'
oPTIoN REG ^ 0x80r b,00000011,
monwf movhr
rrNSEl ^ 0x80 b'00010000'
movwf movlw
ADCOIiII ^ 0x80 b'001111'
lnowf rnovlw
TRISA ^ 0xg0 b'110011'
movwf bcf
TRISC ^ 0x80 sTATus. RPo
bcf
INtcoN,
clrf clrf
Fl.ag RTc
clrf clrf
REC + 1 PWMDuty
i
clrr
pi^,Mcycle
j Silii "" "n.
clrr
Direcrion
; ;::iilT:,-",",
movf
I!fllCON,
r,ow
r rurn off r Conparators
bsf novlw
goto bcf
l'
xorlw blfsc andlw MOVWf
{1 << 5) + (1 << 4) STATUS, C b'001111' PORTA
0
btf,sc incf
STATUS, Z RTc + 1, f
ToIF
r 1:4 Plescale! r T!tR0
S-1 IN!!CON, ToIF
PWIilDuty, w
to
r AjA0/RA1 (ANo/AN1) t ADC Inputs , i
s€Lect ADc cLock as Fosc/8
r Enable r Bics
Motor
t Enable r Bits
Steering
for r wait ; owerflow r Res€t t Flag|
TorF
Going Eorwarals Forwards or Rev€rs€? TRISC Reverse
, , t r
Movingf r Nothing i Save Moto! Valu€ Increment
incf
PWUCycl€.
f
bcf,
Pmlcycl€.
5
Not
TMRo to
Real
lloving
for r wait r Overfloxr
Tine
at
Tiner
r Reeet anal wait r for Next r t r r
check !o upalate the MoEor If Duly > Cycle, then Off
r ; , , , r r
##f* *#** #### ##*#
t i r ; r i r r
#*##
#**# #***
#**# #### #*+#
-
Real,
Ro11s t No!e, t a c 5 5 s
Over
Increment the PWM cycle count Maxinum of 32 cyc1".
i r , ;
0
nop
IJoop: btfss
PwMcycle, PoRTA, w 1 << 5 Direction,
i
PAGE Mainline org
subwf movf iorlv btfsc
Put Other Sensors s€re Put in Remote Control Po11 sere Put in Sensor stat€ Machine - Ligh! (1 Ful] per sensols 32 cycl.es - 1 sanpl€/8 cycles) - objecl (1 Per 32 Cycles) sensilg - line (1 Per 32 Cycles) sensing
- Put operating logic aere (1 Per 32 Cycles) /N€eds Set Flag - Check nAppReset. to se€ if application is to b€ R€starleal - Ramote Control (Move Direct nAppRunn FIag or S!op) Resets oRecallr - Remote Cont'rol Sels "appRun" Flag
Molor Check Test Program: r Move forvrarala for 5 Seconfls at 10 Seconals r 1. TryForwarals: Timecheck 10000. Atlssec novlw 0x1F r Go Forwatals at r Fu11 Speeat f,or 5 s novwf PWMDuty bcf, Direction, 0 goto l"oop Atlssec: Timecheck 15000. TryRight clrf PI{MDuty goto Loop
r at
15 Secondls?
r Yes,
rufn Right at 11 seconds r 2. TryRight: Timecheck 11000, All2sec TurnRiEht bsf goto rJool)
f,or
Slop
Motor
1 s€conal
Atl2sec:
';::"n"ni3lll;nlo""" goto
Loop
Turn lr€ft at 13 Seconale for ; 3. TryL€ft: Tirnecheck L3000, Atl4sec bsf turnleft goto Loop AtL4sec: Timecheck 14000, bcf Turnlef,t gotso IJooP
1 secontl
TryRever6e
S e c t i o nT h i r t e e n Z i o Z a o s @R o b o t
315
t {. t 5.
Stop at 15 Secontts f,or 5 Seconals G o l n R e v e l s e a t 2 0 Seconala for 5 Secontls
Timecheck 20000. nrovfnr 0x1F movwf, bsf, golo
PwMf,)uly Direction, IJooD
At2ssec at i Go Fofi^rarals r F1rll Speeal for
5
0
Res€t RTC anal Repeat r 5. At25s€c: Timecheck 25000, Loop clrf PWMDuty eLlf RTc + 1 cllf RTc
25 secontls At 25 seconals ? Not thele, R€peat Yes. Stop Motor CLea! the R|rC
Einish€dl, loop Alounil Again
As part of the developmentof this application, you'll seethat I cameup with the TimeCheckmacro, which will executethe codefollowing it when the ,'ealtimeclock (KlC\ variablematchesthe numericvalue. The RTC variableis incrementedonceeverymillisecond, sofairly precisetimingsare possible.When you look at the operationof the ZipZaps robot in this experiment,you'll seethat the motor is runningfor 5 seconds. And I want to wam you:The robot can go a long way over 5 seconds. Fortunately,whenthe robot hits a wall or other obstacleand stalls,it doesnot burn out.This is why it wascriticalthat I spenttime understandingthe motor and steeringdriver basecurrentsand addingaddi tional basecurrent-limitingresistorsto ensurethat the driverswould not havetoo much cunent passinq throush them.
Experiment laO-lR FlemoteControl
Radio Shack Zipzaps lemote-control car chassi s 1 Prc16F584 1 Prototype
PCB
1 38 kHz IR TV lemotecontrol leceiver 4? pF electlolytic caPacr!or DMM Soldering
10k resi.stor iron
100C) res isto!
SoIder Slire-r,y53" "r1t.
Beforeyou ran the Zipzaps robot in the previous experiment,you may havedoubtedhow fastthe Zipzaps robot could go.After you ran the experiment, you probablyrealizedhow difficult it would be to control the robot usingjust softwarewithout any type of feedback.In this experiment,you will modily the prototypePCB circuit (seeFigure13-15)so that the entirerobot canbe controlledby a TV remotecontrol setto SonyTV standards(reviewedpreviouslyin this secnonr. The remote-controlreceiverwasaddedto the rear of the robot (seeFigure13-16)asthis wasthe easiest
316
placeI couldfind for the circuit,and it will be usedin a later experiment.The output of the receiverdrives RA3, which canbe usedonly asan input.This wasan importantconsiderationbecauseI wantedto make sureI left the driver valuesopen for the remaining experiments. The applicationcodepolls the IR receiver,waiting for a signalto comein. The codethat processes the signal wastaken directlyfrom the previousIR TV remote-controlexperimentin this section(which alsoallowedme to usethe codesthat wererecorded duringthis experiment).Thebutton commandson the remotecontrol are usedto drive the ZipZaps robot forward (while optionallyturning left or right) or backward (while optionallyturning left or right).The PWM
l , E l P I C @I ' l C [ E J xperiments fon the Evil
6enius
valueof the motor driver can alsobe changedby using the volumecontrols.In the code,ZipBaselR.asm, which is an enhancement of the previousbasecode, you canseethat hookshavebeenput in for the remote conhol to be usedasthe tool that startqstops,or suspendsthe executionof a testprogramthat hasbeen addedto the applicationcode. As you controlthe Zipzaps robot,you'll probably noticea coupleof things.First,running the Zipzaps robot by remotecontrolis a lot of fun-arguably as muchfun asthe originalZipZaps,but different becauseit is just aboutimpossibleto spin it out or slide
it on the floor.This changein operationseemsto be due to the additionalweightof the prototypePCB and its electronics. So,what wasthe advantageof making thesemodifications?After severalhoursof work. have you simplyrecreated the Zipzaps? This is not quite true,the little robot you haveis capableof a lot more asI will showin the remaining threeexDeriments.
t:t:t:
{$
,i1'!
r-!' t,-l l'-*
Zipzaps
t{q
I
{, *rr
Figure 13-15 ZipZaps IR
Fiqure 13-15 Rear-lookingIR receivermounted underthesurfaceofthe ZipZaps robotprototypePCB
; f
:
fa,
ExFeriment 121-LightSensorsand LightFollor-uing
q,?d
|-1 {il Radio Shack zipzaps remote-cont!oI car chassis I
P r c 1 5 F 5 84
1
Prototype
ir:i
PCB
Lj.qht-dependent tors
resis-
i1;I :.{
10k resistors DMM
".,.i
Soldering
iron
SoLde! Wire-wrap
wile
A basicfeatureof any robot is the ability to senselight and dark and,ideally,to do it from multiple pointsof view so that comparisonsofits environmentcanbe made.In this experiment,you are goingto giveyour
Zipz^ps robot rhe gift of sight-that is,two lightdependentresistorsthat canbe usedto seekout or avoidlight in the robot'senvironment.Adding the two LDRs aspart of a voltagedivider is quite simple(see Figure13-17)and takesadvantageof the ADC module built into the PIC16F684. As you canseein Figure13-18,Iput the LDRs abouta third of the way backfrom the front of the robot, with eachone pointingoutwardat 45 degrees. This giveseachLDR a uniquepoint of view.This
5ectionThirteen Z i p Z a p s @R o b o t
3L7
.i.*;
:gJ !'r...4"
:-i l.t?
i.a i :
{_i *? t'l i
1..l
.:-1 e1 11i
ai
placementof the LDRs allowsthe robot to determine which sideis brighter and whetheror not to turn towardit or awayfrom it. The applicationcodeZipBaselDR.asmis an enhancementof ZipBaselR.asm,asit providesan ADC operation(on RAO and RA1, wherethe LDRs are connected)every4 ms.EachLDR is sampledand the resultsare storedfor retrievalby an application. Included in the code is a simple llglrr seekerlhat e\ecuteswhen the remoteconkol's Menu button is pressed.
proportionalsteering,guidanceto a light sourcecanbe gentlerandnot so startlinglyjerky (when the robot turns towardthe light).TheLDRADC valuesare ADCValueL andADCValueR in the applicationcode. I found the robot'sability to hit a flashlighton the floor (the light beamfor it to follow) waslargely dependenton how quickly the robot's motorsturned. The fasterthe robot moves,the later the steering changetakesplace(the decisionis madeevery100 ms),andthe more likely the robot will be to missthe flashlisht.
The light-seekingapplicationturns the wheelsonly whenthe darkerLDR returnsa valuethat is twice (or more) the valueof the lighter LDR. Thisvaluerepresentsquite a drasticchangein light and waschosen becauseof the all-or-nothingoperationof the ZrpZaps chassisternarysteering.In a more typicalrobot with Zipzaps
&."{ i
a
fi1
$l&*
ts{
Experiment laa-lH Bbiect-Detection Sensors
i
t Radio Shack Zipzaps remote-cont!oI car chassis
gV
1 Prc16F584 1 Plototype
PCB
38 kHz IR TV remotereceive!s colrtrol Re d I.ED
H
IR LEDS 10k !esistors
l1!
DMM
1k resi stors
Soldering
100k resi stols
So 1de!
47 /rF el.ectrolytic
VIire-vrrap Length sh!ink
{.,4
*at
of 5nm heattubing
i 6 t
318
l,e3 PICo llCUExperiments for
the EviI
6enius
ZipZaps Battery
t r l
fr
n o
Plc16F6B4
o100 uF 5
0.01 u
F
L
.
410
z
1
8
4.1k
1
4.7k
8
MAX756'
f tt
Reverse FoMards
*J"
RightSolenoid
;J
LeftSolenoid vdd
100 -lI
!
1k
47 uF
T __-l_ -:_
:
100
100
47
47 uF
uF
t/R
-'1I
E\.'
r\J
vdd
Top Side t/R LEDs
l i
t t:
6*"* '"5 '
Figure 1319
Zipzaps complete :t i
In the lasttwo experimentsof this book,I will demonstratehow the IR sensorscanbe usedto detectobiects and data aroundthem.This will be doneby usingthe To IR reflectiondemonstratedin other experiments. the placed around detectobjectEfour LEDs are perimeterof the robot that will drive out IR pulses, which,if reflected,will be pickedup by threeTV IR receiversaroundthe perimeterof the robot.By doing "senseof touch" with this,you are givingthe robot a
Figure l3-e0 Zipzaps robc,twith IR LEDs and W r emote-controI receivers
the two front-lookingIR receiversand the rear IR receivergivingthe robot someideaof wherethe object is aroundit. To modify the robot for this task,I would like you to add the six LEDs (five IR and one visible)to the prototypingPCB,aswired in Figure3-19.EachLED shouldbe pointingin a differentdirection,asshownin Figure13-20.After you havedonethis,pleaseadd two IR receiversto the front of the robot.To avoidproblemswith conflictingIR signals,the receiversshouldbe on the undersideofthe robot (seeFigute 13-2L). To test the robot'ssenseof touch,pressthe Guide button on your Universalremoteafter buildingZipBaseObj.asmand loadingit into your robot.Thiscode continuouslychecksthe perimeterof the robot, every four PWMCycles. I found that I had to put smallpieces(0.5to 0.75 inch long,or 1 cm to 1.5cm long) over the IR LEDs to get reliableoperationof the sensor.But, it is amazingly reliable for eachof the three IR receivers.(To test the operationof eachreceiver,wrap the other two in black electdcaltape to preventIR signalsfrom reachingit.) The stateof the IR receiversandwhetheror not an objectis aroundthe robot canbe polled by checking the PFrontRIR, PFrontLIR, and PRearIR flags.
5ection Thirteen Z i p Z a p s @R o b o t
1 **€
r* :*i.
r} i,-'f,
ri3 :,.f1
ts* F&
319
Experiment 1a3-lH Line-FollouJing SensorE
u.;
.J!
1 Radio Shack Zipzaps remote-cont!oI cal chassis 1Prcl6F684 1 Plototype
PCB
rxt f.{
,'*
:i-**
{J P*
b&6 !
Thislastexperimentis really a follow-up to the previousone.However,rather than sensingobjects,the downward-pointingIR LED at the front of the robot (seeFigure13-21)is directedtowardthe surfaceon which the robot is runningand if the surfaceis white,it is reflectedbackto the IR receivers.(Use a oieceof heat-shrink tubingto directthe LED rowardthe running surface.)The applicationcodeZipBaseline.asm is a modificationof ZipBaseObj.asmand usesa second PWM output. title
M 9,s{
r"d 3 I
,'ZipBaseline
-
Zipzal,s
Robot
Base
Codler
"zipBaaeobj.aslln urith lJine SensorE AaLleal. t t Earalware Not€s: ; PIC15F58{ run.Ding a! 4 Mttz Using tshe t rntelnaL t clock AA0 - I,efts Light. S€nsor r aA1 - Risht Lights Sensor t aiA3 - Rear IR Sensor , *tl€fine R€alrR PORTA, 3 RAlt - Reverae Motor Conlrol t ReveraePltr #al€fine PoRTA, 4 RA5 - Fonrarala ![otor r Control For$aralBPin #tl€fine PORTA, 5
;\t
*C2 t #tlefine RC3 ; *alefire RC4 r RC5 r
- Riglrt Sleering Solenoial TulnRight PORTC, 2 - IJeft St€eling Soleaoitl TurnLef,t PORTC, 3 - IJine Following IR P!{}I - Object Detectsion rR PVUI
IR Coale Table: t Buttono EQU 0x910 Bulton1 EQU 0x010 Bulton2 EQU 0x810 Button3 EQU 0x{10 Butstotr{ EQU 0xC10 Buttons EQU 0x210 Button6 EQU 0xA10 ButtsonT EQU 0x610 ButtonS EQU 0x810 Buttong EQU 0x110 A.?lowltD EQU 0x2F0 ArlonDn EQU 0:.lAF0 AlrowlJt EQU 0x2D0 ArrowRt EQU 0xCD0 volurleu EQU 0x490 volumeD EQU 0r.C90 Chaa€IU EQU 0x090 chauelD EQU 0x890 OKButtn EQU 0nA70 PwrButn EQU 0x490 ![enuBtn EQU 0x070 EnterBt EQU 0:1D10 R€caIlB EQU 0xDD0 PIPBUIn gQU 0xDB0 DiEpBtn EQU 0x5D0 r'tut€Btn EQU 0x290 euitleBr Een 0x764 r
Myke
Prealko
t LIST R=DEC INCLUDE "plSf68{.incn & _BOD_OFF & -CONFIG _I'CMEN_OFF & _IESO.OFF _CPD OEE & _CP_OFF & MCI,RE OFF & PWRTE OII & rirDtt_oFE & _IN:losclo
ua ;?
Varj.abLes CBIJOCK 0x020 i, DLay RTC:2 Difection, PllllDrty, t
n€ ai]:
::{ 'i -"a
Figure l3-?l The businessend of the ZipZaps robot downward-pointingIR LED usedfor linefollowing
320
A.DCCycle, llovecount€r,
Pll!,lcyc1e
ADCValueL, i|Dc\IalueR r .e.DC Valiables NewPvn4Duty, volcounter
rRcoale:2 obj ectPliu
l , E 3 P f C @H C U E x p e r i m e n t s f o r
r 55 seconal RTC r PWUUovetn€nt t varj.abL€s
r Set
the EviI
Genius
Objec!
PWII
objlroEtR, LLnePl|!l IJi!€rrontsR, Flag:2 ENDC
objFroatl, t in€FroDtl
flag r *defj.n€
Bl.l D€f,iaitiong ApDRun Flag,
0
*d6fire
AIrIrR6B6t
rlag,
1
*dl€fin€
Lighls€ek
Flag,
2
#dlefine
objeelgeaae
Elag,
3
*dlcfine
PFrontRrR
r1ag,
{
*dl€finc
PFtontLrR
!1ag|,
5
#dl€f,ine
PRoarIR
Flag,
5
*alefi[e
Linese
llil€fiu€
r,ProatRrR
*dl€fine
aor
LFrortLIR
lilacroa t Tlmech€ck novftr xoliff btfaa goto nov1lr *orcf blfrrs goto €ndn
!1a9,
7
Flaq
+ 1,
FIag
lllacro Tvalua, EICN Avalu€ RTC + 1, rt STAfgS, Z Nolvector I,ow l\talue RTt, td STATjttg, z Notsvgctor
+ 1,
t t i r t r t r i i i , , , , r t r r t 0 r r 1 r ,
set if Aglrlicalion can Run set if, ADItIicatioD Reaat Cotl€ to be Run get \,rheB Lighl geeking ltoale ia Enableal get when Doirg an Objecl S€nBe s€t nb€lr obj€ct to lro|tt Right get wh@ object to Froat Left Set when object to B€ar get whea Doing a lJl.rt€ g€nEe get vlh€lr Lin€ to !!ont Righl g€t wh€n L1n6 to lro'lt IJ€fE
cltcoNo b,00000001' ADCONo I1{R0
novhr
b,00001100'
novwf novlw
ccPlcol{ b'01111000'
novwf
T2COII
bsf nov].w
STATttg, RPo b'11010001'
novnf novhr
OPTION_REG b'00000011'
nonrpf llovlw
INSEL ^ 0x80 b'00010000'
novwf, Dovhr
aDCONI ^ 0x80 b'001011'
lrovlrf movlro
TRISA ^ 0x80 b'110011'
movwf bcf,
TRISC ^ 0x80 STAmS, RPo
bcf
MTCON,
clrf cLrf
Flag PllldDuty
clrf Begirnlng clrf nrovlw
lilacro EutEoa, HICH Buttorl IRCoale + 1, !t ETATI'S, z Notvectora IloW Buttoo IRCod6, rd STATItS, z Notv€Ctor
t For
clrf
PORTA
clrf
PORTC
ToIF
ICD
t aggurne
Section Thirteen
Etralcle
r i ; t
UEIng mrRo as a Pl{Dl Baa€ Enable BaEic Pinl lloal€
ADC oa RAo
tttR2 Ple
lritsb
i 1:{ PreEcaL€r t rltRo
!o
r RAo/RA1 (Ar[0 /Alr1) t lllrc IiDutE ADc clock t Select i aB Fosc/8 , Enab1e Motsor ' IJED BitE
subwf novlw iorlw btfsc
PwMC!rcl€, 0 1 << 5 Dlrectlon,
Ena.ble Bits
iollrd btfac iorlw blfac
1 << 2 PFroDtt rR 1 << 2 PRearIR
5 ct
ts N I
Sle€ring
H llllRo
tso
w r{
Not llovlng al !lrat sEarE ats the
Fr,
5
o
o
f,o! r Wail , Ov€rflow aatl t Reset i for Next
P
llir|er
ts
o
l{ait
t check !o qDtlat€ i the llolor t If Duly > Cycle' t th€n Off
w rd
0
i Force tlotorE i Gioiiag EollcaltlE o! i Forieerala i Reverge?
Movinq t Nothing Ch€ck lo r Object ' PUt IJED ON
Z i p Z a p s @R o b o t
, ,
{
F'
5
q
v,
gav€!€RTA PFrontRIR
3 o
I
(1 << 5) + (1 << 4) SllAlrug, C 0 Objocls€nae
golo btfac
F.
qt
$ - 1 INTCON, TOIF
PWMDuty,
o
rt
(,
&
Fo:.warila i Moving at ttl1 t gtart t SPeed
IN!!CON, ToIF
rovf
x
rd
I
i i
i i i
D€bug Evertthiag
,
for , vfait i Ovelflolt
MotoruDdete:
0
co![)alatora
NelrPlllllDutY A.DCCycle llrcvaluelJ aDcvalueR
grolo bcf
nor.Iw btfsc novltr btfaa
noD
^ 0:<90 t
DLrecllon 0x1F
IJooIr: btfEa
liloweclo!
i
t Enable i a 15x
PllIlCycI€
rlovtrf clrf clr! clrf,
PEGE llaLnlln€ , olg
novwf movltd lovwf clrf
Nolv€ctor
EaDIay llacro C:icles Dovlw HIoH ( (c5zcIes / 5l + 256) Dor'rrf DIay Dovlw LOlv ( (C'ycles / 5l + 256t -1 atldllw blf,ac STATUS, Z tlecfaz DIay, f, qoro $-3 6rdn Bultoacoq)are novlw xorilrf btfsa golo mov\r xorcf btsfds gOtO eddm
t{l
objRear
o 5 u
o
If Sonaor ait get, LED Or
r't
(t 32t
i.orlw 1 << 2 SavePORTA: movwf PoRTA
rrovlw i
u iJl 3**
w (J!
F"r &*{
t t'g
:
Save
lilotor
value
R€al t Incr€lrent r Time Clock blfac incf
STATI'S, z RTC + 1, f
; Note, Ro1ls t a l 5 5 a
i.ncf
P$lMcycle,
f
bcf
PWMCycIe,
5
movf
lfovecounter,
btfsc goto alecfsz
sTA:rgs, z Nouovechang€ llovecourter,
golo btfac
Noltov€Clrange Lighls€ek
goto clrf
DolJlghtseek Pl{tlDutsy
bcf bcf goto
lltrnlJ€ft TulnRtght Noltovechaage
f
t Direct t llove?
Control
; Decrement t Counte!
Move
r h IJight r uoale?
Seeking
C1€ar , If Zelo. Duty , !4oving , Anal Stop Turning
Doligh!Seeh: movf, ADCVaLueIJ, ttt sublrf A.DCValueR, w blfaa STATUS, C groto DolightseekRight Dolightseeklrefl:
r IJook for t Is Righ!
Tutn > IJeft?
< Rights,
*** ;i
;t i - J
F*{
"i4 a-t!
STATUS, C ADCValueR, A.DCvaLu€L.
movltr btfaa novl{r
0 sTATus, C 1 << 3
movwf movl$
PORTC 100
movwf goto
trlov€Counter NoMovechange
DolJightseelrRight
a, yx LI4
r Is l.ef,t , eisht./2?
t ,
!!urn Light
:
STATgg, C ADcvaluer,, ADCValueR,
movlw blfss novlw abverf nrovlw
0 STATUS, C 1 << 2 PORTC 100
nov$f
llovecounter
<
rowarals
i Continue t aDoth€r
bcf rrf subnf
for 100 ms
< Left, r Rigbt Towarala? t tura w sr
i ,
Is Right IrefE/2?
r furd
<
To!,,a!ala
r Codtinu€ r anothe!
Nolilovechange: btfEc RearIR
rRR€afl: btfa6
Ligh!
for 100 ma
call
CountHigh
btfsc goto
STATUS, C Loop
goto
322
t IR Value Being i Recei.veal?
F-1
t l,ine to i Again
12
call novlw subwf
CountlJow 80 Dlay, w
llf llf
IRCoaIe, f IRCoale + 1,
dlecf,sz goto
i, f IIlRIJoop
t Carry Sel, r Erfor/Igrlore
go High
t
Cclt[laEfl
t
Ca!ry
i
R€peaE?
Sel,
1
f
anat lr6ft i Forwarala Bultoncompare Buttonl, CheckButtoa2 nrovhr 2OO i Run for 200 ns novrrf lttovecounler novf, NercPI {Duty, w novrrf, PlmDuty bcf, Direction, 0 t Moving Eofirardts bsf Turnlreft bcf rurnRight bcf .ltpDRun , Tuln Off Plogram bcf IJightseek r Turn Off lJight , g€eking lroop
Butloncorq)ar€
t forwarals
Button2,
movltr movlrf novf lrovrf bcf bcf bcf bef bcf
2OO Movecounler NewPt0tDuty, Pl,{llDuty Di!€ction, Tulnl"eft TulnRight AppRun Lightseek
gotso
LooE)
CheckButston3 r Run for
200 lla
w 0
r Moving
Forlralats
t Turn Off r Turn Off r Seeking
Program Light
CheckButlor3: i ForwaralE arrd Right qrtton3, Buttonconr9are Ch€ckBubtons movlw 200 t Run for 200 ns movfif ltovecounter novf, N€wP$uDuty, w movlrf PWMDUEy bcf Dir€ction, 0 , ltovLng Eoryrarals bcf Tuln]Jeft bsf liuraRigbt bcf, AppRun i Turn Off Progren bcf Ligbtgeek , Turn Off lJtght i seeking goEo
IJooP
Ch€ckButton5:
Sensolcheck
RearrR
Get
for t IJooD llere r Each Bit r l4ust be Applox
ButtoncodE)are Bultons,
goto
3*{
!t !r
IRItIJoop:
CheckButton2:
r Tuln Towartls? bcf lrf, subrdf
to
movwf
golo
r IJeft
t Want , Bits
ovet
the pWM i Incr€m€nt t C-yc1€ counl of 32 i Maxifi4 t c:'cLes f
L2
pw,tDuty
cllf bcf bcf clrf bcf
TurnLeft Turnlight llovecounler AppRun
bcf
lightseek
goto
Loop
l , P 3 P I C @l ' l C UE x p e r i m e n t s f o r
the Evil
r StsoD CheckButtsoaT r Stop
, t r t
Everylhing
StoD Applicalion Running Tuln Off, Light S€eking
6enius
anat IJefE Ch€ckButlon7: t Revels€ Buttson7, CheckBulton8 Buttoncompare 200 movlw t Run for 200 ms Movecouater novwf NewPWUDuty, !t novf PWUDUtY novDtf Direction, 0 bsf t Moving Backwartls b8f TurDleft rulnRight bcf bcf AppRuI r lPurn Off Plogram rJight bcf r,ighlse€k r TurD off t Seeking gtolo
EnterBts, Buttonconpare ap9Ru.u bsf bsf AtpResel goto IJooP
uenucheck
FoIIo''? r light Guitlecheck t SloP A.t[r Previoua , Applicetsion , Enable lJight , Seeking Moal€ , DiaabLe object uoal€ r seeking Line t Diaable
Menucheck: u€nuBtn, ButtoacdE)are ittpRun bcf bsf
TJightseek
bcf,
Objeclsense
bcf
Linegengor
movlw monwf movf, movwf, bcf bcf bcf golo
100 Mov€Counler NewPlCUDrty, PlllllDuty Dir€ctLon, TurnlJeft firrnRigrbt l.oop
*
IJooP
&6 .--
CheckButtsonS:
Buttoncompare rnovlw novwf novf movwf bEf, bcf bcf, bcf bcf, goto
ButtonS,
200 lilov€counler NelrPwltDuty, PlillDutsy Dir€cELon, Turnrr€ft rulnRlghts A)DRua lJightgeek
checkButlong r Run f,or
200 ns
w , Moving
0
Eackwartls
t Turn Off r Tuln Off i se€kingt
Program Lighl
Guiatecheck: Butstoncompare
0
PWll checkvolqp ! t Increase voLnneu, ChecllvolDn Buttoncompare novf N€wPWMDuty, w r At Limit? xorLw 0x1F gTAmS, z blfsc goto LoqP f iacf volcounter, r Delay lx qycle , Get 3s Range 0 btfs6 volcounter, , nr1l i coflErol f incf, N€rrPwllDuty, goto looD CheckvolDd; t DecreaE€ Recallcheck volun€D, ButstoDcolrDare movf, N€wPWUDutsy, f ; At lrinits? STAIUS, Z btfac gofo LoqD f incf, volcounter, r D€lay lx i Get 36
btf8a
volcounts€r,
0
atecf gotso
NewPwMDuty, LooP
f
RecalLcheck:
Bultoncorq)are RecalIB, bsf AppRurr goto LoqP
apDRuu
bcf
Lighlseek
bcf
r,ines€nsor
btsfEc
Objecls€nse
goto bsf
S+3 objectseuse
goto bcf
IJoop Objectsense
goto
IJooD
r.inesenEor LooI)
endllw btfaa goto
; Fu!.l Rang€ i ControL
i Reau[e r AOplication?
Enterch€ck
; Reslarl , ADplication?
Disable s€ehiag Disable g€trso!
Light liloale rJine
a i
,i*j
*?*
ToggLe Obj€ctsenge
:-.5
t Line g€n6or? I,inecheck t Stop Atry Plevious r ApDlication t Enable LighE t Seeking Moale t Disab].e objecE t S€eking uoal€ i Ena5le Line genaor
i:,-J
.:9
senaorch€ckl rnovf Pm.lcycL€,
Pll}l
Cycle
Sense? if unknown
i Disab Object uoale t s€eking
lJigbtseek
bsf gtoto
, Object i Retuln
t Enable object llofle ; seekiag
to objectsense
Loop
, t t t t t
MerruBtn. Bultoncdrpare llDPRun bcf
bcf
Fo:.warala
i Button i gtop Arry Plevious ,IDplication
LineCheck:
b€f
t ltoving
s1*
!4enuBtn,
bcf
100 mB
w
IJooD
& Right CbeckBulton9: r R€verao Bultoncdttr)er€ Buttong ' CheckvoLUp 2OO movln ; Rua for 200 ms llovecounte! mo'\^of novf NewPwMDutsY, !t PwuDuty novwf 0 bsf Dilection, t Movidg Back$tartla llurEleft bcf lUrnRight baf Plogram ApDRun bcf t Tura off Lightseek bcf t Eurn Off lJight t Seekiug goEo LooI)
Enterch€ck:
r Run for
to
w
0x03 STATus, z ObjSense
IJightsenae: incf
,fDCCycL€.
t
bcf
ADCCycle,
3
movf,
A.DCCycle,
w
btf,aE gotso movlw mo\rwf, baf,
STATgg, z A.DCCyclel b'00000001' A.DCON0 a.DCON0' GO
goto
lootr)
S e c t i o nT h i r t e e n Z i p Z a p s @R o b o t
? upalatse ADc? t Every 4lh Cyc].€
ADC , Run lhrough t Cycl€a i A.DcCYcIe = t (e.Dcqrc16 + 1) % 7
i Execut€ , Uachine
t Enable
ADC glate
:t!
'i| 1 :
;-.
LDC on RAO
, 3
ADC t Starl t ODeration
323
!!li
t i
hn
lLDccl,cIe]. xollw btfs8 golo rnovf goto
a tI I
Loop
3 ^ 2 STATUS, Z ADCCycLe4 e.DREgH, w
AItCCycle4: xorlw btfaa goto movlw moirwf baf goto
;
, i
Start
coodl Reafl
Gooal A.Dc Reaal, gave Ir€f! Valu€
A.DCValu€I.
4 ^ 3 STATus, z .B.DCcycIes b,00000101, A.DCONo ADCONo, cO
,
Enabl€
A.DC on RA1
ADC , Start , Op€ration
I.ooI)
.e.DCCycLe5. xorlw 5 ^ { btfss STATUS, Z golo aDcct'c1e6 tnovf ADRESII, w
ADCCycIe6: xorlw blfaa goto bsf
Badt alc t E.pect Value i Reaal, Ignole
Loop
6 ^ 5 gTATUg,
Z ADCCycLe? ADCONo, GO
i
.r$
ADCCycLeT: novf ADRESH, novwf goto ObjSeEae: movf
:,{
!t
r glart
eootl
Reaal
; Gooal ADC Reaal, Va1ue t Save Right
AIrcValueR lJoop
P$illcycl€,
w
anillw xorlw btfsa goco
0x03 1 STATSS, Z linesens€
cLrf
ObjFronlR
cllf cllf movf bsf movwf bcf bcf !!f movwf cllf bcf,
ObjFrontl ObjRear '!,r Obj ectPl{ll, S!!AmS. RPo PR2 ^ 0x80 STATUS, RPo STATUS, C Obj€ctPtcr4, w CCPR1L TIIRz PrRl, 1'!|R2IF
Ff
,.*.*
'J,, !d-r a"A ! -t
324
T2CON, TMR2ON
b8f bcf bcf,
STATug, RPo TRISC ^ 0x80, STASUS, RPo
t lPurn on a'ItIR2 for t objectE 5
, uDdla!€ object t se gor? r Every 4th Cycl.e
the , Cl€ar t Counters
;
setup
tIiIR2
Objects
PoRTC. 0 objFronlR, f PoRTC, 1 ObjFrontL, f PoR!!a, 3 f ObjRear, PrR1, !n4R2rF objloop
b6f baf
STATUS, RPo TRISC ^ 0x80,
bcf bcf
STATUS, RPo T2CON, TI|R2ON
bcf bcf bcf movLw
PFIonERIR PFrontr,rR PRearIR 30
subwf, blfsc bsf, movln aubwf btfac b3f movlw aubwf btfac b6f
ObjFrontR, !,r STATUS, C PFrontRIR 30 ObjElontl, w gtATus, c PFTonIIJIR 30 ObjRea!, w STATUS, c PR€ATIR
goto
lool)
PW!4CycIe,
5
Ptctil Outputs
Polllng
, ,
DiaabLe OutDu!
,
Tula
t
CLear Objec!
r Thirty t S€t,
PwM
off
IUR2
Tim€s
BiEa
f,o!
IJooD r Eitrisheal, r Aroundl Again
w
andlw xorlw btfsE golo
0x03 2 STATgg, Z oDeratinglogic
clrf
lJineFlontR
cllf trovf bgf movwf bef bcf fif rnovwf clrf bcf bsf
LineFronlL lin€PltlM, w STATUS, RPO PR2 ^ 0x80 STATUS, RPo STA!!US, C Lin€P$tl, w ccPRlL TMR2 PrR1, Tl'lR2IE T2CON, I'trlR2ON
bsf bcf bcf
STATUS, RPo TRISC ^ 0x80, sTATus, RPo
LineLoop: btsfEc incf btfsc incf btf6s
t Enal]le
t Loog Eere t objectsa
btfsc incf btfsc lncf btsfgc iacf btsfss goto
IJineSensa: r,ovf
3 t
:
baf
Obj Loop:
ADCCycle3: *lro!1!r btsfaa goto novf
goto
&rq
r B.pect Baat .e.DC i Reafl, Igrlole value
2 ^ L STATUS. Z ADccycLe3 A.DCONo, GO
.q.
F*-
1 STAfUS, Z Al)CCyc1e2 .eDRESll, nr
ADCCycle2: xorln blf,aB gotso bEf
nonwf
'*.-€
!
r upalate Line i Sedaora? t Evertr 4!h Cycle
, i
clear the Countsels
,
getuD
r Turn I.ine 4
t Enalcle
t Loop t Line PoRTc, 0 IrineFrontR, f PoRTC, 1 Lia€Flonll, f PIR1, ltrltR2lF
l , e 3 P I C @l ' C l l - JE x p e r i m e n t s f o n t h e E v i l
6enius
object
I'uR2
on TMR2 f,or
Pttu Output
He!€
Polling
gotso
IJinelJoop
bgf bsf bcf bcf
STATUS. RPO TRIsc ^ 0x80, { STATUS, RPo !2CON, T!|R2ON
bcf bef movlw
IJFToUtRIR IJFToatLIR 30
subwf btf,sc baf novlw Eublrf btfsc baf,
IJiDeFroutR, STATUS, C LFrontsRIR 30 lineFront!, STAfIUS, C LFronlLIR
gtoto
Loop
DisalcLe Turn
P9lM OutDut
off
T!lR2
clear
objecu
Thilly Set
Tines
Bits for
w
w
i i
Finiaheal, Loop Aroundl Again
ODeratsinglogic: IJogic Her6 (8 Per 32 **## - Put Opelating r cycleg) /Neeala set Plag i - Check "A99Reaet" Eo See if , **#* Application ia to be R€atartetl - Rdlote (!'tove or Stop) Direcl Control r **** ReaelE 'AppRunn Flag - Rdrole Control , **lt* aT.I "ADDReaetsT , #*## - Rdrot€ conurol "Reca11n gela
9roso
]JooD r Einisheat. t Alounal Again
Subloutineg t CoutrtLow: clrf Dlay CountsIJowlrooD: incf Dlay, f blfsc STATUS, Z goto CountlowDone soto $+1 gloto $+1 btfss RearIR goto Countlovrloop CounlLolrDo[e !
cllf
coutttsEighl,ooD : incf Dlay, f blfBc STATUS, Z goto CountHighDone goto s+1 goto s+1 btfac RearrR goto countEighloop countEighDone: novf Dlay, w subLw 35 btsfac sTATrts, c movllr aublrf
80 D1ay,
10 uE i counts, i! i Increments Low , Time signal t Clone Arounal? t Y€s, t Want
t Fini8heil,
i
Return
Gone Arountl?
t YeE, , Want
i
ReEurn Zero 10 Oycle IJooD
IJ€ss than
t Greate!
40?
than
79?
ro t Carry
eaal
Return Zero 10 Cycl€ Lop
in 10 us r Count, InclementE Eigh r Tirne Signal anat check
Dlay
I had a lot of trouble in this experiment(whichfigures,becauseit's the lastone) with the IR signalbeing too powerful. I was able to be successfulby carefully heatingthe heat-shrinktubing aroundthe bottompointingLED to the point wherevery little light was let out andwhite and black weredetected.Please checkthe CD-ROM and on my web page (www.myke.com) for updatedcodethat changesthe period PWM of the IR signalto decreasethe sensitivity of the line sensorsso they work better.Otherwise, you may wishto add a largepotentiometer(say10k) in seriesto seeif significantlyreducingthe current flowing throughthe IR LED helpsto better sensethe difference between white and black surfaces.
seh if
trYesn
i,1
l"t ;.{ t'ti i.-
1' I'.i *aj
For Consideration Whew!Although beinga lot of fun to work through, the ZipZaps hack wasa pretty intensive introduction to robotics.And a pretty goodintroductionat that.It is possiblehowever,that you might be questioningthis from a numberof perspectives, includingthe following: . .
The fragility of the robot The difficulty in addingthe new components precisely
. .
The ability of the robot to run only on flat, smoothsurfaces The apparentcomplexityof the software
.
What to do next
I like robotsthat are built like North Americancars built in the 1960s-ableto drive awayfrom a serious accidentwith nothingmore than chippedpaint.I am not trying to be facetious;chancesare your robot will drive itself off the tableyou are working on, andyou'll wishfor the samething.(Thisis a factor becausethere is no on/off switch due to my relying on the Zipzaps batteryfor power.)So rememberto chockthe wheels, andyou'll preventthe robot from goingoff on its own (it doesnot havethe power to successfully climb over at somepoint in time,you'll probaany obstacles).Yet, bly forget to do this and accidentallyleanon the remotecontrol.Despitethis dangerand a few broken wires when I was taking the PCB on and off the chassis,the robot held togetherdudng the development and during about 10 hoursof usewithout any problems.As a prototype,this robot is acceptablyrobust, but it is certainlynot sftongand resistantenoughto withstand the accidentsa commercial Droductwould needto withstand. This hackwould be much easierto perform if a custom PCB weredesisnedfor it. If surface-mount
5ectionThirteen Z i p Z a p s @R o b o t
325
frl
'J
technologywasused,then chancesare the custom PCB couldbe assmallasthe PCB that camewith the originalZipZaps (althoughsomekind of provision would haveto be madefor the IR TV remote-control receivers).The easeof buildingthe circuitrycould also be improvedby relocatingthe motor and steering driver transistorsfrom the cut-downZipZapsPCB to the robot PCB.I did not try this becauseI wantedto leavethe stockdriver circuitsintact,assumingthat they havebeenoptimizedfor the motorsand steering solenoidsused.A customPCB couldalsoreducethe fragility of the final robot. The car chassisand the all-or-nothingsteednglimit the surlaceson which it will run and how the robot works.I prefer working with differentiallydriven robotsthat canliterally turn on a dime.The very small turning radiusof the ZipZapschassisis aboutasgood asyou can expect,but still not asgood aswhat many robotsare capableof. Despitetheselimitations,the chassisandrobot are very usefulfor prototypingand shouldhelp you work throughthe sensorand software issuesof a larger,car-chassis-based robot. The softwareusedin this robot is not ascomplexas it looks.Hopefullyyou canseeitsprogression asyou work throughthe expedmentsand seehow relatively simplechangesresultin substantialimprovementsin capability.If I had presentedthe final softwarewithout any of the intermediatesteps,then I would agreeit is very complexfor somebodyto understandall at once. However,by goingthroughthe individualiterationsof the code,you shouldhavesomeappreciationof how complexsoftwareis built from a seriesof smallpieces. If you can't seeany way to usethis robot, then I suggestthat you spendsometime in your local library or bookstore,or on the Internet.Thereare literally thousandsof differentapplications(and methodsfor implementingthem in hardwareand software)that canbe usedasideasfor your robot.The Zipzaps robot will neverbring you a cold drink from your refrigerator, but it cansimulatethe actionsso you can createa larger,more capablerobot.Thereare alsomany
326
opportunitiesfor expandingthe capabilitiesof the robot,includingaddingmore or differentsensorsor evensomekind of object-capturehardware. On the positiveside,the robot is fast and tracksasif it were on rails.I would sayits speedand ability to movepreciselyis asgoodasor better than the odginal product.Although the car regularlyspinsout,this is not a desirabletrait in a robot.The extraweightof the prototypingPCB and the componentson it probably contdbutegreatlyto how the robot handles.I alsowas pleasantlypleasedby the batterylife of the final product;it seemsto be better than what the originalproduct had.This doesn'tseemquite possiblewhenyou considerthe variouselectricaldevicesaddedto the chassisaswell asits extraweight,which requiresmore power to move.It couldbe that the radio receiveruses a lot more powerthan the PIC MCU solution. Most important,this is a robot that you cando a lot with.The softwareis designedto make comingup with your own applicationcodeaseasyaspossible;the sensorsare continuallypolled by the basecodeand allow you lo simplyreadvariablesto find out the latestvalues.Similarly,to move the robot, it is simplya matter of writing to the appropriatemotor and steeringvariablesto affectany kind of movement.Finally,the remote-controlinterfaceallowsyou to initiate the operationof your codeand to stop it if it is not working properly.You canthen move the robot to a new locationto try something differentor in a newenvironment.It's actuallya nice basicrobot to experiment with. Like this book,the ZipZaps robothack shouldhave givenyou new insightsinto the PIC MCU, how it is interfaced,and how it is programmed.It is now up to you to take this knowledgeand go forward with your I'm looking forward to seeingwhat own experiments. you comeup with.And if at sometime the book's moniker appliesto you,and you usethe skills and knowledgegainedftom this book to take over the world,pleaserememberwherethoseskills andknowledsecamefrom.
l , a 3 P I C @l ' l C UE x o e r i m e n t s f o r
the Evil
6enius
tntrex
$,163 * (seemultiplication) + (seeaddition) - (seesubtraction) / (seadivision) ; (seesemicoloncharacter) & (AND),35 " (bitwiseXOR),35 = (equalssign),38,4G41 = = ( e q u a l tso s l a t e m e n t ) . 3 8 . 4 G 4 1 << (left shift operalor),L74 % (modulusoperator),34 -' (negation),35
I (oR),3s + + (unaryincrement)operator,48 I (bitwise[inclusive]OR),35 & (bitwiseAND), 35 - (bitwisenegation),35 ^ (bitwiseXOR),35 ! logicaloperator,35 [ ] (braces),39-40
A AC (alternatingcurrent),L54 accumulator,l64 Active Surplus,12 function) ADC function (seeanalog-to-digital addition(+): in assemblylanguage,1.6U1"69 assignmentstations,34 repeated,multiplicationas,280 addresses: language. 83.84 C programming for computed gotos,208 for memories,18 PICC Lite compiler,83,84 161-163 for programmemory(assembly), addressing: anay,73 assemblylanguage,173-175 bank (assemblylanguage),173-175 alphanumericLED displays,124 alternatingcurrent(AC), 154 AmericanNational StandardsInstitute(ANSI) standards,29
(ADC) function: analog-to-digiral for multiple devices,238-239 Ptc1.6F684,93-96 AND (&),35 AND gate,189-190 Animate icon,20 29 ANSI standards, application code,137-138,187(Seealso specific applications) applicationmainline/entryfunction (C), 82 applicationmainline/entrypoint (PICC Lite compiler),82 applications: linking multiple files into, 187 readability of, 67-68 tangiblereasonsfor, 89 architectures: computer,l8-19 PICl|'{{.CU,25-26 arithmeticoperations: basic,3,t-35 Boolean,35,36 order of, 3,t-35 with, 201-203 16-bitvalues/variables (Seealso specificoperations) T3 arrayaddressing, arraydimensions: 83 C programminglanguage, PICC Lite compiler,83 array variables,declarrng,182 arrays: (assembly),182-183 defining/implementing read-only (assembly),20&-210 ASCII bytes,convertingbyte into,289-291 T9 ASCII characters, ASCII dataformat,32 ASCIIZ srring,79,80,29+296 6, 159-185 assemblylanguageprograrnming, additioninstructions,168-169 file and basicdirectiveq160-161 asmTemplate.asm 173-175 bank addressing, ol 184 basicparts/sequence bit instructions,175-176 bit skip instructions"177-178 bitwiseinstructions,167-168 bu.bblesort,292-294 conditionalexecution,178-180
Index
327
assemblylanguageprogramrntng(Continuecl) converting byteq 289-291 decfszlooping, 180 definingvariables,165-167 defining/implementing arrays,182-183 division of 16-bit value by eight-bit vahte,28?-284 eighrbit multiplication with 16-bitprodtct,230-282 encrypting/decrlptingASClIZstring,294-296 even parity valuesfor bytes,29l-292 generatingFibonaccinumbersequence,297298 largest common factor of two eight-bit numbers, 298-300 loading/saving contentsof WREG,16+165 programmemoryaddresses, 161-163 sortinglist of 10 eight-bitvafues,292-294 squareroot of 16-bitnumber,28G288 squaringnumber using finite difference theory 28+286 strangesimulatorresults,170 subroutines, 181 subtraction instructionrlTl-t72 assemblylanguageresourceroutines,187-220 circularbuffen,212-213 conditional assembly,197-199 datastacks,210-212 defines,194-196 high-level programmng,Z\S-2j1 implementingC "switch" statement,191-194 implementingread-onlyarrays,208-210 logic simulation using PIC16F684,188-191 macroq 199-201 reading/r:r,ritingEEPROMdatarnemory,2l4-276 16-bitvalues/variables with arithmeticoperations, 201-203 universaldelaymacro,203-205 assignmentstatement n C,32-33 macro for,206-207
B
t tt /tt
s H
backdriving,3o5 bank addressing(assembly),173-175 basicarithmeticoperations,3,[-35 batteries,65 binaryformat.32 binarynumberoutput (with PICkitl start kit LEDs), 5G58 binary operators: C programminglanguage,84,85 PICC Lite compi1er,84,85 binary searchalgorithm,98 binary values,35-36 bipolar stepper motor control,765-268 bit instructions(assembly), 175-176 bit reset(bcf),175
328
bit set (bsf), 175 bir skip instuctions (assembly),177-178 bitwise instructions (assembly),167-168 bitwiseoperators(C),35-36 BOD circuit (seebrownout detect circuit) Boolean adthmetig 35,36 Boolean operationq bitwise, 167-168 BOR(seebrownoutreset) bottle-sort algorithm,292-294 braces({ }),39*40 breadboard wiring: BS2simulator,225 for dual seven-segment LED displaycircuit,lzz for AND gate,189 keypad-based BS2simulator,231 LCD1,777 for object detectionh^nging,Z4s for PIC MCU, 64-66 for potentiometerread circuit,110 sewo contol.2:72.273 for testing clocking optiong 107 for ZipZaps powersupply,306,308 breakstatement,44 breakpoints,20,22 bro$nout detect(BOD) circuit,91-93 brownoutreset(BOR),62,91-93 BS2 interface: commandssupportedby PIC16F684IRtag MCU,253 controlling multiple motors with PWM atd,264-265 keypad,23V23l and,servocontrol,ZT7-278 two-seworobot basewith,277-278 user,224-29 bubblesort,73-74,292-294 buffers, circular,2l2-213 built-in serialinterfaces(UARTs),222 button inputs: basic,58-59 debounci.ng,59-61 byte(s): converting into three decimal,two hex, or eight binaryASCII bytes,289-291. producingevenparity valuesfor,2gl-292
d \, C (seecarry) C programminglang1Jage,6,2:749 addresses, 83,84 applicationmainline/entryfunction,82 applicationsof,27 alnaydimensionq83 assignmentstatements,32-33 binary operators,84,85 bitwiseoperators,35-36
l , e 3 P f C @i l C U E x p e n i m e n t s f o n t h e E v i l
6enius
button read and LED output in,59 characterstrings,T9-81 complexstatements, 48-49 conditionalexecutionusingif statement,3g-41 conditionallooping,45-46 andconfigurationfusebits,82,83 constantformatting,31 32 constantvalues,71 constants,S4 dataaccesswith,27 datadeclarations, 83 datatypes,29 30 decisionstructures,84, 85 defines,Tl-72 definingfunctions,S2 directives,86 expressions, 33-35,84 functions,69-70 globalvariables,71, 83 goto Label statement,S5 implementingC switchstatementin assembly language,191-194 library functions,Sl 82 lists.76-78 local variables,7071,83 logicalexpressions, 37-39 looping,S5 macros,TlJ2 mathematicaloperators,s4 microcontrollerapplicationsin,137158 model railwayswitchcontrol,153-155 nestedconditionalstatements,4l+3 null statement,4S-49 PC operatingstatusdisplay,15G158 PIC MCU "piano,"151-153 pointers,27,7G78,83 PumpkinLED display,138140 reaction-timetester,140-142 and readabilityof programs,68 return statement,36 Rokenbok@monorail/trafficlights,143-146 seven-segment LED thermometer,146-150 singledimensionalarrays,83 for statement,46-49 strings,S3 structures, 75-76 subroutines,6g switchdecisionstatement,43-44 switchstatement,85 unions,76 values,83 variablearrays,7374 variabledeclarationstatements,28-29 variabletypes,84 CadmiumSulfile(CDS) cells,238 call instruction,l62 cannedoscillators,10G108
carry (C), 168,169,171 casestatement,44 cblockdirective,161,,766,1"67,201, CCP: generatingPWM signalsusingTMR2 and,111-114 I/O pin resistancemeasurements using,109-111 CCP PWM, DC motor driven usingpotentiometer control and,257-260 112,113 CCP1RLregister, CD-ROMs (in starterkit), 1 CDS (CadmiumSulfile)cells,238 cFlash.c: simulating,in MPLAB IDE.20-24 wiring circuit,65-66 chardata type,33 charunsignedvariables,188 characterstrings: C programminglanguage, T9 81 encrypting/decrypting, with substitutionalgorithm, 29+296 circularbuffers,212213 clearthe WatchdogTimer (clrwdt) instruction,188 clippedsignal,235,236 clocks: comparingoscillators,106-109 andfunctionsin instructioncycle,203 PIC16F684,16 resistor-capacitor, 95 (Seea/sotimers) clrwdtinstruction,188 code,formatting,68 coi1,255,256 comments,31,68, 160 commoncathode/anode configuration,120 commonfactor of two eight-bitnumbers,298-300 commonregisters,173 comparators: for IR surfacesensor,240,241PIC16F684, 96-99 comparingclock oscillators,106-109 completeresetsolution(PIC16F684),62 34,36 complexexpressions, computedgoto,208 computers: architectures, 18-19 127 asrandomnumbergenerators, conditionalassembly: assemblylanguageresourceroutines,197-199 macrousing,20G-201 conditionalexecutionstatement: assemblylanguage,178-180 nested(C), 41-43 usingif statement(C), 39-41 with,202 conditionaljumps,16-bitvalues/variables conditionallogic,operatorsfor,36 conditionallooping(q,a5a6 _CONFIG directive,l-61-,205
Index
329
l,-l t4 ,.- , {'t :.i.j
configuration fuse bits: and C programminglanguage,82,83 parameterspecifications, 17 PICC Lite compiler,82,83 and unwanted functions, 100 configurationword (PIC16F684),1G17 constantformatting (C)3\a2 constantvalues(C programminglanguage),71 constants: C programming language,84 PICC Lite compiler,84 contextregisterq134 conventions,1.1 counterg29,57 for longer delays,203-204 program,162 sweepgenerator,94 crysral(PIC16F684),108 Cygwin,157,158
D
M t2i
{)
d H
data,storing(seestoringdata) data access(C),27 datadeclarations: C programming language,83 PICC Lite cornpiler,83 data encr)?tionstandard(DES),294 data segments, 19 data sizeq32 data stacks,210-212 data types,29-30 (Seealso spectfictypes) DC (seedigit carry) DC motor control,255-256 with simpleTMR0 PW\11,261-263 usingCCP PWM andpotentiometercontrol, 257-260 deadtime executioncycles,137-138 debouncing: button inputs,59-61 multiple microswitch,237-238 Debtgger,2I,24 debugging: in assemblylanguage,159 difficulties with, 36 pointersin,77 decfszlooping, 180 decirnal,convertingbyte valueinto,289,291 decimalformat,32 decisionstatements,switch (C), 43-44 decisionstructures: C programminglanguage.84. 85 PICC Lite compiler,84,85 declarationstatement: for functions,69 macrog199
330
declaringvariables: anay,187 in assemblylangua9e,765,166 and computer architecture,19 in PICC Lite compiler,28 definelabel,71, 72 defines: assemblylanguage,194-196 C programming language,71-:72 conditional assembly,197 definingarays (assembly),182-183 defining functions: C programming language,82 PICC Lite compiler,82 definingvariables(assembly),165-167 delays: long timer delaysusingTMR1, 10+105 PIC MCU,53-54 shorttimer delaysusingTMRO,101-102 universal delay maqo,203-205 DES (dataencryptionstandard),294 developmentPC,interface to, 13 Digi-Key, 12 digit carry (DC), 16UL69, 17L digital logic,117-119 digital multimeter(DMM), 134 digital thermometer, 14G1-50 digitally proportional signal,272 DIP sockets,51 direct load (movf) instruction, 164 directives: assemblylanguage,16L-1-63 C programming language,86 PICC Lite compiler,86 (Seealso specificdirectives) disassembly listing,190,191 distance-range sensors: IR object-rangingsensor,247249 ultrasonic,249-250 division(/): of 16-bitvalueby eighrbit value,282-284 assignment stations,34 asrepeatedsubtraction,282,283 DMM (digitalmultimeter),134 do-it-yourselfIR objectsensors, Z3-246 dot-matrixLED displays(LED matrix), 124 double float (floating point) variables typeE30 do/untilstatement,46 dual in-line chip package(DIP) socketq51 duty cycle,111
E ECC (error detection/correctcodes),292 ECCP module (seeEnhanced Capture/Compare/PWM module)
l , e 3 P I C @l t C U E x p e r i m e n t s f o n t h e E v i l
6enius
EEPROM memory(seeelectricallyerasable programmableread-onlymemory) EEPROM read,214 EEPROM write,21+216 eighlbit numbers: eight-bitmultiplicationwith 16-bitproduct,28G-282 largestcommonfactor of two, 298-300 eightbit values/variables: bubble-sortinglist of,292-294 divisionof 16-bitvalueby,282 284 saving16-bitvaluesas,32 electretmicrophone,235 electricallyerasableprogrammableread-only (EEPROM) memory,19 reading/writing(assemblylanguage),214-216 storinghetrievingdatawith,114-115 emulators.24.25 ASCIIZ string,29,l 296 encrypting/decrypting ENDC directive, 161 endingapplications(PIC MCU), 63-64 EnhancedCaptureiCompare/PWM(ECCP) module,104 Capturemodeol110-111 PWM generatorfunctionin, 111-114 equals(: ) sign,38,40-41 equalsto (= =) statement,38,4041 equate(equ) directive,166 error detection/correct codes(ECC),292 evenparity values,for bytes,291292 execution: assemblylanguage,178-180 conditional,lTS-l8o expressionstatement,32 Cprogramminglanguage,33-35,37-39,84 logical,37-39 (PICC Lite compiler),84 expressions
E' fanout,118 Fibonaccinumbersequence,generating,29T-298 file narnes,67 file registers,19,164 fill areas(PCB),265 finite differencetheory,squaringnumberusing, 284 286 first,outside,inside,last(FOIL), 281 flag variableq29,30 Flash.c: Build Information for,7 loading,6 250 flight time (ultrasonicsignals),249, float (floatingpoint) variablestypes,30 floating-pointoperations,149-150 floodareas(PCB),265 FOIL (first,outside,inside,last),281
folders,6T for statement: C prograrnminglanguage,46-49 in cFlash.csimulation,2l formattingcode,rulesfor, 68 full H-bridgecircuit,256:258 full stepping,266 full-bridgeoutput forward mode (PWM generator), 113,714 functions C programminglanguage,69-70 declarationstatementfor,69 defining,PICC Lite compiler,82 defining(C),82 recursive,70,297 unwanted,100 written asmacros,200 (SeealsospeciJic lunctions)
G globalinterruptenable(GIE) bit,135 globalvariables(C),71,83 goto instruction,162,208 goto Label statement: C programminglanguage,S5 PICC Lite compiler,85 graphicLCDs,126
H halfadder,291,292 half H-bridgecircuir,256,257 half stepping,266 Harvard architecture,18 19,208 H-bridgecircuits,256,257 for dual DC motor,264 tl.256-258 ha1f,256,257 headerblock,6T-68 hex files,19 convertingbyte valueinto,289291 hexadecimal, hexadecimalformat,32 HIGH directive,201-202 highJevelprogramming: in assembler,205-207,279 assemblylanguagevs.,159-160 HT:Soft PICC Lite compiler,1 4,6,7 83,84 addresses, advantages of,28 applicationmainline/entrypoint,82 array dimensions,83 assemblylanguagecodefor,187-188 binaryoperators,S4,85 capabilitiesof,28
Index
331
.. .
III-Soft PICC Lite compiler (Continued) codeproducedby,28 configuration fuse bits, 82,83 constants, 84 data declarations, 83 data types,29-30 decisionstructures,84,85 declaringvariables,28 defining functiong 82 diectives, 86 downloading/installing,2-4 expressions,84 floating-point capabilities ol 288 goto Inbel statement,85 interrupts,135-136 library functiong 8G88 looping,85 macroq 87-38 mathematicaloperators,84 MPLAB IDE integrationwith, 28 pointers,83 pragmaoptions,86 return statement,86 singledimensional arrays,83 specifying,6 stringq 83 switchstatement,85 variabletypes,84 variablesinsidefunctions,83 while loop,46 HT-Soft web site,2
I
X (, €
c
H
ICE (in-circuitemulator),25 icons,10-11 IE (interrupt enable),135 IF (inlerruptrequestflag)bits.135 if directive, 197 if statementfor conditionalexecution(C),3941 immediate load (movlw) instruction, 164 immediate values/numbers,162 implementingarrays(assembly),182-183 incfsz instruction, 180 in-circuit emulator (ICE), 25 includedirective,161 indexregister,182 indexedaddressing, 73,182 lnouctor (collJ.z)), z)o infrared(IR) remotecontrol: for object detection,243-246 f or ZipZaps@rob ot, 37U317, 31G377 infrared(IR) sensors: do-it-yourself object sensorq243-246 line-following (ZipZaps@rob ot), 32(1325
332
objecfdetection(ZipZaps@ robot), 318-319 object-ranging sensor,247249 robot IR tag,251-253 surfacesensors,239-241 input mode (I/O pn),14,33 input/output (I/O) pins: allocationof,230 functions ol 14 and LEDs, 13
Prc16F684, 14-16 resistancemeasurements usingCCP,109-111 sharing,230 instruction cycleg21 instructions,160,216-218 instrumentinterface (PlC MCU ), 23L-234 int dataR?e,29,30 interfaces,119-136 debugger,25 driving seven-segmentLED display directly from Prc1.6F684,1L9-rZ1 instrument,PIC MCU,237-234 keypad,PIC MCU BS}Z3VZ37 LCD display,12L128 LED matrix displays,724-176 multiple seven-segment LED displays,121-123 of PICkitrM 1 starter kit to PC, 13 producingrandomnumbers,128-129 sensor,222 SharpGP2D120rangingobject sensorE242-243 switchmatrix keypadmapping,131-134 two-bit LCD display,729-730 user,PIC MCU 852,22+229 interrupt enable(IE), 135 inteffupt requestflag (IF) bits,135 interruprs,101,134-136,239-241I/O pins (seeinput/output pins) IR opto-interrupters,239-24t IR remote control (seeinfrared remote control) IR sensors(seeinfrared sensors) IR switchOpro-NPN,240
J Jameco,I2 jumpEconditional,202
K k (thousands),11 keypad: BSZ interface,23F231. switchmatrix keypadmapping,131-134 Kirchoffs Law, 154
l , e 3 P I C @l ' C l l - JE x o e r i m e n t s f o r
the Evil
6enius
L labels, 16,162 addressvaluestbr, 162-163 for conligurationword bit, 16 declaredwith variabledirective,198 numericvalueassociated with,71 lastin lirst out (LIFO) memory,2l LCDs (seeliquid crystaldisplays) LDRs (seelight dependentresistors) LED matrix displays,I24126 LEDs (seelight-emittingdiodes) left shiftoperator(<<),174 LFSRs(seelinear feedbackshift registers) libraries: C run{ime, 81 and data types,30 library functions: C p r o g r a m m i nl ag n g u a g e . 88li PICC Lite compiler,8G88 L I F O ( l a s li n f i r s to u t )m e m o r l2. I light dependentresistors(LDRs), 143,1421 for light sensors, 238-239 ZipZapsrobot,317-318 light following (ZipZaps@ robot),318 light sensorq238-239,317-318 light-emitting diodes(LEDS),1,2 alphanumericLED displays,124 binary numberoutput using,56'58 driving seven-segment displaydirectlyfrom PIC16F684, 119-121 LED matix displays,12+126 multipleseven-segment displays, 121-123 organizationol, 13-14 PC operatingstatusdisplay,156 158 Pumpkin LED display,138-140 sequencing, 55-57 seven-segment LED thennometer,146-150 simpleprogramto flash,58 limit checking,2ll linear teedbackshift rcgisters(LFSRs),138-40 line-followingsensors, IR (ZipZapsltrobot),320-325 Linux, 1 liquidcrystaldisplays(LCDs),120,12G130 list directive,160-161,220 lists(c), 76-78 literal values/numberq 162 littleendian,201 (C),70 71,83 localvariables logarithmfunction,150 logic: conditional,36 digital,117 119 simulation, usingPIC16F684, 188 191 (C),37 j9 logicalexpressions
logicaloperator(!), 35 longtimerdelaysusingTMR1, 104-105 loop incrementstatements, 46 loop testexpression, 46 looping: C programminglanguage, 85 conditional(C),45 46 decfsz(assemblylanguage),180 PICC Lite compiler,85 relativeaddressfor,203 TMR1 vs.for loop,105 LOW directive,201-202 L293D chrp.264265
M M (millions),l1 11 F (millionths), m (thousandths), 11 machinedreceptaclesocket,51 maclos: assemblylanguage,199-201 tbr assignment statements,20620l C programminglang\age,7LJz OPERATE,2O5 207 PICC Lite compiler,87-88 TimeCheck,316 universaldelay,203205 usesof, 199-200 mapping,switchmatrix keypad,131-134 mathematicaloperators: C programminglanguage, 84 floating-pointoperations,149 150 PICC Lite compiler,84 matrix LED displays,12+126 MAX 756step-uppower supply,305306 _MCLR operation(PIC MCU), 61-63 MCU (seemicrocontroller) measurements, 11 memory: EEPROM,1t4-115 LIFO, 210 PIC MCUs,25 PIC16F684,18 19 program,addresses for, 161-163 memoryspace,18 metricsystem,11 MicrochipPIC@microcontrollers(PIC MCUs), 1-12 basicbuttoninputs,5859 basicdelaysapplication,53-54 binarynumberoutput usingPlckit 1 starterkit LEDs,5G58 BS2 keypadinterface,230231 BS2userinterlace,22+229 configurationparametersof, 16
Index
333
Microchip PIC@microcontrollers(Conrlnaed) configuring,6 debouncingbutton inputs,59-61 electronicsPCB (ZipZapsorrobot),307-309 endingapplications,63-64 familiesof, 25 instrumentinterface,237-234 _MCLR operation,6l 63 parameterwords,16 pafi numbersfor,2+25 partsrequiredfor wiring on breadboard,64-66 PCsvs.,18 "piano,"151-153 PIC12F675,1, 10 PICI6F684(seePIC16F684) power supply(ZipZaps@ robot),305-306 recommendations for,26 sequencing PICkit 1 starterkit LEDS,55-56 turning off power,14 wiring cFlash.ccircuit,65-66 MicrochipPICkitrM1 starterkit,1+,10,11 binarynumberoutput usingLEDs,56-58 contentsol 1-2 icon for, 11 machinedreceptaclesocketmodification,51 ordering,1 organizationof LEDs, 13-14 PC interface,13 potentiallynegativeissueswith,13-14 sequencingLEDs,55-56 simpleLED flashapplication,5 8 testcircuit,13 turning off power,4 USB port liability,4 ZIF socketaddition,5l-53 Microchipweb site,4 1l,137-158 (MCU), microcontroller MicrosoltWindows,1, 11 microswitchdebouncing,multiple,23T-238 millions (M), 11 millionths(pt),11 model railwayswitchcontrol,153-155 modulus(%) operator,34 monorail,Rokenbokcr, 143-146 motor control,255 278 bipolarsteppermotorcontrol,265-268 controllingmultiple motorswith PWM and BS2 rnterface,264-765 DC motor controlwith simpleTMR0 PWM, 267263 DC motor driven usingCCP PWM and potentiometercon1rol,257-260 multiple servocontrol softwarestructure,Z74276 radio-controlmodelservoco\tro1,272274 two-seNorobotbasewithBS2interface,zTT-z18 unipolarsteppermotor control,269 271 ZipZaps@robot,3lL131.2
334
MouserElectronics,l2 MPASM@, 159,161-163 conditionalassemblydirectivesin, 197 directives,216,218-220 macros,199 MPLAB@integrateddevelopmentenvironment (IDE),1--:7,9-I2 asdevelopmenttoo1,279 downloading/installing,4,5 screenshotsof, 11-12 simpleprogramto flashLED,5-8 simulatingcFlash.c,20-24 simulatortool,10,70-71 sourcecodecompilingby,187 tutorial for, 2 upgradesol 1 verslonsof,12 multidimensionalarrays,74 multiple assignment statement,33,35 multiplemicroswitchdebouncing,23T-238 multiple servocontrolsoftwarestructve,214 276 multiplication(x): assignment stations,34 eight-bit,with 16-bitproduct,280-282 asrepeatedaddition,280
N names,variable,29 naturallogarithm,150 negation(-),35 nestedconditionalstatement(C), 41 43 nestedsubroutines, Tl Newton'smethodof zero finding,287 non-return-to-zero(NRZ) protocol22\223 nonvolatilememory,114 NOP0; statement,53-54,60,188 nopstring,161 NRZ protocol(seenon-return-to-zeroprotocol) null statement,32,48-49 numbers: ASCII valuesas,289 eight-bit,findinglargestcommonfactorof,298-300 eight-bitmultiplicationwith 16-bitproduct,280-282 generatingFibonaccinumbersequence,29T29S immediate/literal, 162 16-bit,finding squareroot of,28G288 squaring,usingfinite differencetheory,284286
n \-' objectsensors: do-it-yourself,243-246 interfacingto SharpGP2D120,242243 IR object-rangingsensor,247-249
l , a l P I C @l l C U E x o e r i m e n t s f o r
the Evil
Genius
ultrasonicdistance-rangesensor,249-250 ZipZapsorobot,318-319 Ohm'sLaw,154 one-timeprogrammable(OTP) parts,197 Ontario Ministry of EducalionCurriculum Guidelines for ComputerEngineering,9 op-ampcircuit,235 open-collectoroutput,119 open-drain output,11g OPERATE macro,205-207 operatingstatusdisplay(PCs),15G158 OperationResult,168 operational-amplifier(op-amp)circuit,235 OPT (onetime programmable)parts,197 OPTION rcgister,101 opto-interrupters, 239-241 OR (l) operator,35 order of operations,34-35 org directive,161 oscillators,clock,10G109 output controller,ll2 output mode (I/O pin), 14 output sink currents,118
p p (trillionths),11 pagesize(programmemory),163 ParallaxBASIC Stamp,100 parameterstrings,Tl parameterwords,16 parasiticpower,66 parity values(for bytes),29l292 part numbers,24-25, 197 PartsBin icon,11 partssuppliers,12,240 PCB (seeprinted circuit board) PCL register,208,209 PCLATH register,208,209 PCs: operatingstatusdisplay,156-158 PIC MCUs vs.,18 PC/Simulatoricon,11 phototransistors(PTs),240,247 "piano,"PIC MCU, 151-153 PICMCUs(seeMicrochipPIC@microcontrollers) PIC12F675,1,10 PIC16F684,1,10, i3-26 ADC function,93 96 architecture0126 brownoutreset,62,91-93 builtin functions,8990 built-in hardwarefeatureE90 comparatoroperation,9G99 compadngclock oscillators,10G109 completeresetsolutionfor,62
configurationword,16-17 damagefrom plugging/unplugging, 14 driving seven-segment LED displaydirectlyfrom, 119-12I generatingPWM signalsusingCCP andTMR2, 111 114 I/O pins,14-16 logic simulationusing,188-191 longtimerdelaysusingTMR1,10,+ 105 short timer delaysusingTMRO,101-102 simulatingcFlash.cin MPLAB IDE, 20-24 stodng/retrievingdata usingEEPROM memory 11+115 timed I/O pin resistancemeasurements usingCCP, 109-111 TMR0 prescaler,102-103 variablememory/registers/program memory,1s 19 watchdogtimer,99 100 PICC Lite compiler(s??HT-SoftPICC Lite compiler) PICkitrMl starterkit (seeMicrochipPICkitrM1 starterkit) pin throughhole (PTH) chips,65 polnters: andASCII strings,T9 C programrninglanguage, T6 7{i,83 ICC Lite compiler,83 Polaroid6500ultrasonicranger,249-250 pollingintervals,222 PORT bit, 1,+16 positiveactiveread,negativeactivewrite (R/W), 127 pot read,110 potentiometer,25T-260 power: AC, 154 with batteries,65 parasitic,66 turning off,14 for ZrpZapsrobot 305-306 pragmaoptions(PICC Lire compiler),86 preprocessor, Tl prescaler,TMRo,102 103 PrimeCheckfunction,T0 Princetonarchitecture,18,19 printed circuitboard (PCB),1,2 fill/flood areason,265 ZipZaps@,304,307-309,372 problems,resourcesfor, 300 programcounter,162 programfiles,lg programmemory,18 pagesizeol 163 specifyingaddresses for (assembly),161 163 programmerPCB,1,2 programminglangLrages,zT (Seealsospecifrc languages) programmingproblems,resourcesfor,300
Index
33s
PTH (pin throughhole)chips,65 PTs(seephototransistors) pulsewidthmodulation(PWM): DC motor controlwith CCP PWM and potentiometer,25T-260 DC motor control with simpleTMROPWM, 267-263 generatingsignalsusingCCP andTMR2,7|7-774 for motor-speedcontrol,256 multiplemotorscontrolwith BS2interfaceand, 264-265 PumpkinLED display,138-140 PWM (seepulsewidth modulation)
O E quotient,282,284
E r\ Radio Shack,12,302 radio-controlmodelservoconftol,272-274 randomnumbers,producing,128 129 rangingobjectsensors, interfacingto,242-243 RC clock,95 RC oscillator,107,108 rctimefunction,109,110 reaction-timetester,I40-1-42 readabilityof programs,31,67-68,159 readingEEPROM datamemory,21+216 read-onlyarrays(assemblylanguage) .208-270 real-timeclock (RTC) variable,316 recursivefunctions,70,297 recursivesubroutine,181 reglsten: accessing,33 banksof 173-175 CCP1RL,112,113 common,173 context,l34 index,182 involvedwith ADC,94-95 LFSRs,138-40 monitoringvaluesof,21,2324 OPTION,101 PCL,208,209 PCLATH,208,209 PIC16F684,18,19 shadowed,173 STATUS,164,168-L69,173-175,177 T1CON,104 WREG (assemblylanguage),164-165 remainder(division).282,284 remotecontrol:
336
IR, ZipZaps@ robot,310-311,31G317 TV receiverfor object detectron,243244 RequiredPartsicon,10-11 requirementcontinuum,280 reset: address(assemblylanguage),161 bits indicatingreasonsfor,63 -MCLR operation,61-63 PIC76F684,62.9L-93 WDT, 100 Reseticon.20 resistance: in DC motors,255 I/O pin, measurements usingCCR 109-111 thermistor. 148-.149 (RC) clock,95 resistor-capacitor (RC) oscillator,107,108 resistor/capacitor resistors: light-dependant, 143,144 single-inlinepackage,139 resonator(PIC16F684),108 retrievingdata (EEPROM memory),114-115 retum statement(PICC Lite compiler),86 robots: IR tag,251-253 radio-controlmodel seryoconftol,272-274 two-servorobot basewith BS2interface,277278 (SeealsoZipZaps@-based robots) Rokenbok@ monoraiVrrafficlights,143-146 RTC (real-timeclock) variable.316 run arroq 20 Run icon,20 21 RJW (positiveactiveread,negativeactivewrite),127
s segments,l8 (BASIC).44 selectstatement self-contained operutron,Zl4 semicolon(;) character,32,68,160 sensingoperations(polling),222 sensors,221-253 do-ityourself IR objectsensors,243-246 environmentalparameterswith,222 interfacingto SharpGP2D120rangingobject sensors,242243 IR objectrangingsensor,247249 IR surfacesensors.239-241 light,238-239 line-following(ZipZaps@ robot),320-325 multiple microswitchdebouncing,23T238 (ZipZaps@ robot),318-319 object-detection PIC MCU BS2keypadinterface,230-231 PIC MCU BS2userinterface,224229 PIC MCU instrumentintedace.23l-234
l , P 3 P I C @1 1 ( l JE x p e r i m e n t s f o r
the Evil
6enius
polling intervals for, 222 robot IR tag,251-253 sounddetection,235-237 ultrasonic distance-rangesensor,249-250 sequencingPICkit 1 starter kit LEDS, 55-57 servocontrol: multiple servo control software structve,2iT4-276 radio-control mod el,2l72-274 two-servorobot basewith BS2 interface,2iT7-278 seven-segment LED displays: driving directlyfrom PIC16F684,119-121 multiple,121-123 thermometer,146-150 SFRs (seespecialfunction registers) shadowedregisters,173 SharpGP2D120rangingobjectsensorS242-243 short timer delaysusingTMRO (PIC16F684),L07-102 SI (SystemInternationale),11 simulation: BS2 interface,22+229 of cFlash.cin MPL AB LDF,,2U24 logic simulationusingPIC16F684,188-191 prior to burning prograrns,20 simulators: MPLAB IDE, 10,7V71.,170 sendingservopositiondatafrom,278 strangeresultswith, 170 singledimensionalarrays: C programming language,83 PICC Lite compiler,83 singleequals(:) sign,38,4G41 single-dimensional arrayq73J 4 single-inlinepackage(SIP) resistor,139 single-outputmode (PWM generator),114 singly linked lists,7H8 SIP (single-inlinepackage)resistor,139 16-bitnumber,finding squareroot ol28G288 16-bitvalues/variables: with arithmetic operations,201-203 division of by eight-bit value,282-204 int data type,30 programming flexibility with, 201 savingin eight-bit variables,32 sleepstatement,100 slottedIR opto-interruptery240 SMT (surface-mounttechnology),304 sobrietytester,140-142 sound input recognltlon, 235237 sourcecode,1 specialfunctionregisters(SFRs),19,164 spoolingfunction,210 squareroot of 16-bitnumber,finding,28G288 squaringnumber usingfinite differencetheory,284-286 stackmemories,18 stacks,data,Z1U212 StandardC values,29
state machine,95 STATUSregister,164 and additioninstructions,168-169 and bank addressin 9,173-175 andbit skip instructions,177 steeringcontrol (ZipZaps@ robot),311-312 StepIn icon,20 StepOut icon,20 StepOver icon,20 steppermotor control: bipolar,265-268 unipolar,269271 steppermotors,266 step-uppower supply,305 stimulusfunction,20,61 Stimuluswindow,61 Stopwatchfunction,20,23,54 storingdata: ctctular bfifer,27311-4 dat^ stacks,27}-ZIz usingEEPROM memory(assembly), 214-216 usingEEPROM mernory(C), 11,t-115 strings: C programming language,83 character(C),79-81 labels,162 PICC Lite compiler,83 structlanguagestatement,75 structures(C),75-76 subroutines: assemblylanguage,161,181 C programminglanguage,69 nested,71 wdtten asmacros,200 substitution algorithm, encrypting/decrypting ASCIIZ string with, 29+296 subtraction( -): in assemblylanguage,777-772 assignmentstations,34 repeated,divisionas,282,283 Suprernetronic, 12 surface-mounttechnology(SMT), 304 sweepgenerator,94 switchcontrol (modelrailway),153-155 switchmatrix keypad,mapping,131-134 switchstatement: C programming lan guage,4344, 85 C switch statement in assemblylanguage,IgT-7g4 PICC Lite cornpiler, 85 SystemInternationale(SI), 11
T Tab ElectronicsBuild Your Own Robot Kit, 301-302 Thb Electronics Sumo-Bot, 25I-253, 307-i02
Index
337
,{ !-{
ptu
X
task-controlsoftware(Zipzaps@robot),313-316 Templatefile,160-161 testcircuit (PICkitrM1 starterkit), 13 thermistors,148-149 thermometer,seven-segment LED, 14G150 (k), 11 thousands thousandths(m), 11 TimeCheckmacro,316 timed I/O pin resistancemeasurements usingCCP, 109111 timers(TMR): DC motor control with simpleTMR0 PWM, 26L-263 generatingPWM signalsusingCCP andTMR2, 1.L7-11.4 long timer delaysusingTMR1, 104 105 prescaler, TMRO,102-103 short timer delaysusingTMRO,101-102 Watchdog, 16,99-100 title directive,160 TMRs (seetimers) Toolboxicon,11 totempoleoutput,118,119 traffic lights,Rokenbok@, 143-146 translstors: in DC motor control,258,260 phototransistors, 240,241 translationvoltage,189 trillionths (p), 11 TRIS (Tii-State)bit, 1,116 tri-stateddver output,119 TV remotecontrols: for objectdetection,243244 for ZipZaps@ robot, 310-311,316-317 two-seryorobot basewith BS2interface,277278
U UARTs,222 ultrasonicdistance-range sensor,249-250 unaryincrement(+ +) operator,46 union statement,T6 unions(C),76 unipolarsteppermotor coni.lol,269-21 1 UniversalAssemblyLanguage,27 universaldelaymacro,203-205 u n i v e r s a l s e rbi auls( U S B )c a b l eI. universalserialbus (USB) port, 13,14 UpperCasemacro,72 USB cable,1 USB port,13,14 userinterface(PICMCU BSZ),224229
338
v Valuevariable,5T58 values: array,208 ASCII,289 binary,35 36 C programminglanguage,83 for complexexpressions, 36 for configurationword, 16 constant,Tl converting,289-291 immediate/literal,162 in programcounter,162 of re gisters,2l-,23-24 in unions,76 of vartables.21-,23-24 variablearrays(C),73-74 variabledeclarationstatement,165 C programming language,28-29 and computerarchitecture,19 variablememory,18,19 variabletypes(PICC Lite compiler),84 variables: binary,35-36 T0-71,83,84 C programminglanguage, charunsigned,188 declaring(assemblylanguage),165,166 declaring(C),19,28 defining(assemblylanguage),165-167 global,71,83 local,TG-71,83 locationof,19 monitoringvaluesof.21-,23-24 naming,29 pointers,7G78 variablesinsidefunctions(PICC Lite compiler),83 #v(expr)directive,198-199 von Neumannarchitecture,18,208 Vrei 97-98
v{ Watchwindow,23,24 watchdogTimer (WDT): disabling,16 PIC16F684,99-100 WDT (seewatchdogTirner) while directive,198 while loop,45-46 Windows,1,11
l - JE x o e r i m e n t s f o r l,a3 PICo l'lC
the EviI
Genius
working register (WREG): in addition instructions,168-169 in bitwise operations,167-168 loading 164-165 read-only array element,208 savingcontents of, 165 and subtract instructions,77I, 772 writing EEPROM data memory,2L4-216
tt
J}
xoR ("),3s
H
s
p p
zero check module, 164 zero insertionforce (ZIF) socket,14,51-53 ZipZaps@-based robots,301-326 basic task-control software,31!316 characterizing,303-304 IR line-following sensory320-325 IR object-detectionsensors, 318-319 IR remote control,376-377 IR TV remotecontrol,310-311 light sensorsand light foUowing,317-318 motor and steering control, 311-312 PIC MCU electronicsPCB,307-309 PIC MCU power supply,305-306
lndex
o
x
339
DiscountGoupon
2Oo/o CftJRetail Price 1.FlashStart Kit (DV164101) On PlCkitrM DaughterBoard(AC164120) On SignalAnalysisPlOtailrM MicrochipTechnology is offeringa 20% discountoff the retailpricefor the PlCkitTM 1 FlashStarter Kit (DV164101)and the SignalAnalysisPlctailrMDaughterBoard (AC164120)lowrost developmentkit and daughterboard.The discountmay be or on the Microchipe-Commerce redeemedthroughyourlocalMicrochipdistributor, This offer cannot be used after Match 31, website http//:buy.microchip.com. 2006.
Termsand Gonditions: This offer appliesonly to the PlckitrM1 FlashStarterKit andlor the Signal to authorized Board.Thisvouchermustbe surrendered Analysis PlctailrM Daughter reference of orderandmustincludeMicrochip distributor at the time of placement e{ommercesite, numbershownbelowto allowfor discount.lf usingMicrochip's numbershown cart.Typethe reference selectthe toolandproceed to the checkout "apply "Coupon" green button coupon." andpressthe belowinto_ the boxlabeled: Thisvouchermaynot appliedto yourpurchase. Thediscountwill be automatically withanyotheroffer,andhasnocashvalue.Onlyonevoucher be usedin conjunction withoutpriornotice. This offer maybe withdrawn may be used per transaction. specified withanyothertermsandconditions Voucher mustbe usedin conjunction Technology Inc. byMicrochip Note Io Disilributor: (QTN)belowmustbe shownon yourolderto gaindiscount. Thereference Distributor or directfrom fromyourlocalMicrochip Usethis numberto purchase Microchip via http//:buy,microchip.com
PREDO5 Referenee Number