PicBasic Pro Compiler Code Optimizations

<-back to Index 

Here are a few tricks that I've learned to save on code space using the MELabs PBP BASIC compiler for Microchip PIC microcontrollers. My compiler is the most recent as of Jan. '02, version 2.40a with the update that fixes the array indexing issue.  (See below.)

Array accessing--saves 2 words

Incrementing Variables--saves 2 words

For-Next Loops--saves 1 word

Replace For-Next with While--Saves 2-4 words

More For-Next Loops--saves up to 13-14 words

IF ... AND...Then's--saves 5 words

ADCIN--Lots of room for saving time, up to 100uS.

Code Location--code dependant

 

NOTE: This page is brand new as of Jan 10, '02, and subject to updates. Please check back once in to catch corrections (such as the note on incrementing variables) and additions.

 

Note 2: If using assembly in place of the compiled basic, make sure you address the Banking issue. Code above 2k will have this requirement. 

If you have a suggestion for this list, feel free to direct submissions to cliff@griffinlab.com .


 

Array accessing:

New method:

    j=i+1
    array[j]=...
compiles two words shorter than the old "shorter" version:
array[i+1]=...

Note also that the above new method is a workaround for the PBP 2.40 bug that gives a compile error with the original 2.40 version. If you download the 2.40a update from the MELabs web site, you won't receive the compile time error.

 

 

Incrementing Variables:

Another trick to save a word is to use an assembly routine to increment variables:
    @ incf _Time ,1
This compiles two words shorter, but is functionally equivalent to
    Time = Time + 1
Don't forget the underscore before Time in the assembly line.
NOTE: With feedback from Jeff Schmoyer, he has indicated that the incrementation of a byte only takes "one  word to do this with byte-sized variables.  With word- sized variables, it will use 3 words.  It will also take care of the banking issue.  Many users have variables in several banks.  The compiler will make sure to set the appropriate bank." So, unless you set the variable into a specific memory bank and your code is there also, do not use this. So...use this with caution.

For-Next Loops:

Save one word by using 0 to 9 instead of 1 to 10!

For x = 0 to 9        'note: one word shorter!

    '...code here...

next x

 

For x = 1 to 10        'note: one word longer

    '...code here...

next x

 

Replace For-Next Loops with While:

Instead of using a  for next loop:

    for i = 1 to 10
    next

Use a While loop, and save two words. Note that you will save two words regardless of the starting value, either 0 or 1.

    i=1
    while i<11
    i=i+1        ' even better if you use
@ incf _i ,1
    wend

As noted, you can use the assembler technique for incrementing i, and you'll save two more words! See the notes above on incrementing before implementing this!

 

More on For-Next Loops:

This technique saves 14 words space over a For-Next loop:
    x = 0                 ' set up for an assember For-Next loop of 256
    LoopI:
    Pause 5            'misc. code goes here.
                                   'Note that the F in the following line is to
                                    'indicate that you are accessing a File register.
    @ incfsz _x, F            'again, remember the underscore before your variable name.
    @ goto _loopI            ' like the NEXT statement. Use the underscore!


The above sample is to loop 256 times. To count down from, say 10 to 1, set x=10 and replace the incfsz (increment file, skip next line if it =0) with decfsz, (decrement & skip if zero). This will save 13 words:

    x = 10        'equivalent to For x=10 to 1 step -1
Loopl:
    pause 5
    @ decfsz _x,F    'will jump out of the loop if x=0
    @ goto _Loopl

 

 

If... AND... Then's

Using two IF commands saves five words 

    looptest:
    'if (i=1) and (k=1) then looptest

Instead, use this technique:
    if i=1 then
    if k=1 then looptest
    endif

 

 

ADCIN and Reading Analog Inputs

There is a LOT of room for saving execution time during an ADCIN read. The ADCIN command had a time delay in it, making it even worse. Here is an example of reading the analog port before the ADCIN command came about:

    ' Subroutine to get pot x value
    getx:
        ADCON0 = $41 ' Set A/D to Fosc/8, Channel 0, On
        Pauseus 50 ' Wait for channel to setup
        ADCON0.2 = 1 ' Start conversion
        Pauseus 50 ' Wait for conversion
        x = ADRESH
    Return

There are two things you can do to save time here. The obvious thing is to replace the 50uS pause commands with code. Another thing to do is to replace the "start conversion" command and the second pause with this code:

    GO_DONE = 1                        ' Start conversion by setting GO_DONE bit
    while GO_DONE = 1 : wend     'then wait for it to clear

What this does is start the conversion and then waits just until it's done, rather than an arbitrary predetermined amount of time that will cover all conversion times.

 

 

Code Location

Note that I have not verified this tip, but it was offered by Ben of the PICBasic list. Jeff Schmoyer--the PBP author--has indicated that code location is NOT an issue with more recent versions. As expected, he has made many code size and speed improvements over the years.

 

    >What I did was to move my subroutines up to the front of my program right after my variable definitions. Then put a goto statement in, to jump past the subroutines and the code SHRUNK by 96 words!!! Hope the explanations helps someone else trying to squeeze every last drop of space out.

    'variable declarations . .

    goto EndSub

    'subroutines here . .

    EndSub: 'Start program here Loop: . .

    'code . .

    goto loop

    end

 

 


 

 

Hit Counter

Copyright 2002, Cliff Griffin