用AVR Studio + AVRGCC写死循环延时注意了,要加asm("nop");
如题~~~以下是示例代码:
void usDelay(unsigned int dat)
{
while(dat>0){
dat--;
asm("nop");//--如果这里不加上此指令,在调用时,反汇编查看,根本就没有调用usDelay(unsigned int dat);此函数
}
}
不知道大家有没有这种情况? 您觉得您写的这个比avr-gcc的库里面那个好用? aozima 发表于 2013-1-17 23:32 static/image/common/back.gif
您觉得您写的这个比avr-gcc的库里面那个好用?
只是遇到有这种现象提醒一下而已,是编译器的关系 与优化有关,有时就把延时程序嵌入,所以没有CALL的。但仔细瞧,有延时在里面。 #include <avr/io.h>
#include "iolgt8f0xa.h"
#define nIRQ PA0 //JRF模块 中断信号,平时为高电平
#define SDN PA1 //JRF模块 芯片关断模式输入(高电平有效)
#define nSEL PA2 //JRF模块 SPI 片选输入(低电平有效)
#define SCK PA3 //JRF模块 SPI 串口时钟输入
#define SDI PA4 //JRF模块 SPI 串口数据输入
#define SDO PA5 //JRF模块 SPI 串口数据输出
#define Test PA7 //
void usDelay(unsigned int dat)
{
while(dat>0){
dat--;
//asm("nop");//--这里取消与不取消,查看反汇编代码对比一下
}
}
void write_spi(unsigned char dat)
{ //write data into the SPI register
unsigned int i;
PORTA &=~_BV(SCK);//SCLK==0;
for (i=0;i<8;i++)
{
if ((dat & 0x80)==0x80)//判断发送0或发送1
{
PORTA |=_BV(SDI);//SDI==1;
}
else
{
PORTA &=~_BV(SDI);//SDI==0;
}
usDelay(10);
PORTA |=_BV(SCK);//SCLK==1;
dat <<= 1;
usDelay(10);
PORTA &=~_BV(SCK);//SCLK==0;
usDelay(10);
}
}
void MCU_Init(void)
{
DDRA=0xde;
PORTA=0x21;
}
int main(void)
{
MCU_Init();
write_spi(0x55);
while(1)
{
;
}
}
以上代码编译后的反汇编代码如下(已经没有了延时函数的存在):
--- LGT_Test3.c ----------------------------------------------------------------------------------
24: }
+0000004A: 9508 RET Subroutine return
@0000004B: write_spi
27: { //write data into the SPI register
+0000004B: 9813 CBI 0x02,3 Clear bit in I/O register
+0000004C: E020 LDI R18,0x00 Load immediate
+0000004D: E030 LDI R19,0x00 Load immediate
34: if ((dat & 0x80)==0x80)//判断发送0或发送1
+0000004E: FF87 SBRS R24,7 Skip if bit in register set
+0000004F: C002 RJMP PC+0x0003 Relative jump
36: PORTA |=_BV(SDI);//SDI==1;
+00000050: 9A14 SBI 0x02,4 Set bit in I/O register
+00000051: C001 RJMP PC+0x0002 Relative jump
40: PORTA &=~_BV(SDI);//SDI==0;
+00000052: 9814 CBI 0x02,4 Clear bit in I/O register
44: PORTA |=_BV(SCK);//SCLK==1;
+00000053: 9A13 SBI 0x02,3 Set bit in I/O register
48: PORTA &=~_BV(SCK);//SCLK==0;
+00000054: 9813 CBI 0x02,3 Clear bit in I/O register
32: for (i=0;i<8;i++)
+00000055: 5F2F SUBI R18,0xFF Subtract immediate
+00000056: 4F3F SBCI R19,0xFF Subtract immediate with carry
+00000057: 3028 CPI R18,0x08 Compare with immediate
+00000058: 0531 CPC R19,R1 Compare with carry
+00000059: F011 BREQ PC+0x03 Branch if equal
46: dat <<= 1;
+0000005A: 0F88 LSL R24 Logical Shift Left
+0000005B: CFF2 RJMP PC-0x000D Relative jump
+0000005C: 9508 RET Subroutine return
55: DDRA=0xde;
+0000005D: ED8E LDI R24,0xDE Load immediate
+0000005E: B981 OUT 0x01,R24 Out to I/O location
56: PORTA=0x21;
+0000005F: E281 LDI R24,0x21 Load immediate
+00000060: B982 OUT 0x02,R24 Out to I/O location
57: }
+00000061: 9508 RET Subroutine return
@00000062: main
59: {
+00000062: ED8E LDI R24,0xDE Load immediate
+00000063: B981 OUT 0x01,R24 Out to I/O location
56: PORTA=0x21;
+00000064: E281 LDI R24,0x21 Load immediate
+00000065: B982 OUT 0x02,R24 Out to I/O location
61: write_spi(0x55);
+00000066: E585 LDI R24,0x55 Load immediate
+00000067: 940E004B CALL 0x0000004B Call subroutine
+00000069: CFFF RJMP PC-0x0000 Relative jump
61: write_spi(0x55);
+0000006A: 94F8 CLI Global Interrupt Disable
+0000006B: CFFF RJMP PC-0x0000 Relative jump 加volatile修饰 我这也一样 释放版本里没有 调试版本里有 ming180 发表于 2013-1-18 00:53 static/image/common/back.gif
加volatile修饰
voidusDelay(volatile unsigned int usTime)//
{
while(usTime>0){
usTime--;
//asm("nop");//--上面加上volatile修饰后,这里就可以取消了
}
} goodcode 发表于 2013-1-18 00:54 static/image/common/back.gif
我这也一样 释放版本里没有 调试版本里有
ca,Keil写51时如果用高级C编译器,那么Release版本有很大几率不能正常工作。莫非这些嵌入式C编译器的优化有问题? 我觉得是bug WinAVR-20100110 本帖最后由 Gorgon_Meducer 于 2013-1-23 00:38 编辑
的确是bug,确认。仿真器在C单步模式下会有这个问题,进入汇编界面但不则不会出现。 Gorgon_Meducer 发表于 2013-1-23 00:37 static/image/common/back.gif
的确是bug,确认。仿真器在C单步模式下会有这个问题,进入汇编界面但不则不会出现。 ...
哈哈~~~偶像也来发话了."BUG"
页:
[1]