Dav*_*ili 3 assembly loops avr delay
一个在线延时循环发电机给了我0.5秒的运行时间为频率为16MHz运行该芯片延迟循环。
我心中的问题是:
一开始加载的值究竟是如何计算的?
ldi r18, 41
ldi r19, 150
ldi r20, 128
L1: dec r20
brne L1
dec r19
brne L1
dec r18
brne L1
Run Code Online (Sandbox Code Playgroud)小智 5
要准确回答您的问题:
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
Run Code Online (Sandbox Code Playgroud)
该循环将执行 256 次,即 DEC 的 256 个周期和 BRNE 的 512 个周期,总共 768 个周期。在 16MHz,那是 48us。
将其包装在外部延迟循环中:
ldi r7 10
ldi r8 0
L1: dec r8
brne L1
dec r7
brne L1
Run Code Online (Sandbox Code Playgroud)
您可以看到,每次内循环计数器达到 0 时,外循环计数器都会递减。因此,在我们的示例中,外循环 DEC/BRNE 将发生 10 次(768 个周期),而内循环将发生 10 x 256 次,因此此循环的总时间为 10 x 48us + 48us 为 528us。同样对于 3 个嵌套循环。
从这里开始,计算每个循环应该执行多少次以实现所需的延迟是微不足道的。这是外循环可以执行的迭代次数少于所需时间的最大次数,然后抽出该时间,对下一个嵌套循环执行相同操作,依此类推,直到最内循环填满剩余的少量。