Saturday 14 December 2013

CHAINED IF COMPILATION IN AVR STUDIO - TIPS ON AVR PROGRAMMING


CHAINED IF COMPILATION IN AVR STUDIO
 

     Often chained if loop will be necessary for checking a port input status, but it may take up some unnecessary space & delay if not handled properly.

avr:elecdude



     For an example code shown below:
C code:
prv=PIND & MSK;
      if(prv != 0xF8) {
            Wait(TIME);
            if(prv != (PIND & MSK))
             { ……… }
      }

the compiled assembly code will be as follows:
Assembly code:
42:        prv=PIND & MSK;
IN        R20,0x16       In from I/O location
ANDI      R20,0xF8       Logical AND with immediate
MOV       R17,R20        Copy register
43:         if(prv != 0xF8) { //chk for any key press
CPI       R20,0xF8       Compare with immediate
BREQ      PC+0x26        Branch if equal
LDI       R24,0x40       Load immediate
LDI       R25,0x9C       Load immediate
SBIW      R24,0x01       Subtract immediate from word
BRNE      PC-0x01        Branch if not equal
46:               if(prv != (PIND & MSK))
IN        R24,0x16       In from I/O location
MOV       R18,R20        Copy register
LDI       R19,0x00       Load immediate
LDI       R25,0x00       Load immediate
ANDI      R24,0xF8       Logical AND with immediate
ANDI      R25,0x00       Logical AND with immediate
CP        R18,R24        Compare
CPC       R19,R25        Compare with carry
BREQ      PC+0x19        Branch if equal

We can see there is unnecessary usage of R19, R25. To overcome this, the chained if must be broken. The comparison must include only 2 variables as follows.

C code:
  unsigned char p;
 prv=PIND & MSK;
      if(prv != 0xF8) {
            Wait(TIME);
            p=PIND & MSK;
            if(prv != p)
             { ………  }
}

 Assembly code:
42:        prv=PIND & MSK;
IN        R18,0x16       In from I/O location
ANDI      R18,0xF8       Logical AND with immediate
MOV       R17,R18        Copy register
43:         if(prv != 0xF8) { //chk for any key press
CPI       R18,0xF8       Compare with immediate
BREQ      PC+0x21        Branch if equal
LDI       R24,0x40       Load immediate
LDI       R25,0x9C       Load immediate
SBIW      R24,0x01       Subtract immediate from word
BRNE      PC-0x01        Branch if not equal
45:               p=PIND & MSK;
IN        R24,0x16       In from I/O location
46:               if(prv != p) //(PIND & MSK))
ANDI      R24,0xF8       Logical AND with immediate
CP        R18,R24        Compare
BREQ      PC+0x19        Branch if equal

We might think that adding a variable could increase memory space & memory access, but the compiler optimizes it with using a register. So memory space & memory access cycles are not required.

This code uses lesser space & is faster the previous code.

If you enjoyed this post plz let us know your views via comments.
This helps us to do much more better.
Thankyou.

0 comments:

Post a Comment

Search Here...