我一直在争论这个话题。我在Atollic上使用STM32F103C8和ST-Link V2。
我在装配时做了一些延迟功能。我一直在ATSAM上使用示波器测试这段代码(84 MHz并且工作正常),在STM32上我也使用CPU寄存器来查看调试的确切周期数 - DWT(数据观察点和跟踪)。 p>
当我将STM32 CPU时钟配置为24MHz时,我为时间延迟设计的确切周期数是正确的。它是1个循环用于递减汇编指令,2个循环用于分支指令(在大多数情况下)。因此,主循环花费3个周期。
当我将CPU时钟更改为72MHz时,每个汇编指令花费两倍的时间!
那么,prefecth缓冲区是2x64位,等待状态不应该影响这个微控制器上的执行CPU时间(不考虑预测或其他代码停顿)?应该吗?
好吧,在24MHz时,闪存没有等待状态,时钟越高,CPU就不应该等待执行任何代码。应该吗?
我使用发布十六进制闪烁以查看一些差异,但没有找到任何差异。
我唯一的解释是ST-LINK V2?我对吗?
非常感谢您的时间和精力。
这是重要的代码:
asm (".equ fcpu, 72000000\n\t"); //72 MHz
asm (".equ const_ms, fcpu/3000 \n\t");
asm (".equ const_us, fcpu/3000000 \n\t");
void delay_us(uint32_t valor)
{
asm volatile ( "movw r1, #:lower16:const_us \n\t"
"movt r1, #:upper16:const_us \n\t"
"mul r0, r0, r1 \n\t"
"r_us: subs r0, r0, #1 \n\t"
"bne r_us \n\t");
}
void delay_ms(uint32_t valor)
{
asm volatile ("movw r1, #:lower16:const_ms \n\t"
"movt r1, #:upper16:const_ms \n\t"
"mul r0, r0, r1 \n\t"
"r_ms: subs r0, r0, #1 \n\t"
"bne r_ms \n\t");
}
答案 0 :(得分:2)
这是因为FLASH存储器的等待状态在72MHz运行。阅读文档很好:)。
将代码放入SRAM中,您将获得所需的信息。
为了FLASH的良好结果,在冲洗管道时避免分支。这种延迟只适用于非常短的延迟。任何更长的时间都应该使用计时器来实现。
我建议避免代码延迟。
PS St-Link无罪:)。
答案 1 :(得分:0)
我一直在做几次测试。我的第一个结论是开销取决于内存上指令的对齐(预取缓冲区是2x64bits)。 其次,由于分支的确定性行为,在采用时,它会刷新预取缓冲区以及管道。