STM32阻塞延迟与禁用的中断不一致

时间:2017-02-16 02:31:15

标签: timer stm32 stm32f4 stm32f0

我在STM32F0xx micro上运行,我有以下代码,只需使用阻塞延迟切换引脚(是的,我知道阻塞延迟很糟糕,不在这里指出)。

uint32_t ticks = 0;
// Disable interrupts
__disable_irq();
for (int bit = 0; bit < 10; bit++) {
  // Toggle pin high
  WritePin(GPIO_PIN_SET);
  ticks = 500;
  while (ticks--) {
    __NOP();
  }
  // Toggle pin low
  WritePin(GPIO_PIN_RESET);
  ticks = 500;
  while (ticks--) {
    __NOP();
  }
  // Repeat
  WritePin(GPIO_PIN_SET);
  ticks = 500;
  while (ticks--) {
    __NOP();
  }
  WritePin(GPIO_PIN_RESET);
  ticks = 500;
  while (ticks--) {
    __NOP();
  }
}
__enable_irq();

我禁用中断以确保此时没有其他任何事情发生。当我对这些波形进行调整时,我会看到10个时钟周期;但是,这些波形的周期并不完全匹配。所有偶数波形(0,2,4,6,8)具有相同的周期,并且所有奇数波形(1,3,5,7,9)具有相同的周期,但偶数和奇数波形相差很大(%12)。偶数波形与第一次延迟切换相关,而在for循环中与奇数相关。我不知道为什么这些会在一段时间内有所不同。有人有任何见解吗?

1 个答案:

答案 0 :(得分:3)

请参阅有关ARM Cortex-M0内核NOP的文档:

http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0497a/CHDJJGFB.html

  

操作

     

NOP不执行任何操作,并且不保证是耗时的。   处理器可能会在它到达之前将其从管道中删除   执行阶段

     

使用NOP进行填充,例如放置后续指令   在64位边界上。

为此,您必须添加其他变化因素,例如管道重新填充(由于分支)和闪存等待状态(因为不同循环中的指令块可能无法完全对齐闪存加速器而变化)。

执行精确延迟的唯一可靠方法是使用计时器。