# Calculating Delay

I want create one milisecond time delay. But, I don't know how to do it because I could not use following three variable in an equation, if there is. Can you help me to creating one milisecond time delay?

I have some issue to consider ;

• development kit works with z mhz
• tool, which is used to code at computer, runs with y mhz

f :

movlw   X
movwf   variable_temp
loop:
nop
decfsz  variable_temp, 1
goto    loop

-
You 1st need to know the clk cycles per instruction at the clock speed used. For the PIC code shown most instructions are one unit but the decfsz is two units. Some processors may take one unit if test fails and two if it passes or whatever. So the timing loop is 3 or 4 units long. Work out the basic unit time (say for nop instruction) at clock speed W Mhz and one mS then needs a count of x in 'movlw x' of 1000/Tw/4, where Tw is time for eg nop instruction. Is nop took 0.5 uS then x = 1000/0.5/4 = 500. Iv variable_temp is 8 bit then this count is too large and a double byte counter is needed. – Russell McMahon Mar 26 '12 at 9:31

This sort of delay scales inverse-linearly with clock speed as long as there are no interrupts or similar running (ie double clock speed and delay halves).

• If a delay takes 1 mS at Z Mhz it will take Y/Z mS at Y Mhz.

• If you need a count of X loops to delay eg 1 mS at Z MHz
then you will need X * Y/Z loops at Y MHz.

This is useful: PIC delay routines.

To work out how many loops are needed you 1st need to know the number of clock cycles or uS per instruction at the clock speed used.

For the PIC that you have shown, most instructions take one "unit" of time.
This will vary among processor families.
Some take 4 crystal clock cycles per instruction, some take 1, some take more.
Assume you know Tw = basic instruction unity time at W Mhz.

In a PIC most instructions execute in Tw at W Mhz where Tw is usually 4/F_Mhz in the older style 14 bit core PICs. .
BUT check this for the processor you are using.

In a PIC the decfsz skip instruction takes one time unit if the test fails (register is non zero) and two time units if the test passes - register is zero and skip occurs.
Some processors may take one unit if test fails or passes or two whether it fails or passes or ... - check what applies for the processor you are using.

So here the main timing loop is 3 time units usually and 4 units only when the register reaches zero.

Work out the basic unit time (say for nop instruction) at clock speed W Mhz and one mS then needs a count of x in 'movlw x' of

• count = 1000 / Tw / 3

where Tw is time for a nop instruction and the 3 is due to 3 x single Tw length instructions in the loop.

If a NOP took 0.5 uS then

• Count = 1000/0.5/4 = 500.

As an 8 bit counter can only count to 255, if variable_temp is 8 bit then this count is too large and a double byte counter is needed.

Something more like below. Here you have inner and outer loops. Each inner loop runs for K_Count_Low loops and the inner loop is called K_Count_High times. Counters are 8 bit so should be set to <= 255.
Maximum delay is ~~~= 255 x 255 x 3 x Tw.
Outer loop handling , included nops etc change this. Seeing exactly how is part of learning how this all works.

    movlw   K_count_High
movwf   Counter_High


LoopOuter:

     movlw   K_count_Low
movwf   Counter_Low


LoopInner:

     nop
decfsz  CounterLow, 1
goto    LoopInner

decfsz  CounterHigh, 1
goto    LoopOuter

Call "We are the Borg of Pentium. Division is futile! We will approximate you"


E&OE.

-