我在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循环中与奇数相关。我不知道为什么这些会在一段时间内有所不同。有人有任何见解吗?
答案 0 :(得分:3)
请参阅有关ARM Cortex-M0内核NOP
的文档:
http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0497a/CHDJJGFB.html
操作
NOP不执行任何操作,并且不保证是耗时的。 处理器可能会在它到达之前将其从管道中删除 执行阶段。
使用NOP进行填充,例如放置后续指令 在64位边界上。
为此,您必须添加其他变化因素,例如管道重新填充(由于分支)和闪存等待状态(因为不同循环中的指令块可能无法完全对齐闪存加速器而变化)。
执行精确延迟的唯一可靠方法是使用计时器。