Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

PIC Micro code optimization.

Status
Not open for further replies.

justin_sane

New Member
Can this by done any faster:

Code:
/* receive a clocked byte from the host */
inline char getbyte(void)
{
    char count, recdata = 0;

    // load 8 clocked bits
    for (count  = 0; count < 8; count++)
    {
        // shift data right 
        recdata >>= 1;    // (rotate right)

        // wait for high clock
        while (!clock); 
     
        if (data) 
          recdata |= 0x80;  //set the MSB  

        // wait for low clock
        while (clock);  
    }
    return(recdata);
}
/* end of get byte */

I handed coded into assembly as:

Code:
        movlw	0x08	  	// count = 8
        movwf	count

        BCF   0x03,Carry	//  reset carry
        // we only need to reset the carry once per call
 
countlp
        RRF   recdata,1     // recdata >>= 1;    shift data right

waitckh btfss clock         // wait for high clock
        goto waitckh        // while (!clock); 
     
        btfsc data          // if (data) set the MSB  
        BSF   recdata,7     // recdata |= 0x80; 

waitckl btfsc clock         // wait for low clock
        goto waitckl        // while (clock);  
        
        decfsz count
        goto countlp


I can't think of any ways to get the assembly version any faster, or a better way of clocking eight bits in for that matter.
 
I don't see much improvement possible with your sample code. However, there might be a bug and I modified the code to correct it as follows:

Code:
        movlw   0x08        // count = 8 
        movwf   count 

countlp  ; <-- moved label here.
        BCF   0x03,Carry   //  reset carry 
        // we only need to reset the carry once per call 

        RRF   recdata,1     // recdata >>= 1;    shift data right 

waitckh btfss clock         // wait for high clock 
        goto waitckh        // while (!clock); 
      
        btfsc data          // if (data) set the MSB  
        BSF   recdata,7     // recdata |= 0x80; 

waitckl btfsc clock         // wait for low clock 
        goto waitckl        // while (clock);  
        
        decfsz count 
        goto countlp

The label was moved because you have to clear the carry flag before the RRF instruction or else the carry flag will depend on the result from the previous RRF instruction (unless the entire recdata file register was cleared prior to calling this routine).

In addition, you should consider using interrupts here because the PIC is doing absolutely nothing while waiting for the clock to change. You can use RB0 pin as clock input.
 
Wouldn't it be faster to clear recbyte before the loop, rather than clear the carry eight times?

Thanks for the interrupt suggestion.

Eventually it must be implemented that way.
 
Wouldn't it be faster to clear recbyte before the loop, rather than clear the carry eight times?

That is correct. Except that you would have to add the "CLRF recdata" ahead of the loop and the "BCF status,carry" would still be required. This is against your objective of reducing code.

Unless the serial clock frequency were faster than 99Khz (11 instructions steps @ 4Mhz), you lose nothing by clearing the carry eight times. You will still waste cycles waiting for the clock to transition unless you're using interrupts.

At this speed (99Khz), interrupts would not be possible because of the overhead of context saving.

BTW, the maximum safe serial clock frequency would be about 62.5Khz (16 instructions steps @ 4Mhz).
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top