我有这个代码 - 所有LED每1秒打开和关闭一次(使用MPLAB X IDE,汇编程序,振荡器频率为4MHz):
#include <p16f84a.inc>
__CONFIG _WDTE_OFF & _PWRTE_OFF & _CP_OFF & _FOSC_HS
;General registers for delay
CounterA equ h'0c'
CounterB equ h'0d'
CounterC equ h'0e'
org 0
Start:
; select bank 1
bsf STATUS, RP0
; set port B as output
movlw b'00000000'
movwf TRISB
; select bank 0
bcf STATUS, RP0
MainLoop:
; turn on LEDS
movlw b'11111111'
movwf PORTB
call Delay_1s
movlw b'00000000'
movwf PORTB
call Delay_1s
goto MainLoop ;Repeat
Delay_1s:
movlw d'6'
movwf CounterC
movlw d'24'
movwf CounterB
movlw d'168'
movwf CounterA
loop:
decfsz CounterA,1
goto loop
decfsz CounterB,1
goto loop
decfsz CounterC,1
goto loop
return
end
有人可以解释Delay_1s
是如何运作的吗?我试过乘以168 * 24 * 6 =24192μS,但这是不正确的,我应该得到1000000μS..
编辑:
我越来越近 - decfsz CounterA,1
需要1μS,goto loop
需要2μS才能处理。所以我认为答案应该看起来像(168 * 3)*(24 * 3)*(6 * 3)=653184μS。对于cource,我应该在将值设置为CounterA
,CounterB
和CounterC
时添加6μS。有什么我想念的吗?
EDIT2:
我为下面的每个操作添加了时间价值。我明白了吗?
Delay_1s:
movlw d'6' ; 1µS
movwf CounterC ; 1µS
movlw d'24' ; 1µS
movwf CounterB ; 1µS
movlw d'168' ; 1µS
movwf CounterA ; 1µS
loop:
decfsz CounterA,1 ; 1µS
goto loop ; 2µS (the same while skipping)
decfsz CounterB,1 ; 1µS
goto loop ; 2µS (the same while skipping)
decfsz CounterC,1 ; 1µS
goto loop ; 2µS (the same while skipping)
return ; 1µS ??
答案 0 :(得分:1)
很抱歉,我不擅长解释,但我希望这会给你一些线索:
Using a 4MHz Xtal OSC
Set OPTION_REG to b'11010100'
'xxxxx100' = 1 instruction :32 uSeconds
32 uSeconds * 250 = 8 milliseconds
8 milliseconds * 125 = 1 second
PORTB (all outs) = B'00000000'
EIGHT_MS EQU 0x10
INIT
BSF STATUS, RP0
MOVLW B'11010100'
MOVWF OPTION_REG
MOVLW B'00000000'
MOVWF TRISB
BCF STATUS, RP0
CLRF PORTB
RETURN
START
L0 CLRF TMR0
L1 MOVF TMR0, W
XORLW .250
BTFSS STATUS, Z
GOTO L1
CLRF TMR0
INCF EIGHT_MS
MOVF EIGHT_MS, W
XORLW .125
BTFSS STATUS, Z
GOTO L1
CALL LIGHT_LED
GOTO L1
LIGHT_LED
...
CALL DELAY
...
RETURN
MAIN
CALL INIT
CALL START
GOTO MAIN
答案 1 :(得分:1)
我查看了此程序,发现该例程花费的周期数为1,003,827,相当于1.003827秒。
我通过三种不同的方法做到了,而且我总是得到相同的结果。
方法1:公式 方法2:用Python模拟 方法3:使用MPLAB仿真器,在函数调用之前和之后设置断点并观察周期计数器。
公式推导如下
让我们首先问自己一个程序,如下所示需要花费多少周期:
循环: decfsz x,f此行运行x次,x-1次不跳,而1次跳, 所以循环数是x-1)+2 goto循环运行x-1次,因此周期为2(x-1) 总的来说,周期是(x-1)+ 2 + 2(x-1)= 3x-1个周期
让我们考虑x在1到256之间(包括1到256,如果x为0等于256)
所以整个程序的循环数是
反周期A B的初始值为3A-1 计数器B的以下时间(B-1)*(3 * 256-1) 计数器C的下一次(C-1)* 256 * 767 计数器B周期 第一次是C为6 3B-1时 以下时间C(C-1)* 767 计数器C循环 第一次也是唯一一次3C-1 调用,Return和6个初始化行 ------------------------- 总计:3A + 770B + 197 122C-197879
用A代替168,B = 24和C = 6得到1,003,837的值 更好的值将是A = 172 B = 19 C = 6产生999,999 在变量初始化中添加nop会得到1,000,000