Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/loops/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Loops PIC汇编语言-decfsz循环_Loops_Assembly_Pic_Microchip - Fatal编程技术网

Loops PIC汇编语言-decfsz循环

Loops PIC汇编语言-decfsz循环,loops,assembly,pic,microchip,Loops,Assembly,Pic,Microchip,我正在使用Microchip的PIC18F微控制器连续生成矩形信号。信号本身的代码位于标签5 我需要产生这个信号的255*20个脉冲。基本上,我需要重复标签5前4行的说明255*20次。因为我不能有大于2^8的数字,所以我需要这样写数字 label5 BSF portd,5 call timer1 BCF portd,5 call timer2 在下面的代码中,我试图实现这种行为。我给了variable1255的

我正在使用Microchip的PIC18F微控制器连续生成矩形信号。信号本身的代码位于
标签5

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

    label5  BSF portd,5
            call timer1
            BCF portd,5
            call timer2
在下面的代码中,我试图实现这种行为。我给了
variable1
255的值,并从该值开始递减,直到
variable1
为零,在这种情况下,我返回到
label2
并重新启动程序。每次我递减
变量1
时,我调用
标签4
。类似的事情也发生在
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

    ```


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

两个循环的方法需要更长的时间,而且我的PIC编码非常生疏,所以请考虑这个pSueDO代码:

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产品,它有两个定时器输出,并且在芯片中有and门,所以你可以有一个硬件生成的载波信号和一个硬件生成的门,但通过软件生成闸门的持续时间。有了这张图片,我就有了一些小的循环来做同样的事情,所有这些都是通过计算指令来计时的


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

另一种方法是使用值为255*20的16位循环计数器

大概是这样的:

;
;
;
TIMER1_CODE code
timer1:
        return
;
;
;
TIMER2_CODE code
timer2:
        return
;
;   main application
;
MAIN_CODE   code
main:

    bcf     TRISD,5         ; make RD5 an output

ProcessLoop:
    movlw   D'255'          ; Compute loop count
    movwf   PRODL
    movlw   D'20'
    mulwf   PRODL           ; PRODH:PRODL = 255*20 = 5100

OutBitLoop:
    movlw   0xFF            ; Decrement loop count
    addwf   PRODL,F
    addwfc  PRODH,F
    bnc     Stop            ; Stop when done enough loops

    bsf     LATD,5          ; Set output bit high
    call    timer1
    BCF     LATD,5          ; Set output bit low
    call    timer2
    bra     OutBitLoop

    bra     ProcessLoop

Stop:
    bra     Stop
    end
请注意,您发布的代码使用PORTD寄存器设置或清除带有执行读-修改-写操作的操作码的输出位。这是一个错误的选择


对于PIC18F,始终使用输出锁存寄存器(LATD)更改输出位的状态时。

如果我正确理解您的问题,也许我没有理解,但您在这里要做的是在另一个循环中有两个循环,例如255/256限制,您将使用计数为20的循环来包装该循环,有效地给出20*256。@old_timer。是的,这就是我要找的。对不起,英语不是我的第一个语言。那就是你会做的内环变量/登记,如果需要的话,它可能是一个紧环,也许是一个NOP。然后,你会经常看到用零初始化的内部循环,使它减去0xFF,然后下降到0x00,因此你得到的循环次数不超过PAR的256倍。decfsz的t。然后是一个外循环,用于包装该循环。如果您真的需要长时间计数,可以继续包装。使用计时器也很好,但对于PIC和其他具有非常可预测的指令执行时间的计时器,这非常常见。@old_timer非常感谢您的帮助!真的帮助我理解了。我会接受您的答案,b但是我不能,因为你在评论中发布了这个。