首页 > 解决方案 > PIC 汇编语言 - decfsz 循环

问题描述

我正在使用 Microchip 的 PIC 18F 微控制器来连续生成矩形信号。信号本身的代码位于label5.

我需要生成这个信号的 255*20 个脉冲。所以基本上,我需要在标签 5 处重复前 4 行的指令 255*20 次。因为我不能有高于 2^8 的数字,所以我需要这样写数字。

    label5  BSF portd,5
            call timer1
            BCF portd,5
            call timer2

在下面的代码中,我试图实现这种行为。我给variable1了 255 的值,然后从这个值递减直到variable1为零,在这种情况下,我返回label2并重新启动程序。每次我减少variable1我打电话label4。类似的事情发生在label4。这里我有另一个变量 ,variable2它也会递减,直到它达到零(这里是主信号生成程序,每次递减操作都重复),在这种情况下,程序返回。

有人可以告诉我我是否走在正确的轨道上吗?


label2      movlw .255
            movwf variable1

label3      call label4
            decfsz variable1,1
            goto label3

            goto label2

; """"""""""""""

label4      movlw .20
            movwf variable2

label5      BSF portd,5
            call timer1
            BCF portd,5
            call timer2
            decfsz variable2,1
            goto label5
            return

            end

    ```

标签: loopsassemblypicmicrochip

解决方案


一般建议是使用定时器来消耗时间,有些人认为中断有可能使芯片处于低功耗模式。但是对于像 PIC18 这样的处理器,您可以在其中计算指令并非常准确地确定执行时间,以使用简单的循环来消耗时间。

有两种方法可以使循环花费更长的时间,而且我对我的 PIC 编码非常生疏,所以考虑一下这个伪代码:

variable2 = 0
label:
  decfsz variable2,1
  goto label

那基本上是256个循环是吗?你可以计算指令,包括额外的时钟或任何时间为零的时间......

variable2 = 0
label:
  nop
  nop
  decfsz variable2,1
  goto label

添加 nop 会消耗更多时间(是的,我可能仍然不明白你是在燃烧还是只是想要更多循环)。

或者如果你想让它更多循环并且你只有 8 位可以计算然后嵌套循环

variable1 = 20
variable2 = 0
outer:
inner:
  ; other stuff goes here?
  decfsz variable2,1
  goto inner
  decfsz variable1,1
  goto outer

内循环将计数 256 次,外循环将计数 20 所以你得到 20*256 总循环

我已经使用这种方法来制作非常准确的信号,这些信号无法通过在该处理器上使用定时器来产生更有效的指令集和更快的处理器需要使用定时器完成相同的事情,即使可能的。但是您会改为购买具有计时器外围设备的产品,该外围设备可以执行您正在尝试执行的操作或其中的一部分,例如红外遥控器,您可以获得一些 ST 产品,它们具有两个计时器输出并在芯片中具有与门,所以你可以有一个硬件生成的载波信号和一个硬件生成的门,但通过软件生成门的持续时间。有了这张图片,我只是有一些小循环来做同样的事情,而且都是通过计数指令来计时的。

我不会在 cortex-m,也许是 msp430,也许是 avr 上使用这种方法,但不是流水线的东西,也不是从别人那里购买 IP 的东西(arm 不制造芯片,st 和 nxp 以及其他制造芯片和只需从 arm 购买 IP 以及芯片的大部分其余部分都不是 arm IP,并且每个供应商都可以在获得 IP 时调整 IP,因此不同芯片中的相同内核(例如 cortex-m0+ rev xy)不一定表现得很好相同)。


推荐阅读