我正在 STM32F4 CPU 上开发一个项目,生成信号。
我在 STM32 上的 CPU 时钟(无预分频器)上有一个通用定时器,在溢出时触发中断,之后使用 GPIO 生成周期性信号。
我需要在非常精确的时间触发 GPIO(基本上低至一个 CPU 周期精度)。我已经设法通过设置优先级和 al 将这种抖动减少到 +-5 个周期,但是这种抖动存在,具体取决于 CPU 正在做什么。
我需要补偿这几个周期的抖动。只要我在精确的时间切换 GPIO,增加几个周期的延迟就不是问题。
我的想法是读取计数器的当前值,并有一个 FIXED_NUMBER-CURRENT_VALUE 时间的活动循环,确保我会在精确的时间退出循环。
然而,在 C 中做一个简单的循环——作为一个 FOR 循环,或者一个 while(counter->value < TARGET) 不起作用,因为它增加了抖动而不是减少它。
我做错了什么/天真吗?我应该在汇编中这样做吗?这与 C 有何不同(我用 GCC 检查了反汇编以检查循环没有被优化掉,也没有达到内存?)
(我确保使用空的、未优化但未命中内存循环体)
编辑:在 AVR 上查看这个示例(我知道更稳定) 参见示例http://lucidscience.com/pro-vga%20video%20generator-7.aspx (搜索“jitter”)
edit2:我在程序集中尝试了一个简单的循环,例如(r0 是我的计数器,要等待的周期数,在寄存器中)
loop : SUBS r0,#1 ; tried with 2 also
BGE loop
而且,没有它,抖动会更好。
总而言之,我已经知道我应该延迟多少。我只需要一种方法让代码分支在一个案例中可靠地消耗 N 个周期,在另一个案例中消耗 M 个周期。不幸的是,单独的分支似乎不起作用,因为管道重新填充似乎不需要可靠数量的周期,而条件表达式也不是,因为它们总是需要相同数量的周期(有时什么都不做)。
从 RAM 而不是闪存运行会提高一致性吗?(NB stm32f4 有一个闪存预取..)