[英]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.