;---LCDNib VarPortB.Nib1
i Var Byte
;Constants
;---
RegSel Con B0
Clk Con B1
RdWrPinCon B2
;Initialization
;---Pause500 ;AllowstheLCDtoinitialize LCDInitRegSel\Clk\RdWrPin,LCDNib
Main
Fori=$80TO$FF
LCDWriteRegSel\Clk\RdWrPin,LCDNib,[Clear,Home,”Value:“,DECi,”“,ISHEXi]
LCDWriteRegSel\Clk\RdWrPin,LCDNib,[ScrRAM+$40,”Char“,i]
Pause2000
Next GotoMain End
Bynow,thisprogramshouldrequirelittleexplanation,aswe’veseenallofitearlierinthischapter.The
keylineswritethenumericalvalue(indecimalandhex)onthetopline,whilethecorrespondingcharac-terappearsonbottomline.ThenormalEnglishcharactersetstopsat$7F,sowestartat$80andgotothe
maximumpossiblebytevalue,$FF.Ifyouchangethestartingpointto$20,insteadof$7F,youcanseethe
normalEnglishcharactersetaswell.
CustomCharacters
Ifthenormalandextendedcharactersaren’tenough,youcandefineuptoeightcustomcharacters.Oncede-fined,thesecharactersarefullyaccessiblejustasanypre-definedcharacter.Customcharactersarecontained
incharactergeneratormemory,orCGRAM.SinceCGRAMisvolatile,yourprogrammustrewritethecus-tomcharacterstoCGRAMifpowerisremovedfromtheLCDmodule.Wewillloadourcustomcharacters
atinitialization.
We’lldemonstratecustomcharactersinthecontextofabargraphdisplay.Ifwe’remeasuringaparameter,
suchasananalogvoltagewithaPIC’sbuilt-inanalog-to-digitalconverter,canshowtheresultingvalue
asadigitstringonourdisplay—12.56volts,forexample,updatedseveraltimesasecond.But,ifyouare
adjustingavariablevoltagecontrol,youwillfinddigitaldisplaysaren’twellsuitedtoshowingtrendsor
short-termchanges.Indeed,seeingatrendorspottingamomentaryfluctuationareareaswhereanold-fash-ionedmovingneedlemeterisoftenbetterthanadigitaldisplay.Manydigitalmetermanufacturershave
addedaquickrespondingbargraphmimickingananalogmeterscale.Ourbargraphexampleduplicatesthis
feature.
Let’sstartwithacloseupofacharacter,“T”asifitwereaddedtoCGRAM:
16 8 4 2 1
Thecharacter“T”isformedfroma5x8matrix,withthebottom
rowreservedfortheunderscorecursor.We’venumberedtherows
0…7,toptobottomandcolumns0…4,righttoleft.Tostorethis
characterinformation,the44780controllermapseachrowintoa
memorybyte,withthebottomfivebitsmappedintothedisplay
cells—1foranopaquepixeland0foratransparentpixel.We
cancalculatethevalueofthecorrespondingbytebysumming
theopaquepixels.Forexample,thecapofthe“T”hasthebinary
value00011111,whichwemayconverttodecimalas16+8+4+
2+1,or31.(Thethreemostsignificantbitsmaybeanything,as
theyarenotusedincharactermapping.We’llmakethem000for
convenience.)
Theeightcustomcharactersareassignedvalues0…7.Towritealleightcustomcharacterstothedisplay,
therefore,thesyntaxisLCDWrite…[0,1,2,3,4,5,6,7].
Tocreatecustomcharacters,wemustwritetheirrowbytevaluestoCGRAM.We’llaccomplishthisthrough
MBasic’sall-purposeLCDWriteprocedure,LCDWrite…[CGRAM+Offset,Value].CGRAMistheaddress
ofthefirstbyteofCGRAMmemory,andvalueisthebytevalueassociatedwiththeparticularaddress.
Eachbytefollowsinroworder,andeachcharacterfollowsincharacterorder.Thefollowingtableprovides
theoffsetforeachrow,foreachcharacter.Fortunately,werarelymustkeeptrackofindividualCGRAM
values,astheHD44780controllerchipdoesitforus.
CharacterNumber
Row 0 1 2 3 4 5 6 7
Ifwewishcharacternumber0to
containournew“T,”wewould
simplyexecuteLCDWrite…
[CGRAM,31,4,4,4,4,4,4,0].
Thisprocedurefirstsetsthewriting
tooccuratCGRAMposition0.(We
couldhavewrittenthisCGRAM+0.)
Thenexteightargumentsarethebyte
valuesofthecharacterrows,inorder
row0…row7.Ifwehaveusedthe
normalinitializationstringforthe
LCDmodule,theLCDmoduleisinauto-increment
modeandeachbytewrittenisautomaticallyplacedin
thenextmemorylocationbytheHD44780.Ifwehave
asecondcustomcharactertodefine,wewouldstartit
atCGRAM+8,andthethirdatCGRAM+16 .(Ifitim-mediatelyfollowedthefirstdefinition,wecouldskip
theCGRAM+8andallowtheinternalauto-increment
featuretodefinetheaddress.)
OurbardisplayisbasedonworkbyLarryPhipps,
afriendoftheauthor,whodevelopedaquickacting
displayreferenceusedinadjustinghisamateurradio
equipment.Westartbydefiningfourcustomcharacters:
Character0
16 8 4 2 1
Character1
Character2
0 21
Character3
0 0
Customcharacter3isavisualplaceholder;itfillsthedisplaywithdots.Theotherthreecharactersshowac-tivity,withone,twoorthreeverticalbars.Here’showwemightwritethesecustomcharactersintoCGRAM:
LCDWRITERegSel\Clk\RdWrPin,LCDNib,[CGRAM,16,16,16,21,16,16,16,0]
LCDWRITERegSel\Clk\RdWrPin,LCDNib,[CGRAM+820,20,20,21,20,20,20,0]
LCDWRITERegSel\Clk\RdWrPin,LCDNib,[CGRAM+1621,21,21,21,21,21,21,0]
LCDWRITERegSel\Clk\RdWrPin,LCDNib,[CGRAM+240,0,0,21,0,0,0,0]
A16characterdisplay,usedtotallyforbars,permitsdisplaying0…48.Larry’sadjacentbarshaveaspace
sincetheLCDmodulehasaone-pixelgapbetweenadjacentcharacters.Theresultisuniformlyspacedverti-calbarsacrossthefulldisplaywidth.
We’llassumethatthebargraphistodisplayavalueheldinabytevariableTempandthatTempisscaled
0…48.Ourstrategyfordisplayingbarsisthus:
GetnewvalueofTemp
Determinewhichcharacterswillbeallbars(Char(2))
Writethosecharactersasallbars
Determinehowmanybarswillbedisplayedtotherightofthelastallbars
character
Displaythataseither0(Char(3),1(Char(0)or2(Char(1)bars Fillanyremainingspacewithalldots(Char(3))
Ourdemonstrationprogramcyclesthrough0…48bars,withonesecondbetweensuccessivebardisplays.If
weremovetheintentionalonesecondpause,wecanupdatethebarapproximately100times/secondassum-ingourPIChasa20MHzclockandtherearenolengthycalculationsinvolvedtodetermineTemp.
Program5-5
;ProgramBarGraphSample
;Varibles
;---LCDNib Var PortB.Nib1
i Var Byte
j Var Byte
x Var Byte
y Var Byte(3)
Temp Var Byte
;Constants
;---
RegSel Con B0
Clk Con B1
RdWrPin Con B2
;Initialization
;---Pause500 ;AllowstheLCDtoinitialize y(0)=3
y(1)=0 y(2)=1
LCDInitRegSel\Clk\RdWrPin,LCDNib GoSubLoadBar
Main
Fori=0to48 ;executiontime10.08mSec
Temp=i
x=Temp/3 ;div
LCDWriteRegSel\Clk\RdWrPin,LCDNib,[SCRRAM]
j=0
Whilej<x
LCDWriteRegSel\Clk\RdWrPin,LCDNib,[2]
j=j+1
WEND
LCDWriteRegSel\Clk\RdWrPin,LCDNib,[y(Temp//3)];mod
Forj=x+1to15
LCDWriteRegSel\Clk\RdWrPin,LCDNib,[3]
Next
LCDWriteRegSel\Clk\RdWrPin,LCDNib,[SCRRAM+$40,”“]
LCDWriteRegSel\Clk\RdWrPin,LCDNib,[SCRRAM+$40,DecTemp]
Pause1000
Next
GoToMain End
LoadBar ;loadthebarcharactersintocharacterRAM
;--- LCDWRITERegSel\Clk\RdWrPin,LCDNib,[CGRAM,16,16,16,21,16,16,16,0]
LCDWRITERegSel\Clk\RdWrPin,LCDNib,[20,20,20,21,20,20,20,0]
LCDWRITERegSel\Clk\RdWrPin,LCDNib,[21,21,21,21,21,21,21,0]
LCDWRITERegSel\Clk\RdWrPin,LCDNib,[0,0,0,21,0,0,0,0]
Return
Asbefore,we’veseenmuchofProgram5-5,sowe’llconcentrateonthenewelements.
LoadBar;loadthebarcharactersintocharacterRAM
;--- LCDWRITERegSel\Clk\RdWrPin,LCDNib,[CGRAM,16,16,16,21,16,16,16,0]
LCDWRITERegSel\Clk\RdWrPin,LCDNib,[20,20,20,21,20,20,20,0]
LCDWRITERegSel\Clk\RdWrPin,LCDNib,[21,21,21,21,21,21,21,0]
LCDWRITERegSel\Clk\RdWrPin,LCDNib,[0,0,0,21,0,0,0,0]
Return
SubroutineLoadBariscalledduringtheinitializationprocessandloadsourfourcustomcharactersinto
CGRAM.Sinceweloadthesecharactersintheircharacternumberorder,withoutanyotherinterveningdata
beingsenttotheLCDmodule,weneedonlysettheCGRAMaddressonce,andpermittheHD44780’sauto-incrementfeaturetotakecareoftherest.
Main
Fori=0to48 ;executiontime10.08mSec
Temp=i
x=Temp/3 ;div
TheForiloopcyclesusthroughallpossiblevaluesofbarlength.Forthisdemonstrationprogram,welet
thebarlengthvariable,Temp,equali.Thevariablexdeterminesthebreakpointbetweenallthreebarsand
allthreedots.SupposeTemp=11.Thecorrespondbargraphwillhavethree“|||”charactersfollowedbyone
“||.”character.Theremainingcharacterswillbetheblankidentifiers“...”.Sinceeach“|||”corresponds
toavalueof3bars,wecandeterminehowmany3-barsarecontainedinTempbysimpleintegerdivision.In
thiscase11/3=3.Ratherthanrepeatthisdivision,we’lldoitonceandusethevariablextoholdtheresult
viax=Temp/3.So,wecannowwritex “|||”characterstothedisplay,afterfirstresettingthedisplayad-dresstothetopline,character0:
LCDWriteRegSel\Clk\RdWrPin,LCDNib,[SCRRAM]
j=0
Whilej<x
LCDWriteRegSel\Clk\RdWrPin,LCDNib,[2]
j=j+1
WEND
WeusetheWhile/WENDconstructionhere,becauseit’spossiblethatthereshouldno“|||”characters
displayed,asisthecasewhereTemphasthevalue0,1or2.Sincetheconditionaltestismadeattheoutset
inaWhile/WENDloop,wehaveproperlydealtwiththecasewhereno“|||”istobedisplayed.Wesimply
executeLCDWrite…[2]xtimestoputupthecorrectleading“|||”characters.
LCDWriteRegSel\Clk\RdWrPin,LCDNib,[y(Temp//3)];mod
Nowwedealwiththevariablenumberofbarsinthenextcharacter.There’salotpackedintothisonelineof
code,sopayattention.Todeterminehowmanybarsareinthenextcharacter,welookattheremainderafter
integerdivisionby3,thenumberofbarspercharacter.(InMBasic,theremainderor“modulus”operator
usesthe//symbol.)Theresultis0,1or2.Iftheremainderis0,wedisplaycharacter3.Iftheremainderis1,
wedisplaycharacter0.Iftheremainderis2,wedisplaycharacter2.Wecouldindexintoaseriesof LCD-Writestatements,basedonthevalueoftheremainder,butthat’sslow.Instead,weuseathree-elementbyte
arraywedefinedandinitializedearlier:
y(0)=3
y(1)=0
y(2)=1
Thus,ifweusetheremainderastheindex,theyarraygivesusthecorrectcharactertowritetothescreen.
Hence,wehaveLCDWrite…[y(Temp//3)].
Wemayhaveavoidedarrayindexmappingbyabetterselectionofcharacterorder,butthisexampleisa
fragmentofalargerprogramanddisplaythatcalledfortheorderweused.Besides,arraymappingisause-fultrickthatwillbehandyinotherinstances.
Forj=x+1to15
LCDWriteRegSel\Clk\RdWrPin,LCDNib,[3]
Next
Now,wefinishupbyfillingwhateverisleftofthedisplaywithourblankplaceholder,character3.Wedo
thiswithaFor/Nextloop,startingonepositionpastthevariablebarcharacter.
LCDWriteRegSel\Clk\RdWrPin,LCDNib,[SCRRAM+$40,”“]
LCDWriteRegSel\Clk\RdWrPin,LCDNib,[SCRRAM+$40,DecTemp]
Pause1000
Next
GoToMain
Finally,wewritethedecimalvalueofTemponthebottomline,pause1secondtoallowyoutoseethebar
versusdigitalcountandthengotothenexttestloop.Figure5-15showstheresultsofProgram5-5.Ina
programdoingusefulwork,wewoulddeletethePause1000statement.Figure5-16showstheapplication
resultingfromLarry’swork.
Figure5-15:Bargraphdisplay. Figure5-16:Usingabargraphdisplay.
References
[5-1] Hitachi,HD44780(DotMatrixLiquidCrystalDisplayController/Driver),(undated).Ifyouareinter-estedinthenutsandboltsofLCDwork,youwillneedtheHD44780datasheet.Hitachirecentlyspun
itssemiconductoroperationsintoRenesasTechnologyandtheHD44780datasheetisavailablefor
downloadathttp://america.renesas.com/products/supportdocs/hd44780.pdf.AlthoughRenesasdoesnot
recommendtheHD44780fornewdesigns,newerLCDcontrollersaredownwardcompatiblewiththe
HD44780commandset.
[5-2] TianmaMicroelectronicsCo.,Ltd.,SpecificationforLCDModule,ModuleNo.TM162YBC6,
(undated).Thisdatasheetisavailablefordownloadathttp://www.tianma.com/spec_sheets/
TM162YBC6%20SPEC.pdf.
[5-3] EpsonElectronics,SED1278LCDController/DriversTechnicalManual,(undated).
[5-4] SamsungElectronics,KS0066U16COM/40SEGDriver&ControllerforDotMatrixLCD,(undated).