在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. 请记得将公司名称及客户名称等资料删除,并注明你的代码是使用何种版本软件编写的。
注:你可以使用编辑功能修改,并将这段红色文字删除。谢谢你的支持! 你改為這樣if(PIND&0x10)就會細很多了!!
因為系統幫你做了移位運算1<<PD4!! 楼上解释不通吧,那第二条语句怎么就两句汇编呢
109: if(PIND&(1<<PD4))
+0000020C: 9B84 SBIS 0x10,4 Skip if bit in I/O register set
+0000020D: C002 RJMP +0x0002 Relative jump 改成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 按 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 我想是优化了的结果!
因为你在同一个winavr中,第一次已计算了(PIND&(1<<PD4))
第二次做if(PIND&(1<<PD4))只要做:判断(PIND&(1<<PD4))是否等于1
我从来没有用过汇编(不懂),只用C
希望没有误导你!!!! opt=?
改成 opt=s 看看?
makefile默认是opt=s,不知道楼主用的是那个设定。 我的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;上面,但不知道为什么会有这样的影响,希望大侠释疑 刚才把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 联系上下文。
单单测试这一段代码,并没有顶楼所说的现象。 请看源码,我用的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;
} 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 顺便问一下,调用延时函数的时候为什么会出现下面的情况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 1 sbi/cbi在那里支持? WINAVR20050214并没有集成这个宏.
2 什么型号的AVRMCU? sbi/cbi是我自己定义的加在头文件 sfr_defs.h 里面了
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit)) 人工智能 AI.
估计是编译器无法推测 你这段程序的流向 ,故无法进行全面的有效的优化。
我也觉得你这段程序是莫名其妙的------出口永远是
sbi(DDRD,PD4);//OUTPUT
return x; //返回x
你想干什么?
不如先优化你的程序,再试一试?
当 return的值一样时,优化就没问题。
ps 延时函数没问题,最好使用makefile来设定,不要使用AVRSTUDIO的设定。 路过看看 路过看看
页:
[1]