Thought I'd share this here in case it is useful to anyone.
I'm sure it's been done already but I couldn't find one. I'm pretty sure it works for delays of 28 to 65535 cycles in periodH and periodL (unchanged by the function). Should work on all baseline and midrange PICs.
call and retlw instruction times are included. You can change the offset (up to 255) if you want to balance out time from your main loop.
If anyone spots any issues let me know.
I'm sure it's been done already but I couldn't find one. I'm pretty sure it works for delays of 28 to 65535 cycles in periodH and periodL (unchanged by the function). Should work on all baseline and midrange PICs.
call and retlw instruction times are included. You can change the offset (up to 255) if you want to balance out time from your main loop.
If anyone spots any issues let me know.
Rich (BB code):
delay2 ;d2 = High byte d1 = Low byte
offset equ d'28'
movf periodH, W ;copy
movwf d2
incf d2, F ;so that decfsz can be used later
movf periodL, W
movwf d1
movlw offset ;subtract the overhead
subwf d1, F
btfss STATUS, C
decf d2, F
comf d1, W ;delay for the number of cycles of the
andlw b'00000111' ;lower 3 bits
addwf PCL, F
nop
nop
nop
nop
nop
nop
nop
nop
movlw b'11111000' ;lower 3 bits of delay taken care of already
andwf d1, F
movlw d'8' ;preload W (unchanged in loop)
delay2loop ;this loop always takes 8 cycles
subwf d1, F ;so subtract 8 from low byte
btfsc STATUS, C ;check overflow of low byte
goto nocarry ;make loop up to 8 cycles
decfsz d2, F ;decrease high byte
goto delay2waste2cycles
goto enddelay2 ;job done
nocarry
goto $+1
delay2waste2cycles
goto delay2loop
enddelay2
retlw 0x00