I have this code - all LEDs are turn on and off every 1 second (using MPLAB X IDE, assembler, oscillator frequency is 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
Could someone explain how the Delay_1s is working? I have tried to multiply 168 * 24 * 6 = 24192 µS, but that is incorrect, I should get 1000000 µS..
EDIT:
I'm getting closer - decfsz CounterA,1 takes 1 µS, and goto loop takes 2 µS to process. So I think the answer should look like (168 * 3) * (24 * 3) * (6 * 3) = 653184 µS. Of cource I should add 6 µS while setting values to CounterA, CounterB and CounterC. Is there something I missing?
EDIT2:
I've added time valus to each operation below. Do I understand it right?
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 ??
CounterAandCounterBstarts from 256 (CounterConly going to zero and then routine returns) - then the result is 390150, and if I multiply it by 3µS - then I get 1,170450 Sec