簡體   English   中英

PIC 匯編語言 - decfsz 循環

[英]PIC Assembly Language - decfsz loop

我正在使用 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

    ```

一般建議是使用定時器來消耗時間,有些人會爭辯說中斷有可能使芯片處於低功耗模式。 但是對於像 PIC18 這樣的處理器,您可以計算指令並非常准確地從中確定執行時間以使用簡單的循環來消耗時間。

使循環花費更長時間的兩種方法,而且我對 PIC 編碼非常生疏,因此請考慮以下偽代碼:

variable2 = 0
label:
  decfsz variable2,1
  goto label

那本質上是 256 個循環是嗎? 你可以計算指令,包括額外的時鍾或任何時間為零的時間......

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

添加 nops 可以消耗更多時間(是的,我可能仍然不明白您是在燃燒還是只是想要更多循環)。

或者如果你想讓它更多的循環並且你只有 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 時對其進行調整,因此不同芯片中的相同內核(例如 cortex-m0+ rev xy)不一定表現得如此相同)。

另一種方法是使用值為 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)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM