In response to earlier query I have attached a macro and code
which I wrote which delays precisely any number of cycles between 1 and
188600. It is very useful for software delays (e.g. serial interfacing) where
the code may be written for any oscillator speed and needs precise delays
calculated programatically
To use this simply use the macro :
DELAY n
; where n is the number of cycles to wait
This is a complete program which includes test code, please
remove code between "start" and "lop" labels to use in your own routines, It
will need modifying at the top for different processors.
**************************************************************************
*
*
Forest Electronic Developments
* http://dspace.dial.pipex.com/robin.abbott/FED
*
**************************************************************************
#ifndef __PICDE
processor 16f84
#endif
#include "P16F84.inc"
cblock
0x0c ; Variables in RAM
DelayIndex
DelayIndexH ; Delay
variables
endc
noexpand
;
; This macro delays an
exact
; number of clock cycles between
; 1 at minimum or 186420 at
max
;
DELAY macro Cyc
LOCAL Nx
SmallCyc=Cyc
if (SmallCyc<8) ; Short delays
if
(SmallCyc&1)
NOP
SmallCyc-=1
endif
while
(SmallCyc>=4)
call Del4
SmallCyc-=4
endw
if
(SmallCyc==2)
goto Nx
Nx:
SmallCyc-=2
endif
endif
if Cyc>.775 ; Long delays
BigCyc=(Cyc-.730)
LoopDelay=BigCyc/.728
movlw
LoopDelay+1
call BigDel
SmallCyc=Cyc-(.730+LoopDelay*.728+3)
endif
if
(SmallCyc)
LoopDelay=(SmallCyc-3)-5 ; Delay<=775
Cyc
movlw LoopDelay/3+1
call
Delay0-LoopDelay%3
endif
endm
start DELAY
.1
; Only for test purposes
DELAY .2
DELAY .3
DELAY
.4
DELAY .5
DELAY .6
DELAY .7
DELAY
.8
EndDel nop
lop goto lop
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; Delay
routines
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; Insert a delay
of up to 772 Cycles
; Loop time = 5 + 3*(W-1), minimum 5
; Call Delay 1 to
add 1 cycle
; Call Delay 2 to add 2 Cyc
;
; Remember it takes 2 Cycles
to call
; this routine, and 1 cycle to load
; W before calling
it
;
Delay2 nop ; 1
Delay1
nop ; 1
Delay0 movwf DelayIndex ; 1
DelayLop
decfsz DelayIndex ; 1/2
goto DelayLop ;
2
Del4 return ; 2
;
; Big delays need
an outer loop
; This delays 730 + (W-1)*728 Cycles
;
BigDel movwf
DelayIndexH ; 1
BDLop movlw 0xf0 ; 1
call
Delay0 ; 724
decfsz DelayIndexH ; 1/2
goto
BDLop ; 2
return ; 2
#ifndef
__PICDE
end
#endif