AVR Assembly BRNE 延迟循环如何工作?

Dav*_*ili 3 assembly loops avr delay

一个在线延时循环发电机给了我0.5秒的运行时间为频率为16MHz运行该芯片延迟循环。

我心中的问题是:

  1. 如果寄存器变为负数,分支是否继续分支?
  2. 一开始加载的值究竟是如何计算的?

        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 个嵌套循环。

从这里开始,计算每个循环应该执行多少次以实现所需的延迟是微不足道的。这是外循环可以执行的迭代次数少于所需时间的最大次数,然后抽出该时间,对下一个嵌套循环执行相同操作,依此类推,直到最内循环填满剩余的少量。