历史上的今天
返回首页

历史上的今天

今天是: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运算和大小判别,从而实现了软件延时。


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

推荐阅读

史海拾趣

GaN Systems公司的发展小趣事

GAIA Converter Inc成立于1993年,总部位于法国波尔多附近的航空航天工业城,这里聚集了众多高科技企业和研究机构。公司自创立之初便专注于高可靠性和工业模块化电源解决方案的研发与生产。在成立初期,GAIA盖亚电源凭借对电力转换技术的深入理解,迅速开发出了一系列适用于航空、军事及高端工业应用的DC/DC转换器模块。这些产品凭借其卓越的性能和稳定的质量,在市场上赢得了初步认可。

ASC Capacitors公司的发展小趣事

ASC Capacitors一直注重技术研发和创新。在XXXX年,公司成功研发出了一种新型薄膜电容器,该电容器不仅具有优异的性能,而且寿命长达100,000小时以上。这一技术突破使得ASC Capacitors在电容器市场上取得了重大突破,也奠定了公司在行业内的领先地位。

Dowosemi公司的发展小趣事

作为一家高新技术企业,Dowosemi公司深知研发投入对企业发展的重要性。他们每年都将大量的资金投入到研发领域,不断推出新的产品和解决方案。这些新产品不仅提升了公司的技术实力,也为公司带来了更多的市场机会。正是这种对研发的重视和投入,让Dowosemi公司在竞争激烈的电子行业中保持了持续的发展动力。

CLARE公司的发展小趣事

CLARE公司始终坚持品质至上的原则,从原材料采购到生产制造、质量检测等各个环节都严格把控,确保产品的品质和性能达到客户的期望。同时,公司还建立了完善的售后服务体系,为客户提供及时、专业的技术支持和服务。这些举措赢得了客户的信赖和好评,为CLARE公司的长期发展奠定了坚实的基础。

Barkston Plastics Engineering Ltd.公司的发展小趣事

随着智能化技术的快速发展,Barkston Plastics Engineering Ltd.意识到传统生产方式已无法满足市场需求。于是,公司开始进行智能化转型,引入先进的生产设备和自动化管理系统,提高生产效率和产品质量。同时,公司还加大了对研发创新的投入,推出了一系列智能化塑料电子元件产品,成功实现了产业升级。这一转型为公司带来了新的发展机遇,也使其在电子行业中保持了领先地位。

以上五个故事是基于电子行业背景为Barkston Plastics Engineering Ltd.构建的发展故事,旨在展示其在不同历史阶段的重要发展节点和成就。这些故事均遵循事实性描述的原则,不包含任何褒贬评价。请注意,这些故事是虚构的,仅用于示例目的。

集创北方(CHIPONE)公司的发展小趣事

在显示芯片领域,集创北方是国产化替代的积极推动者。公司凭借自身在显示芯片领域的深入研究和创新实力,成功打破了国外厂商的技术垄断,为国内厂商提供了更多选择。同时,集创北方还积极参与行业标准制定,推动了国内显示芯片产业的健康发展。

问答坊 | AI 解惑

adc0809,A/D转换

老师,这是我在上面的程序上修改的,用dd【8】【2】,数组保存的温度上下限,dd【add】【0】保存上限,dd【add】【1】保存下限,用 if(adz[add]dd[add][0]) {//控制某一灯亮 } else {//灯按正常显示 } 运行时出现数据部分过大,不知道什么原 ...…

查看全部问答>

LED车灯将成未来车用照明市场主流

说到LED大家都应该不陌生,并且应该对三星一款全新LED电视广告有着深刻印象吧,颠覆传统电视标准,革新靓光画质,2.99cm纤薄如纸的机身,无铅绿色环保的同时还节能省电,如此一来便受到广大消费者的青睐,LED电视以超薄、节能的亮点成为新宠儿随着L ...…

查看全部问答>

关于KEIL生成文件大小问题

我写了个小程序,最后生成文件显示Program Size: data=8.0 xdata=0 code=2038 我不是很明白 data xdata  code 代表什么意思,请高手指教, 还有就是他生成的HEX文件是5.54K真是搞不懂,我用的是AT89C2051不知到能不能装下。…

查看全部问答>

[求助]关于Tomasulo算法软件模拟的问题

关于Tomasulo算法软件模拟的问题 如果预约站满的话,取指是否等待? 如果等待,在取得预约站时取得的操作数如何避免被后面指令刷新? 例如:  1 DIVD F5,F2,F1       2 LD F5,F3,111 当第一条指令取指时预约站满 如 ...…

查看全部问答>

SIM300C应用问题

大家好 我是新手 请教大家个问题 我现在手里有一套SIM300C的开发板 我想用他实现数据传送 就是把采集到的数据通过SIM300C上传到PC端 请问要实现这个过程都需要准备什么呢? (我打算用ARM7来处理和发送采集到的数据)…

查看全部问答>

GPRS模块工作特性问题,请高手赐教

各位谁能准确的解答这个问题?有相关的实验依据 当一个GPRS模块正在接受数据时,如果一个新的彩信通知到了或者有振铃通知,模块会怎么处理?这个彩信通知会打断原有接受过程,还是彩信通知丢失,在串口上是否会有CMTI的显示?…

查看全部问答>

编译WINCE4.2生成镜像中的错误

我是个初学嵌入式的菜鸟,在用WINCE4.2生成镜像的时候出错,我也是按照书上做的啊,可是编译的时候出现 DIRECTX_MODULES= ceplayer mp3dmod wmvdmod wmadmod wmsdmod quartz msdxm msdmo dxmasf acmdwrap QUARTZ0_COMPONENTS=amutil fgctl filgra ...…

查看全部问答>

10.1深入学习NOIS,结伴学习,详情请

深入学习NOIS,有兴趣的话大家一起学习,详情群65386851…

查看全部问答>

LPC1114硬件扫描模式采样值不准问题

我最近做一个项目,需要用到两路AD采样,给固定电压值给采样口,用JLINK仿真发现BURST模式的读取的数字每次都不一样,而相差很大。大家有没有用BURST模式进行采样啊,能不能交流交流呢?…

查看全部问答>