PDA

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 &amp; _MCLRE_ON &amp; _LVP_OFF &amp; _WDT_OFF &amp; _PWRTE_ON &amp; _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