Menu

Speeding up Code Execution - A Simple Trick

2016-10-19
2016-10-19
  • William Roth

    William Roth - 2016-10-19

    Speeding up Code

    When GCB compilies the Basic Source code into ASM it must address certain registers.
    In the case of turning on or off an I/O pin on enhanced PIC chips it must address
    a LATx register. To do this the correct register bank address must be selected. This
    is done autmatically by the compiler.

    For example, we want turn RA2 on/off quickly in a loop;

    BASIC CODE:

    Dir PORTA.2 OUT
        Do
           Set PORTA.2 ON
           Set PORTA.2 OFF 
        Loop
    

    Here is the resultant ASM Code:

       banksel  TRISA
       bcf  TRISA,2
    
    SysDoLoop_S1
          banksel   LATA
          bcf   LATA,2
          bsf   LATA,2
          goto  SysDoLoop_S1
    

    Notice that "Banksel" is executed in each iteration of the loop. This take up instruction cycles
    and is not optimal. A trick to eliminate this is to set the bank address BEFORE calling the loop.

    OPTIMIZED BASIC CODE:

    Dir PORTA.2 OUT
    Set PORTA.2 OFF   ;This sets the register bank address the compiler "remembers"
    
    Do
           Set PORTA.2 ON
           Set PORTA.2 OFF 
    Loop
    

    Here is the resultant OPTIMIZED ASM Code:

             banksel  TRISA
             bcf  TRISA,2
             banksel  LATA
             bcf  LATA,2
    
    SysDoLoop_S1
             bcf LATA,2
             bsf     LATA,2
             goto   SysDoLoop_S1
    

    Notice that banksel is executed before the loop and is no longer placed inside
    the loop by the compiler.

    In the case of a 16F1788 operating at 32 MHz, the first example toggles the
    pin at 1.52 Mhz.

    With the optimized code, it toggles at 2.0 Mhz. This is a significant performance
    improvement.

    William

     
  • Chuck Hellebuyck

    William,
    That is a good point and definitely a great description. To add to that though it is recommended coding practice that anytime you are changing a port from input to output, especially at start-up, you should be setting the state of the port pin before changing it's output state. Since the port registers are RAM you really don't know the state of the port bit so presetting it before changing it to an output prevents a brief pulse coming from the pin when you don't want it. I've seen those brief unwanted pulses cause serious issues when controlling a high current device via a transistor circuit.
    So I recommend you just reverse your first two lines as shown below.

    Set PORTA.2 OFF ;Preset the Pin State
    Dir PORTA.2 OUT ;Set Port Direction to Output
    
    Do
           Set PORTA.2 ON
           Set PORTA.2 OFF 
    Loop
    
     
  • William Roth

    William Roth - 2016-10-19

    Thanks for the feedback Chuck,

    Unfortunately that method deos not eliminate the banksel being placed inside the loop and results in the following ASM .

            banksel LATA
            bcf LATA,2
            banksel TRISA
            bcf TRISA,2
    SysDoLoop_S1
            banksel LATA  ;*** Banksel inside loop
            bsf LATA,2
            bcf LATA,2
            goto    SysDoLoop_S1
    

    Setting the Pin state LOW before TRIS should not be necessary in GCB because if we look at the INITSYS routine in the GCB generated ASM file we can see the following that it is already done:

        banksel PORTA   ; Bank 0 (Same for all PORTS)
        clrf    PORTA
        clrf    PORTB
        clrf    PORTC
        clrf    PORTD
        clrf    PORTE
    

    So all PORTx Registers should default to LOW upon chip reset amd should be glitch free when the Pin direction is set to an output in source code. (An exception might be if the pin was previously Set high then changed to an input and then back to an output)

     

    Last edit: William Roth 2016-10-19

Log in to post a comment.

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.