打印
[AT32F403/403A]

for 循环,延时的时间长度相差两三倍。

[复制链接]
1233|39
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
玄德|  楼主 | 2024-10-8 16:31 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 玄德 于 2024-10-9 11:13 编辑


使用 AT32F403ACGT7 芯片,for( i=0; i <0x8000000; i++   ); 语句,
做不考虑精度的延时,比如 LED 亮、灭时间的长短。

以前正常的版本是 v31,亮灭的时间长短经过调整,一直很合适。
复制 v31 整个工程项目,命名为 v32 。做了少量的修改,我发誓和下面的问题无关。

现在,同样的 I-A-R 版本,同一块硬件电路板,同样的 for 语句,下载、运行,
发现 LED 亮灭时间明显变长,v32 的时间是 v31 的 2~3 倍,很明显。

顺便说一下,同样的情况,大概五六年前在 STM32F407VGT6 芯片上也遇到过。

下面的帖子将把我的努力和结果发上来,供大家参考、会诊。



使用特权

评论回复
沙发
玄德|  楼主 | 2024-10-8 16:32 | 只看该作者
本帖最后由 玄德 于 2024-10-8 16:39 编辑


首先想到的就是观察 for 语句的汇编语言是否相同。
分别打开 v31、v32 ,发现汇编语句是完全相同的。

如下图:



证明不是汇编造成的问题。


使用特权

评论回复
板凳
玄德|  楼主 | 2024-10-8 16:33 | 只看该作者
本帖最后由 玄德 于 2024-10-8 16:42 编辑


其次就怀疑时钟设置不同,v31 的频率高, v32 不知什么原因变低了。利用芯片的 pA8 引脚,输出内部的时钟信号,分频选择为 4 分频。

用示波器观察,无论 v31 还是 v32,pA8 输出的都是 48MHz 时钟,如下图:





使用特权

评论回复
地板
玄德|  楼主 | 2024-10-8 16:44 | 只看该作者

至此再想不到其他原因。
特来求助。
@ArteryMCU     @ArterySW




使用特权

评论回复
5
Diyer123| | 2024-10-8 20:20 | 只看该作者
很可能是:
1-中断服务。验证方法是关闭全局中断
2-Flash访问时间参数不同

使用特权

评论回复
6
mbutterfly| | 2024-10-9 12:30 | 只看该作者
做了啥修改?可以把做的修改去掉,看时间一样不,如果一样,那一点点添加修改,直到不一样的时候,就找到添加了啥,会改变时间。

使用特权

评论回复
7
muyichuan2012| | 2024-10-9 15:07 | 只看该作者
这是合理现象,每次for循环结束都会多一些loop back指令。没有汇编指令精炼。
如果要做延时函数,最好是使用定时器或systick做延时函数。或者尝试使用-o3优化等级再试试

使用特权

评论回复
8
英雄本色2022| | 2024-10-9 15:27 | 只看该作者
会不会是两个代码位置不一样,导致指令预取缓存结果不一样

使用特权

评论回复
9
xionghaoyun| | 2024-10-9 16:59 | 只看该作者
emm 别用delay

使用特权

评论回复
10
cooldog123pp| | 2024-10-10 09:28 | 只看该作者
这种for循环的延时确实不同单片机不一样,单片机里面也是电路,哪怕你的时钟设置的是一样的 也会有差别的,你要重新测试一个值,最好用systick,或者定时器。

使用特权

评论回复
11
ZALIN| | 2024-10-10 10:10 | 只看该作者
32位指令作为转移目标地址,并且不在4字节对齐地址时,会插入额外的取指等待周期,不过相差2~3倍有点夸张了
这种延时与芯片的具体实现有关,比如有指令高速缓存时,可能就没有这个额外的取指等待周期

使用特权

评论回复
12
ZALIN| | 2024-10-10 10:17 | 只看该作者
早期的403、413等的取指零等待是用SRAM作为指令存储器实现的,后期的带指令预取或者也有高速指令缓存,指令执行的行为是有差异的

使用特权

评论回复
13
菜鸟的第一步| | 2024-10-10 14:03 | 只看该作者
这种阻塞形式的延时会受很多因素影响,特别是有中断就会打断

使用特权

评论回复
14
jtracy3| | 2024-11-7 21:43 | 只看该作者
编译器可能会对for循环进行优化,特别是当循环体内没有实际的操作或者操作非常简单时。优化后的代码可能会减少循环迭代的次数,从而缩短延时时间。

使用特权

评论回复
15
ccook11| | 2024-11-8 09:36 | 只看该作者
编译器可能会对代码进行优化,导致实际执行的指令数量与预期不同。例如,编译器可能会合并某些操作或删除未使用的变量。

使用特权

评论回复
16
jtracy3| | 2024-11-8 11:00 | 只看该作者
编译器可能会对循环进行优化,导致实际执行的指令数少于预期,从而影响延时的准确性。可以通过关闭编译器优化或使用特定的编译器指令来避免这种情况。

使用特权

评论回复
17
jonas222| | 2024-11-8 12:10 | 只看该作者
建议使用单片机内部的定时器/计数器模块来产生延时,而不是依赖for循环。

使用特权

评论回复
18
gygp| | 2024-11-8 14:50 | 只看该作者
如果for循环中涉及到外设的访问(如I/O操作),外设的响应时间和访问速度也会对延时长度产生影响。

使用特权

评论回复
19
cashrwood| | 2024-11-8 16:38 | 只看该作者
在编译设置中选择较低的优化级别或完全关闭优化。

使用特权

评论回复
20
wengh2016| | 2024-11-8 20:36 | 只看该作者
不同的编译器和硬件平台可能会对for循环的执行产生不同的影响。例如,某些编译器可能会生成更高效的代码来执行循环,而某些硬件平台可能具有更快的指令执行速度。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:有事请找 xuander

153

主题

5921

帖子

44

粉丝