AVRNEWER 发表于 2005-12-14 16:36:39

在winavr中同一个语句:if(PIND&(1

77:               if(PIND&(1<<PD4))

+000001E7:   B380      IN      R24,0x10         In from I/O location

+000001E8:   2799      CLR   R25            Exclusive OR

+000001E9:   E024      LDI   R18,0x04         Load immediate

+000001EA:   9596      LSR   R25            Logical shift right

+000001EB:   9587      ROR   R24            Rotate right through carry

+000001EC:   952A      DEC   R18            Decrement

+000001ED:   F7E1      BRNE    -0x04            Branch if not equal

+000001EE:   019C      MOVW    R18,R24          Copy register pair

+000001EF:   7021      ANDI    R18,0x01         Logical AND with immediate

+000001F0:   7030      ANDI    R19,0x00         Logical AND with immediate

+000001F1:   FF80      SBRS    R24,0            Skip if bit in register set

+000001F2:   C00B      RJMP    +0x000B          Relative jump



109:              if(PIND&(1<<PD4))

+0000020C:   9B84      SBIS    0x10,4         Skip if bit in I/O register set

+0000020D:   C002      RJMP    +0x0002          Relative jump







<font color=red>以下红色文字由版主:HJJourAVR 于:2005-12-15,14:56:47 加入。请上传源代码

本论坛推荐,尽量上传源代码,以加快其它人为你解答问题的速度。

上传的源代码请注意以下事项:

1. 尽量将源代码简化,以能将问题演示出来即可。不要上传太复杂的代码。

2. 请记得将公司名称及客户名称等资料删除,并注明你的代码是使用何种版本软件编写的。

注:你可以使用编辑功能修改,并将这段红色文字删除。谢谢你的支持!

avrboy 发表于 2005-12-14 17:42:41

你改為這樣if(PIND&0x10)就會細很多了!!

因為系統幫你做了移位運算1<<PD4!!

AVRNEWER 发表于 2005-12-14 17:48:51

楼上解释不通吧,那第二条语句怎么就两句汇编呢

109:         if(PIND&(1<<PD4))

+0000020C:   9B84      SBIS    0x10,4         Skip if bit in I/O register set

+0000020D:   C002      RJMP    +0x0002          Relative jump

AVRNEWER 发表于 2005-12-14 17:50:01

改成if(bit_is_set(PIND,PD4))也有同样的问题



79:               if(bit_is_set(PIND,PD4))

+000001F4:   B380      IN      R24,0x10         In from I/O location

+000001F5:   2799      CLR   R25            Exclusive OR

+000001F6:   E024      LDI   R18,0x04         Load immediate

+000001F7:   9596      LSR   R25            Logical shift right

+000001F8:   9587      ROR   R24            Rotate right through carry

+000001F9:   952A      DEC   R18            Decrement

+000001FA:   F7E1      BRNE    -0x04            Branch if not equal

+000001FB:   019C      MOVW    R18,R24          Copy register pair

+000001FC:   7021      ANDI    R18,0x01         Logical AND with immediate

+000001FD:   7030      ANDI    R19,0x00         Logical AND with immediate

+000001FE:   FF80      SBRS    R24,0            Skip if bit in register set

+000001FF:   C00B      RJMP    +0x000B          Relative jump



111:              if(bit_is_set(PIND,PD4))

+00000219:   9B84      SBIS    0x10,4         Skip if bit in I/O register set

+0000021A:   C002      RJMP    +0x0002          Relative jump

AVRNEWER 发表于 2005-12-14 17:53:24

按 avrboy 單片王子所说的改的结果也是同样的





79:               if(PIND&0x10)

+000001F4:   B380      IN      R24,0x10         In from I/O location

+000001F5:   2799      CLR   R25            Exclusive OR

+000001F6:   E024      LDI   R18,0x04         Load immediate

+000001F7:   9596      LSR   R25            Logical shift right

+000001F8:   9587      ROR   R24            Rotate right through carry

+000001F9:   952A      DEC   R18            Decrement

+000001FA:   F7E1      BRNE    -0x04            Branch if not equal

+000001FB:   019C      MOVW    R18,R24          Copy register pair

+000001FC:   7021      ANDI    R18,0x01         Logical AND with immediate

+000001FD:   7030      ANDI    R19,0x00         Logical AND with immediate

+000001FE:   FF80      SBRS    R24,0            Skip if bit in register set

+000001FF:   C00B      RJMP    +0x000B          Relative jump

baplmqj 发表于 2005-12-15 11:34:52

我想是优化了的结果!

因为你在同一个winavr中,第一次已计算了(PIND&(1<<PD4))



第二次做if(PIND&(1<<PD4))只要做:判断(PIND&(1<<PD4))是否等于1



我从来没有用过汇编(不懂),只用C

希望没有误导你!!!!

HJJourAVR 发表于 2005-12-15 11:41:32

opt=?

改成 opt=s 看看?

makefile默认是opt=s,不知道楼主用的是那个设定。

AVRNEWER 发表于 2005-12-15 14:25:35

我的opt=s

继续讨论,请看我的c代码:



         for(i=0xff;i>0;i--)

        {

                //if((PIND&(1<<PD4)) == 0)

                if(bit_is_clear(PIND,PD4))

                {

                        //sei();

                        _delay_us(480);

                        //wait_us(490);

                        sbi(DDRD,PD4);//OUTPUT

                        return 1;

                }

        }

        //if(PIND&(1<<PD4))

        if(bit_is_set(PIND,PD4))   //就是这一句会有那么多句汇编

        {

                sbi(DDRD,PD4);//OUTPUT

                return 0;                //返回0

        }



我觉得问题很可能出在return 1;上面,但不知道为什么会有这样的影响,希望大侠释疑

AVRNEWER 发表于 2005-12-15 14:30:22

刚才把return 1;注释掉重新试了一下确实有所改观,还请大侠解释一下

79:               if(bit_is_set(PIND,PD4))

+000001F9:   9984      SBIC    0x10,4         Skip if bit in I/O register cleared

+000001FA:   C000      RJMP    +0x0000          Relative jump

HJJourAVR 发表于 2005-12-15 14:58:22

联系上下文。



单单测试这一段代码,并没有顶楼所说的现象。

AVRNEWER 发表于 2005-12-16 09:54:27

请看源码,我用的studio版本是4.12,不知有没有关系



#define        F_CPU 1000000UL

#include <avr/io.h>

#include <avr/delay.h>   //_delay_us()最大延时768us;_delay_ms()最大延时262us





#define DQ        PD4



#define uchar   unsigned char

#define uint      unsigned int



uchar test(void)        //       

{

        uchar i;

        cbi(PORTD,DQ);

        _delay_us(600);

        sbi(PORTD,DQ);

        _delay_us(10);

       

        cbi(DDRD,PD4);//INPUT

        sbi(PORTD,PD4);//PULL UP

       

        for(i=0xff;i>0;i--)

        {

                if(bit_is_clear(PIND,PD4))

                {

                        _delay_us(480);

                        sbi(DDRD,PD4);//OUTPUT

                        return 1;

                }

        }

        if(bit_is_set(PIND,PD4))

        {

                sbi(DDRD,PD4);//OUTPUT

                return 0;                //返回0

        }

        sbi(DDRD,PD4);//OUTPUT

        return 0;

}



int main(void)

{

        sbi(DDRD,PD4);                //dq设置为输出

        test();

        while(1);

        return 0;

}

AVRNEWER 发表于 2005-12-16 09:59:54

studio下的汇编



14:               cbi(PORTD,DQ);

+0000002C:   9894      CBI   0x12,4         Clear bit in I/O register

146: Error: Invalid line

+0000002D:   EC88      LDI   R24,0xC8         Load immediate

90: Error: Invalid line

+0000002E:   958A      DEC   R24            Decrement

+0000002F:   F7F1      BRNE    -0x02            Branch if not equal

16:               sbi(PORTD,DQ);

+00000030:   9A94      SBI   0x12,4         Set bit in I/O register

146: Error: Invalid line

+00000031:   E083      LDI   R24,0x03         Load immediate

90: Error: Invalid line

+00000032:   958A      DEC   R24            Decrement

+00000033:   F7F1      BRNE    -0x02            Branch if not equal

19:               cbi(DDRD,PD4);//INPUT

+00000034:   988C      CBI   0x11,4         Clear bit in I/O register

20:               sbi(PORTD,PD4);//PULL UP

+00000035:   9A94      SBI   0x12,4         Set bit in I/O register

22:               for(i=0xff;i>0;i--)

+00000036:   EF8F      SER   R24            Load immediate

24:                       if(bit_is_clear(PIND,PD4))

+00000037:   9B84      SBIS    0x10,4         Skip if bit in I/O register set

+00000038:   C012      RJMP    +0x0012          Relative jump

22:               for(i=0xff;i>0;i--)

+00000039:   5081      SUBI    R24,0x01         Subtract immediate

+0000003A:   F7E1      BRNE    -0x04            Branch if not equal

31:               if(bit_is_set(PIND,PD4))

+0000003B:   B380      IN      R24,0x10         In from I/O location

+0000003C:   2799      CLR   R25            Exclusive OR

+0000003D:   E024      LDI   R18,0x04         Load immediate

+0000003E:   9596      LSR   R25            Logical shift right

+0000003F:   9587      ROR   R24            Rotate right through carry

+00000040:   952A      DEC   R18            Decrement

+00000041:   F7E1      BRNE    -0x04            Branch if not equal

+00000042:   019C      MOVW    R18,R24          Copy register pair

+00000043:   7021      ANDI    R18,0x01         Logical AND with immediate

+00000044:   7030      ANDI    R19,0x00         Logical AND with immediate

+00000045:   FF80      SBRS    R24,0            Skip if bit in register set

+00000046:   C00B      RJMP    +0x000B          Relative jump

33:                       sbi(DDRD,PD4);//OUTPUT

+00000047:   9A8C      SBI   0x11,4         Set bit in I/O register

34:                       return 0;                //返回0

+00000048:   E080      LDI   R24,0x00         Load immediate

+00000049:   E090      LDI   R25,0x00         Load immediate

+0000004A:   9508      RET                      Subroutine return

146: Error: Invalid line

+0000004B:   EA80      LDI   R24,0xA0         Load immediate

90: Error: Invalid line

+0000004C:   958A      DEC   R24            Decrement

+0000004D:   F7F1      BRNE    -0x02            Branch if not equal

27:                               sbi(DDRD,PD4);//OUTPUT

+0000004E:   9A8C      SBI   0x11,4         Set bit in I/O register

28:                               return 1;

+0000004F:   E081      LDI   R24,0x01         Load immediate

+00000050:   E090      LDI   R25,0x00         Load immediate

+00000051:   9508      RET                      Subroutine return

36:               sbi(DDRD,PD4);//OUTPUT

+00000052:   9A8C      SBI   0x11,4         Set bit in I/O register

37:               return 0;

+00000053:   01C9      MOVW    R24,R18          Copy register pair

38:       }

+00000054:   9508      RET                      Subroutine return

---- No Source ------------------------------------------------------------------------------------

+00000055:   9508      RET                      Subroutine return

@00000056: main

---- asm.c ----------------------------------------------------------------------------------------

40:       int main(void)

41:       {

+00000056:   E5CF      LDI   R28,0x5F         Load immediate

+00000057:   E0D2      LDI   R29,0x02         Load immediate

+00000058:   BFDE      OUT   0x3E,R29         Out to I/O location

+00000059:   BFCD      OUT   0x3D,R28         Out to I/O location

42:               sbi(DDRD,PD4);                //dq设置为输出

+0000005A:   9A8C      SBI   0x11,4         Set bit in I/O register

43:               test();

+0000005B:   DFD0      RCALL   -0x0030          Relative call subroutine

44:               while(1);

+0000005C:   CFFF      RJMP    -0x0001          Relative jump

AVRNEWER 发表于 2005-12-16 10:01:43

顺便问一下,调用延时函数的时候为什么会出现下面的情况Error: Invalid line

146: Error: Invalid line

+00000031:   E083      LDI   R24,0x03         Load immediate

90: Error: Invalid line

+00000032:   958A      DEC   R24            Decrement

+00000033:   F7F1      BRNE    -0x02            Branch if not equal

HJJourAVR 发表于 2005-12-16 10:40:33

1 sbi/cbi在那里支持? WINAVR20050214并没有集成这个宏.

2 什么型号的AVRMCU?

AVRNEWER 发表于 2005-12-16 10:44:46

sbi/cbi是我自己定义的加在头文件 sfr_defs.h 里面了



#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))

#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))

HJJourAVR 发表于 2005-12-16 11:45:48

人工智能 AI.

估计是编译器无法推测 你这段程序的流向 ,故无法进行全面的有效的优化。



我也觉得你这段程序是莫名其妙的------出口永远是

      sbi(DDRD,PD4);//OUTPUT

      return x;      //返回x

你想干什么?

不如先优化你的程序,再试一试?



当 return的值一样时,优化就没问题。





ps 延时函数没问题,最好使用makefile来设定,不要使用AVRSTUDIO的设定。

yanglei920509 发表于 2014-4-22 15:02:20

路过看看

tcltiant 发表于 2014-4-25 18:13:10

路过看看
页: [1]
查看完整版本: 在winavr中同一个语句:if(PIND&(1