原创 IAR FOR AVR 编译环境中优化要注意的问题

2010-5-24 23:30 7064 8 8 分类: MCU/ 嵌入式

               IAR FOR AVR 编译环境中优化要注意的问题


<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

 


在用IAR开发C程序时,开发环境提供了一个优化的选项,有4档,即None/Low/Medium/High。但在实际应用时要注意,不是什么情况下都可以进行优化,有时在没有优化时运行的代码,优化后则不能正常运行了。(这个现象在用WINAVR软件开发时更严重,本人就是因为觉得WINAVR这个问题比较严重才转到IAR环境的)


例如,下面的程序是让LED闪烁:


#include <ioavr.h>   


 


// 定义一个宏操作


#define _BV(x) (1<<x)


 


// 定义LED对应的端口


#define LED 0


 


int main(void)


{


    unsigned int k;


 


    PORTB = _BV(LED);                   // 端口B的第0位置1


    DDRB  = _BV(LED);                   // 设置端口B的第0位为输出


    while(1)                            // 进入无限循环


    {


        PORTB = PORTB & ~_BV(LED);      // PB0<-0,点亮LED     


 for(k=0;k<60000;k++);    


        PORTB = PORTB | _BV(LED);       // PB0<-1,熄灭LED                 


        for(k=0;k<60000;k++);


    }   


}


 


在没有优化时,或者优化级别为LowMedium时,可以看出LED是在闪烁,或者用示波器可以测出,PB0输出的是一个频率较低的方波。


但如果我们选了优化级别为High,这时就看不出来LED在闪烁了,或者用示波器可以测出,PB0输出的是一个频率较高的方波。


C语言是看不出任何问题的,只能从编译后的汇编语言找问题。首先看一下在优化级别为Medium时,main函数对应的机器码,如下图所示:


 


0b552b97-f337-46c4-b36b-036d56d762f3.JPG 


从汇编代码中,我们可以看出,当对PB0端口操作后,程序进行了延时,(R25,R24)寄存器对作为变量k,进行了加1运算,和判断大小。


但如果我们选择了优化级别为High时,main函数的代码就变成如下图所示:


 


0bed9445-2271-418b-b55f-faa8a3c94f83.JPG


 


很明显看出,当对PB0端口设置为0后,紧接的下一条指令就是设置1的指令,然后又跳转回来,中间的延时完全被优化掉了,当然运行结果就是在PB0端口上看到一个频率较高的方波了。


如果我们确实需要对代码优化,可又需要这样的软件延时,那应该怎么办呢?答案是只要将上面的变量k定义成volatile类型即可,修改后的程序如下:


#include <ioavr.h>   


 


// 定义一个宏操作


#define _BV(x) (1<<x)


 


// 定义LED对应的端口


#define LED 0


 


int main(void)


{


    volatile unsigned int k;


 


    PORTB = _BV(LED);                   // 端口B的第0位置1


    DDRB  = _BV(LED);                   // 设置端口B的第0位为输出


    while(1)                                        // 进入无限循环


    {


        PORTB = PORTB & ~_BV(LED);      // PB0<-0,点亮LED      


 for(k=0;k<60000;k++);


        PORTB = PORTB | _BV(LED);       // PB0<-1,熄灭LED                 


        for(k=0;k<60000;k++);


    }   


}


 


设置优化级别为High时,main函数对应的汇编代码如下:

 


 

04ce0cc8-10a8-4a13-8caa-4a0c6fae0383.JPG


 




bf8b4f71-8eb9-4ac2-802e-ef2ff99cc699.JPG


 


 


从汇编代码中,我们可以清楚地看见,当进行了PB0端口操作后,程序调用Subroutine0Subroutine1分别完成加1运算和大小判别,从而实现了软件延时。


总之,当遇到优化后与优化前代码实现的功能不一样时,不妨从汇编代码进行分析一下。这样有利于解决问题。


 


                               <?xml:namespace prefix = st1 ns = "urn:schemas-microsoft-com:office:smarttags" />2010-5-24

文章评论0条评论)

登录后参与讨论
我要评论
0
8
关闭 站长推荐上一条 /2 下一条