计数循环在STM32F103C8上不匹配?预取缓冲区不能正常工作?

时间:2018-04-23 17:51:44

标签: stm32

我一直在争论这个话题。我在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");
}

2 个答案:

答案 0 :(得分:2)

这是因为FLASH存储器的等待状态在72MHz运行。阅读文档很好:)。

将代码放入SRAM中,您将获得所需的信息。

为了FLASH的良好结果,在冲洗管道时避免分支。这种延迟只适用于非常短的延迟。任何更长的时间都应该使用计时器来实现。

我建议避免代码延迟。

PS St-Link无罪:)。

答案 1 :(得分:0)

我一直在做几次测试。我的第一个结论是开销取决于内存上指令的对齐(预取缓冲区是2x64bits)。 其次,由于分支的确定性行为,在采用时,它会刷新预取缓冲区以及管道。