;******************************************************************
; *
; DelayMS(), DelayUS(), DelayCy() Mike McLaren, K8LH, Jun'07 *
; *
; a small 16-bit delay subroutine with macro "front ends" which *
; allow you to specify delays in msecs, usecs, or cycles. *
; *
; requires the use of constant operands known at assembly time! *
; *
; each delay macro call generates 4 instructions (for delays in *
; the ranges shown below). longer delays up to several seconds *
; are possible but the macro produces 4 additional instructions *
; for every 262016 cycles in the delay. *
; *
; 4 MHz, 1 cycles/usec, 16..262144 usecs, 1..262 msecs *
; 8 MHz, 2 cycles/usec, 8..131072 usecs, 1..131 msecs *
; 12 MHz, 3 cycles/usec, 6...87381 usecs, 1...87 msecs *
; 16 MHz, 4 cycles/usec, 4...65536 usecs, 1...65 msecs *
; 20 MHz, 5 cycles/usec, 4...52428 usecs, 1...52 msecs *
; *
; here are some of the ways to generate a 1 millisecond delay; * *
; *
; DelayMS(1) ; delay 1 msec *
; DelayUS(1000) ; delay 1 msec *
; DelayCy(1*msecs-2) ; delay 1 msec minus 2 cycles *
; DelayCy(1000*usecs) ; delay 1 msec *
; *
; use the DelayCy macro with the 'msecs' or 'usecs' multipliers *
; in the operand plus or minus some number of cycles to produce *
; precise clock independent isochronous timing. *
; *
;******************************************************************
radix dec
clock equ 8 ; user clock frequency in MHz
;
; DelayCy() operand multipliers
;
usecs equ clock/4 ; cycles/microsecond multiplier
msecs equ usecs*1000 ; cycles/millisecond multiplier
; *
; DelayMS(), DelayUS(), and DelayCy() macros *
; *
DelayMS macro pDelay ; milliseconds
DelayCy(pDelay*msecs) ; convert to cycles
endm ;
DelayUS macro pDelay ; microseconds
DelayCy(pDelay*usecs) ; convert to cycles
endm
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
; *
; example code for simulation testing; *
; *
SimTest DelayCy(20*msecs) ; remember to set 'clock' equate
nop ; put simulator break point here
; *
;******************************************************************
; *
; 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 ;
; *
;******************************************************************