1

I am running on an STM32F0xx micro, and I have the following code that simply toggles a pin using blocking delays (yes I know blocking delays are bad, not point here).

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();

I disable interrupts to make sure nothing else is going on at this point. When I scope these waveforms, I see 10 clock periods; however, the periods of these waveforms do not all match. All even waveforms (0,2,4,6,8) have the same period, and all odd waveforms (1,3,5,7,9) have the same period, but the even and odd waveforms differ by a significant amount (%12). The even waveforms correlate to the first delay toggling, and odd to the second in the for loop. I do not have any idea why these would differ in period. Anyone have any insight here?

4

1 回答 1

4

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

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

手术

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

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

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

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

于 2017-02-16T07:16:02.987 回答