历史上的今天
今天是:2025年02月25日(星期二)
2020年02月25日 | IAR FOR AVR 编译环境中优化要注意的问题
2020-02-25 来源:eefocus
简介:本文介绍了使用IAR编写AVR程序时优化的问题。
在用IAR开发C程序时,开发环境提供了一个优化的选项,有4档,即None/Low/Medium/High。但在实际应用时要注意,不是什么情况下都可以进行优化,有时在没有优化时运行的代码,优化后则不能正常运行了。(这个现象在用WINAVR软件开发时更严重,本人就是因为觉得WINAVR这个问题比较严重才转到IAR环境的)
例如,下面的程序是让LED闪烁:
#include //定义一个宏操作 #define _BV(x) (1< //定义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++); } } 在没有优化时,或者优化级别为Low或Medium时,可以看出LED是在闪烁,或者用示波器可以测出,PB0输出的是一个频率较低的方波。 但如果我们选了优化级别为High,这时就看不出来LED在闪烁了,或者用示波器可以测出,PB0输出的是一个频率较高的方波。 从C语言是看不出任何问题的,只能从编译后的汇编语言找问题。首先看一下在优化级别为Medium时,main函数对应的机器码,如下图所示: 从汇编代码中,我们可以看出,当对PB0端口操作后,程序进行了延时,(R25,R24)寄存器对作为变量k,进行了加1运算,和判断大小。 但如果我们选择了优化级别为High时,main函数的代码就变成如下图所示: 很明显看出,当对PB0端口设置为0后,紧接的下一条指令就是设置1的指令,然后又跳转回来,中间的延时完全被优化掉了,当然运行结果就是在PB0端口上看到一个频率较高的方波了。 如果我们确实需要对代码优化,可又需要这样的软件延时,那应该怎么办呢?答案是只要将上面的变量k定义成volatile类型即可,修改后的程序如下: #include //定义一个宏操作 #define _BV(x) (1< //定义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函数对应的汇编代码如下: 从汇编代码中,我们可以清楚地看见,当进行了PB0端口操作后,程序调用Subroutine0和Subroutine1分别完成加1运算和大小判别,从而实现了软件延时。 总之,当遇到优化后与优化前代码实现的功能不一样时,不妨从汇编代码进行分析一下。这样有利于解决问题。
史海拾趣
|
老师,这是我在上面的程序上修改的,用dd【8】【2】,数组保存的温度上下限,dd【add】【0】保存上限,dd【add】【1】保存下限,用 if(adz[add]dd[add][0]) {//控制某一灯亮 } else {//灯按正常显示 } 运行时出现数据部分过大,不知道什么原 ...… 查看全部问答> |
|
说到LED大家都应该不陌生,并且应该对三星一款全新LED电视广告有着深刻印象吧,颠覆传统电视标准,革新靓光画质,2.99cm纤薄如纸的机身,无铅绿色环保的同时还节能省电,如此一来便受到广大消费者的青睐,LED电视以超薄、节能的亮点成为新宠儿随着L ...… 查看全部问答> |
|
我写了个小程序,最后生成文件显示Program Size: data=8.0 xdata=0 code=2038 我不是很明白 data xdata code 代表什么意思,请高手指教, 还有就是他生成的HEX文件是5.54K真是搞不懂,我用的是AT89C2051不知到能不能装下。… 查看全部问答> |
|
关于Tomasulo算法软件模拟的问题 如果预约站满的话,取指是否等待? 如果等待,在取得预约站时取得的操作数如何避免被后面指令刷新? 例如: 1 DIVD F5,F2,F1 2 LD F5,F3,111 当第一条指令取指时预约站满 如 ...… 查看全部问答> |
|
大家好 我是新手 请教大家个问题 我现在手里有一套SIM300C的开发板 我想用他实现数据传送 就是把采集到的数据通过SIM300C上传到PC端 请问要实现这个过程都需要准备什么呢? (我打算用ARM7来处理和发送采集到的数据)… 查看全部问答> |
|
各位谁能准确的解答这个问题?有相关的实验依据 当一个GPRS模块正在接受数据时,如果一个新的彩信通知到了或者有振铃通知,模块会怎么处理?这个彩信通知会打断原有接受过程,还是彩信通知丢失,在串口上是否会有CMTI的显示?… 查看全部问答> |
|
我是个初学嵌入式的菜鸟,在用WINCE4.2生成镜像的时候出错,我也是按照书上做的啊,可是编译的时候出现 DIRECTX_MODULES= ceplayer mp3dmod wmvdmod wmadmod wmsdmod quartz msdxm msdmo dxmasf acmdwrap QUARTZ0_COMPONENTS=amutil fgctl filgra ...… 查看全部问答> |
|
我最近做一个项目,需要用到两路AD采样,给固定电压值给采样口,用JLINK仿真发现BURST模式的读取的数字每次都不一样,而相差很大。大家有没有用BURST模式进行采样啊,能不能交流交流呢?… 查看全部问答> |




