Académique Documents
Professionnel Documents
Culture Documents
Knowinghowtouselookuptablesisavaluableskillforanyembeddedprogrammer,
they allow us to replace potentially complex runtime computation with a simple array
indexingoperation.ThisarticleofferswaystoapplytheselookuptablesinMikroCandoffers
examplesdemonstratingthesetechniques.
Until recently, data stored in program memory could not be modified after
downloading. Many newer devices do now allow program memory to be modified by the
program,thoughthenprocessisusuallyslowandcomplicated.
DatastoredinthedataEEPROMisslowtowrite,butquickandeasytoread,andwillnot
belostwhenthepowerisremoved.
DatastoredinRAMisquickandeasytoreadandwrite,butisvolatile,andmustbere
calculatedeachtimepowerisappliedtothedevice.Thismaystillbeusefulifthecalculations
canbeperformedduringaninitializationperiod.
With the sine wave example we only need to store one quadrant of values (0 to 90
degrees).Datacanbeaccessedinawaythatwillallowthegenerationofallthesine,cosineand
tangentvalues,usingonlysimplecalculations.Otherexamplesmightoperateadequatelyusing
interpolationtocalculatevaluesbetweentheonesstoredinthearray.
7.Sin(108)=0.95
8.Sin(126)=0.81
9.Sin(144)=0.59
10.Sin(162)=0.31
Wedonttakesin(180)asthisvaluewillbenextcalledwhenweimplementsin(0),which
bothequal0.
Now,weknowhowtofindthevalues.Now,howtoimplementthis.So,wereusingPIC
PWM.1means100%dutycycle,0means0%and0.5means50%.So,fromtheabovetable,we
knowthat:
1.Sin(0)=0%
2.Sin(18)=31%
3.Sin(36)=59%
4.Sin(54)=81%
5.Sin(72)=95%
6.Sin(90)=100%
7.Sin(108)=95%
8.Sin(126)=81%
9.Sin(144)=59%
10.Sin(162)=31%
Now,weneedtoputthesevaluesintoapropersinetable.Forthatweneedtoknowthevalue
ofPR2.
PWMPeriod=[(PR2)+1]*4*TOSC*(TMR2PrescaleValue)
Weknow,PWMperiod,TOSCandprescalevalue,soputtingthisandrearranginggivesus,
PR2+1=PWMPeriod/(4*TOSC*{TMR2PrescaleValue})
Therefore,
PR2=[PWMPeriod/(4*TOSC*{TMR2PrescaleValue})]1
*Formuladerivedfromthatgivenindatasheet.
Now,weneedtodecideatwhichfrequencywearegoingtodothePWM(carrierfrequency).
Say,wehaveanoscillatorof16MHzandwedecidetouseacarrierfrequencyof16kHz.Then,if
youputinthevaluesintotheaboveformula,wehave:
PR2=[(1/16,000)/(4*{1/16,000,000}*1]1
Givingus,
PR2=249
Soweassign249toPR2.ThedutycycleregisterisCCPR1L.WhenCCPR1L=0,dutycycle=0,
when
CCPR1L=(PR2+1),dutycycle=100%.Thisisbecause(PR2+1)=Period
So,CCPR1L/(PR2+1)=Dutycycle
So,thetable:
1.Sin(0)=0%
2.Sin(18)=31%
3.Sin(36)=59%
4.Sin(54)=81%
5.Sin(72)=95%
6.Sin(90)=100%
7.Sin(108)=95%
8.Sin(126)=81%
9.Sin(144)=59%
10.Sin(162)=31%
Canberearrangedas:
1.Sin(0)=0*250
2.Sin(18)=0.31*250
3.Sin(36)=0.59*250
4.Sin(54)=0.81*250
5.Sin(72)=0.95*250
6.Sin(90)=1*250
7.Sin(108)=0.95*250
8.Sin(126)=0.81*250
9.Sin(144)=0.59*250
10.Sin(162)=0.31*250
Herewemultipliedby250as250isthepeakofthesinewave[y=sin(x)*250]as250isthe
period.
Sowehave:
1.Sin(0)=0
2.Sin(18)=77.5,takeas77
3.Sin(36)=147.5,takeas147
4.Sin(54)=202.5,takeas202
5.Sin(72)=237.5,takeas237
6.Sin(90)=250
7.Sin(108)=237.5,takeas237
8.Sin(126)=202.5,takeas202
9.Sin(144)=147.5,takeas147
10.Sin(162)=77.5,takeas77
There,wehavenowfoundoutoursinetable:
[0,77,147,202,237,250,237,202,147,77]
Thats10values.Youcanrepeattheprocessforasmanyvaluesasyouneed.
Now,howtousethisforimplementationofsinewave:
PR2=249
Initially,CCPR1L=0
WeenableCCP1interrupt,bywritingonetoCCP1IEandGIEandPEIE.Theinterruptoccursat
theendofeveryperiod,ie,whenTMR2=PR2,ie,whenTMR2counts250steps,ie6.25us,ieat
afrequencyof16kHzourcarrierfrequency.
Wesetthesinetableasanarray.Letstakethevariableassinval.
So,
sinval=[0,77,147,202,237,250,237,202,147,77]
Welltakeavariabletoactasthearrayindex.Letstakethatasind.Initially,ind=0.
Wellalsotakeanothervariablethatsignalstheendoftheindex.Letstakethatasendi.We
knowthereare10values,sinval[0]tosinval[9],sowellassignendi10.So,initially,endi=10
In the ISR, we first use ind to determine the current position of the array. So, at first
ind=0.Wecallsinvalwiththeindexbeingind.So,whenind=0,wecallsinval[0],whichis0.We
passthisvaluetoCCPR1L.
Then,weincrementtheindexvariableindandcomparethisagainstendi.Inddoes
notequalendi,sowecontinue.Repeattheprocedureuntilallaredone.
So when ind = 9, sinval[9] is called. We have retrieved the value 77. We pass this to
CCPR1L.Thenafterincrementing,ind=10.Wealwayscomparethevalueagainstendi.Soind=
endi, so, we reverse the direction of the full bridge by toggling bit 7 of ECCP1CON, which is
P1M1orEPWM1M1.
Wecontinueagain,thistimeclearingind,sothatwehaveind=0again,andwhenind=
endi,wereversethedirectionagain.
So, what we have achieved is, while at first QA and QD are on, we modulated in one
direction, and then with QA and QD off and QB and QC on the other direction. If we use LC
filter,wellachieveasinewave.
But.Thereisonethingremaining.Thefrequencyisnt50Hz.Why?
Ourcarrierfrequencyis16kHzandinatotalwave,wehave20samples.So,thefrequencyis
16/20=0.8kHz=800Hz.
800Hzisthefrequency.Soperiodis1.25ms.For50Hz,weneedaperiodof20ms.So,we
must prolong our period (20/1.25) = 16 times. This can be done, by sending each sample 16
times,thusprolongingtheperiodandso,wehavea50Hzfrequency.
Thiswould meansendingeachvalueofsinval16timesintheISRandthenincrement
theindexregisterind.
Sosinval[0]wouldbesent16times,sinval[1]wouldbesent16times,sinval[2]16times
andsoon.Thismeans,for16interrupts,thesamevaluewouldbepassedtoCCPR1Landthen
indwouldbeincremented.
PROGRAMCOMMANDS:
MikroC directly supports lookup tables in both data memory (as strings/arrays) and
EEPROM(usingtheEEPROMcomponent).TheprogrammemoryoptionrequirestheuseofC
codeblocks.
Example1SINLookUpTable
Uses a look up table to convert a degree value between 0 and 180 into a value of SIN with
amplitudeof100.
unsignedcharconstsine_wave[32]={20,41,60,80,98,116,132,147,161,173,183,
192,199,204,207,208,207,204,199,192,183,173,161,147,132,116,98,80,60,41,20,0};
Interrupt_subroutine()\\inthesubroutinejustcallarrayvalue
note:youcancallinsidethemainfunctionalso
{
CCPR1L=sine_wave[index];\\sin_waveisthetable_nameandindexisthebytevariableCCPRILis10bit
RegisteritcanbealsoTIMERregister
++index;\\incrementindexvalue
if(index==32)\\checkifindexreachesthevalueof32
index=0;\\ifYESresettozero
}
Voidmain(){
Index=0;\\declareindexvalueaszero
}
Variables
DataType
bit
signedchar
unsignedchar
signedint
unsignedint
signedlong
unsignedlong
float
Bits
1
8
8
16
16
32
32
32
Bytes
1
1
2
2
4
4
4
ValueRange
0to1
128to+127
0to255
32768to+32767
0to65535
2147483648to2147483647
0to4294967295
1.175494E38to3.402823E+38
Theformatofthecommandtostoreupto256bytesofdataintheprogrammemoryofaPIC
deviceis:
PIC:romchar*table_name={d0,d1,d2,d3,d4,.........,d255};
TheformatofthecommandstostoredataintheprogrammemoryofanARMorAVRdeviceis:
ARM:constchartable_name[]={d0,d1,d2,d3,d4,.........,dxxx};
AVR:constchartable_name[]PROGMEM={d0,d1,d2,d3,d4,.........,dxxx};
TheAVRandARMarraysizesareonlylimitedbytheavailablememory.
Accessinganindividualelementofthedatatablerequiresthefollowingcode:
FCV_DATA_VAL=table_name[FCV_INDEX];(PIC,ARM)
FCV_DATA_VAL=pgm_read_byte(table_name+FCV_INDEX);(AVR)
WhereFCV_DATA_VALandFCV_INDEXaretheCcodeversionsofthevariablenames'data_val'
and'index',declaredasbytevariablesinMikroC.
Note:ThesamevariablescanbeaccessedfromMikroCusingtheappropriateversionofthe
variablename.