安online delay loop generator给我这个运行在 16MHz 的芯片的延迟循环为 0.5 秒。
我心中的问题是:
- 如果寄存器变为负数,分支是否会继续分支?
如何准确计算一开始加载的值?
ldi r18, 41 ldi r19, 150 ldi r20, 128 L1: dec r20 brne L1 dec r19 brne L1 dec r18 brne L1
最佳答案
准确回答您的问题:
1:DEC指令不知道“有符号”数字,它只是递减一个 8 位寄存器。二进制补码算法的奇迹使这项工作在环绕(0x00 -> 0xFF,与 0 -> -1 的位模式相同)。 DEC 指令还在状态寄存器中设置 Z 标志,BRNE用于确定是否应该发生分支。
2:从AVR手册可以看出DEC是单循环指令。 BRNE在不分支的时候也是一个周期,分支的时候是2个周期。因此,要计算循环的时间,您需要计算每条路径的执行次数。
考虑单个 DEC/BRNE 循环:
ldi r8 0
L1: dec r8
brne L1
这个循环将恰好执行 256 次,即 DEC 的 256 个周期和 BRNE 的 512 个周期,总共 768 个周期。在 16MHz 时,即 48us。
将其包装在外部延迟循环中:
ldi r7 10
ldi r8 0
L1: dec r8
brne L1
dec r7
brne L1
您可以看到,每次内循环计数器达到 0 时,外循环计数器就会递减。因此在我们的示例中,外循环 DEC/BRNE 将发生 10 次(768 个周期),内循环将发生 10 x 256 次,所以这个循环的总时间是 10 x 48us + 48us 为 528us。对于 3 个嵌套循环也是如此。
从这里开始,计算每个循环应该执行多少次才能达到所需的延迟是微不足道的。这是外部循环可以少于所需时间的最大迭代次数,然后将这段时间移出,对下一个嵌套循环执行相同的操作,依此类推,直到最里面的循环填满剩下的少量。
关于loops - AVR 组装 BRNE 延迟循环如何工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47453737/