View Full Version : Code: Why is this code greater than 2000 words?
DrDreas
- 31st May 2007, 23:12
Hi Guys,
I am new to PICs and picbasic pro, and an using a PIC 16F628a. I have a program up and running, but I seem to have run out of space on my PIC. The 628 has a 2000 word limit, and it seems that my compiled code exceeds that. I don't quite understand what in the code amounts to one word of data. Is it possible to take a peek at my code and see what is taking up so much space, am I doing something wrong, or is this normal for the commands I am using?
Right know I have commented out several blocks of code that use the pulsout command to generate a pwm signal to move a servo. I have commented them so that the code remains below 2000 words. With those blocks it grows to roughly 2300 words.
I appreciate the help,
Andreas
mister_e
- 1st June 2007, 02:05
Actually, it compile 1808 word here. if you need to use PULSOUT often , just create a subroutine(or macro) and pass the parameters in. But frankly... Pulsout is nothing more than
High
PAUSEUS xxxx
Low
you could still upgrade to a 16F88 or 16F648A
Also, apply the same rule to every code you use 2,3,4,5 times such as this section
RawCompass = (A_Curve - LowLimit) * Scale
Compass = ((RawCompass/10) * 4) /10
Heading = Compass + 1800
if Heading > ActuateOn and Heading < ActuateOff then
high PortB.4
In Section A, B ,C, D. Sure there's some variant between them, but sure you can reduce the whole thing.
DrDreas
- 1st June 2007, 14:57
yes, it compiles at 1800 now because I commented out the sections that deal with servo control. So the best method of reducing the size is to create subroutines for repeated code blocks?
Acetronics2
- 1st June 2007, 15:33
Hi, Andreas
A little thing ... you use a 4Mhz crystal ...
no use, then, to keep WORDS for pulse length : result always will be between 50 and 250 ... so BYTES will fit.
Will save much room ( and time ) in the calculation part !!!
But if you want to use 20 Mhz crystal ... you have to keep the WORDS.
Alain
T.Jackson
- 1st June 2007, 15:40
The term "reuse-ability" springs to mind. For example, you could create a routine for PULSOUT and pass allocated variables to it, resulting in just one instance of the PULSOUT (this will certainly save space)
GOSUB Do_Pulse
Do_Pulse:
PULSOUT IO_Pin, Duration
RETURN
<lu>
<li> Just declare IO_Pin and duration as variables that are specific to the purpose.</li>
</lu>
Acetronics2
- 1st June 2007, 16:01
just missing ref. to a twin axis gyroscope sensor ... IDG 300 ???
<< if Ratio < 100 And Ratio > 0 then ... >>
other room to save : Ratio is ALWAYS > 0 ( Coz. PbP only works with POSITIVE INTEGERS !!! ) ...
<< Alpha = Ratio*11 + 732*10 >>
Why not directly write " Alpha = Ratio*11 + 7320 "
saves one 16x16 multiplication !!!
Was just some examples ...
Alain
skimask
- 1st June 2007, 16:20
yes, it compiles at 1800 now because I commented out the sections that deal with servo control. So the best method of reducing the size is to create subroutines for repeated code blocks?
Just had a look, how about some of this:
Combine math in this chunk of code if possible:
Alpha=Ratio*51 + 532*10
Alpha=Alpha/10
Instead of /2, use >> 1 (shift right by one bit = divide by 2), example:
if Alpha < (ServoArc/2) then.......becomes:
if Alpha < ( ServoArc >> 1 ) then
Same thing with any multiply or divide by a power of two, use a shift << for multiply, shift >> for divide
Like Ace said, combine your subroutines a bit:
SectionA:
RawCompass=(UpLimit - A_Curve) * Scale: gosub FIXCOMPASS
Compass=((RawCompass/10) << 2) /10
Heading=Compass
if Heading > ActuateOn and Heading < ActuateOff then
GOSUB SUBSECTION1
else
GOSUB SUBSECTION2
endif
GoTO Mainloop ' Do it indefinitely
SectionB:
RawCompass=(B_Curve - LowLimit) * Scale : gosub FIXCOMPASS
CrossZero=Compass + 2700
if CrossZero >= 3600 then SectionBA
Heading=CrossZero
if Heading > ActuateOn and Heading < ActuateOff then
GOSUB SUBSECTION1
else
GOSUB SUBSECTION2 (and so on, but the rest aren't boldfaced for emphasis)
endif
GoTO Mainloop ' Do it indefinitely
SectionBA: ZeroCross=CrossZero -3600 :Heading=ZeroCross
if Heading > ActuateOn and Heading < ActuateOff then
GOSUB SUBSECTION1
else
GOSUB SUBSECTION2
endif
GoTO Mainloop ' Do it indefinitely
SectionC:
RawCompass=0:RawCompass=(UpLimit - B_Curve) * Scale
gosub FIXCOMPASS : Heading=Compass + 900
if Heading > ActuateOn and Heading < ActuateOff then
GOSUB SUBSECTION1
else
GOSUB SUBSECTION2
endif
GoTO Mainloop ' Do it indefinitely
SectionD:
RawCompass=(A_Curve - LowLimit) * Scale : gosub FIXCOMPASS
Heading=Compass + 1800
if Heading > ActuateOn and Heading < ActuateOff then
GOSUB SUBSECTION1
else
GOSUB SUBSECTION2
endif
GoTO Mainloop ' Do it indefinitely
Calibrate: IF A_Curve > 2048 THEN UpLimit=A_Curve ' Establish the actual upper limit
If A_Curve < 2048 THEN LowLimit=A_Curve ' Establish the actual lower limit
Spread=9000 / (UpLimit - LowLimit):Scale=(Spread * 10) >> 2:Return
SUBSECTION1:
high PortB.4: pulseWidth=2000:lowTime=20000 - pulsewidth:Low Servo
Pulsout Servo, pulseWidth/10:Pauseus lowTime
return
SUBSECTION2:
LOW PortB.4: pulseWidth=1500:lowTime=20000 - pulsewidth:Low Servo
Pulsout Servo, pulseWidth/10:Pauseus lowTime
return
FIXCOMPASS:
Compass=((RawCompass/10) << 2) /10
return
That might get your program on the chip. There's a couple of other optimizations relating to Bank'ing your variables, but that's a bit of an advanced subject. If the program still doesn't fit, re-post what you've got...maybe more optimizations will get 'er in there.
mister_e
- 1st June 2007, 17:17
Here the multiple used math is more revealant than Pulsout Itself. Yeah i still refer to the same method to measure the code size... let's see
<font color="#000080">@ __CONFIG _INTRC_OSC_NOCLKOUT & _MCLRE_ON & _LVP_OFF & _WDT_OFF & _PWRTE_ON & _BODEN_ON
</font>PORTB=0
TRISB=0
Led1 <font color="#000080">VAR </font>PORTB.0
Led2 <font color="#000080">VAR </font>PORTB.1
Led3 <font color="#000080">VAR </font>PORTB.2
Led4 <font color="#000080">VAR </font>PORTB.3
Led5 <font color="#000080">VAR </font>PORTB.4
Led6 <font color="#000080">VAR </font>PORTB.5
Led7 <font color="#000080">VAR </font>PORTB.6
Led8 <font color="#000080">VAR </font>PORTB.7
ByteA <font color="#000080">VAR BYTE
</font>ByteB <font color="#000080">VAR BYTE
</font>Worda <font color="#000080">VAR WORD
</font>PORT <font color="#000080">VAR BYTE
</font>DURATION <font color="#000080">VAR WORD
GOTO </font>Start
<font color="#000080">ASM
HOGSTART MACRO
BLOCKSTART=$
ENDM
HOGEND MACRO BLOCKNAME
BLOCKNAME = $-BLOCKSTART
ENDM
CUSTOM_PULSOUT MACRO PORT, PIN, DURATION, BYTEA
PULSOUT?TC PORT,PIN,DURATION
MOVE?CB BYTEA,_ByteA
L?CALL _DO_CALC
ENDM
ENDASM
</font>DO_CALC:
ByteB=50+ByteA
Worda=(ByteA+ByteB)*100
<font color="#000080">RETURN
</font>Start:
@ HOGSTART
<font color="#000080">PULSOUT </font>Led1,10000
ByteA=10
ByteB=50 + ByteA
Worda=(ByteA+ByteB)*100
<font color="#000080">PULSOUT </font>Led2,10000
ByteA=20
ByteB=50 + ByteA
Worda=(ByteA+ByteB)*100
<font color="#000080">PULSOUT </font>Led3,10000
ByteA=30
ByteB=50 + ByteA
Worda=(ByteA+ByteB)*100
<font color="#000080">PULSOUT </font>Led4,10000
ByteA=40
ByteB=50 + ByteA
Worda=(ByteA+ByteB)*100
@ HOGEND ____MULTIPLEPULSOUT
<font color="#000080">ASM
HOGSTART
CUSTOM_PULSOUT _Led1,10000,10
CUSTOM_PULSOUT _Led2,10000,20
CUSTOM_PULSOUT _Led3,10000,30
CUSTOM_PULSOUT _Led4,10000,40
HOGEND ____MACRO_CUSTOM_PULSOUT
ENDASM
</font>SPIN: <font color="#000080">GOTO </font>SPIN
Compile this with MPASM, and open the according .LST file... and discover that...
SYMBOL TABLE
LABEL VALUE
____MACRO_CUSTOM_PULSOUT 0000002C
____MULTIPLEPULSOUT 00000074
2c=44 decimal
74=116 Decimal
here the simple macro and sub call will use 116/44=~2.6 time less code and make the code MUCH MORE readable... at least to me.. case not.. hum, hum, just fart in Darrel's direction :eek: http://www.mister-e.org/Pics/ROFL
How handy they are :D
skimask
- 1st June 2007, 19:10
How handy they are :D
The farts or the macros? :D
mister_e
- 1st June 2007, 19:51
mmm, hard to tell :D
Powered by vBulletin® Version 4.1.7 Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.