Here's a somewhat universal delay sub-system I use which allows you to specify exact delays in cycles, microseconds, or milliseconds with almost any clock (4, 8, 12, 16, or 20 MHz). It's relatively low overhead with a 12 word sub-routine and uses 4 words for each DelayCy() macro call (minimum, depending on the clock and delay). You
must set the clock equate to your clock frequency (in MHz).
Soapbox
Honestly I don't know why you guys keep recommending those barbaric loop routines from PICLIST. They're fine if you only need a single delay. Wouldn't you rather have a single general purpose routine that works with any clock? I think I'd fall off my chair if one of you were ever to recommend the method I've been promiting this last year (lol).
Mike
Code:
radix dec
clock equ 8 ; user clock frequency in MHz
usecs equ clock/4 ; cycles/microsecond multiplier
msecs equ usecs*1000 ; cycles/millisecond multiplier
DelayCy macro pDelay ; cycles (Tcy), minimum 16
local cycles
cycles = pDelay
while cycles > 262032
movlw high((262016-16)/4)+1
movwf TMRH
movlw low((262016-16)/4)
call DelayLo-(262016%4)
cycles -= 262016
endw
movlw high((cycles-16)/4)+1
movwf TMRH
movlw low ((cycles-16)/4)
call DelayLo-(cycles%4)
endm[COLOR=Red]
; *
; example code for simulation testing; *
; *
SimTest DelayCy(1000*msecs) ; 1 second delay
nop ; put simulator break point here[/COLOR]
; *
; Delay(16..262159 Tcy) subroutine Mike McLaren, K8LH, Jun'07 *
; *
; 12 words, 1 RAM variable, 14-bit core *
; *
Delay.16
nop ; entry point for delay%4 == 3 |B0
nop ; entry point for delay%4 == 2 |B0
nop ; entry point for delay%4 == 1 |B0
DelayLo addlw -1 ; subtract 4 cycle loop time |B0
skpnc ; borrow? yes, skip, else |B0
goto DelayLo ; do another loop |B0
nop ; |B0
DelayHi addlw -1 ; subtract 4 cycle loop time |B0
decfsz TMRH,F ; done? yes, skip, else |B0
goto DelayLo ; do another loop |B0
goto $+1 ; burn off 2 cycles |B0
return ; |B0