Searching \ for 'Delay loops' in subject line. ()
Make payments with PayPal - it's fast, free and secure! Help us get a faster server
FAQ page: www.piclist.com/techref/timers.htm?key=delay
Search entire site for: 'Delay loops'.

Truncated match.
PICList Thread
'Delay loops'
2002\08\05@172006 by Michael A. Powers

picon face
Hi,

I am using the following code on a PIC16F877 @ 4MHz:

bsf PORTB, 4
bsf PORTB, 1  ;---------------------
; delay for at least 2ms
movlw 0x95
movwf Dlay
movlw 0x02
movwf Dlay + 1
decfsz Dlay
 goto $ - 1
decfsz Dlay + 1
 goto $ - 3

bcf PORTB, 4 ; --------------------

I intended for 2ms to elapse  between the execution of the dashed lines.
My formula: 1us per instruction
3us per subtraction iteration
2000us / 3us = 667 cycles
667 - 6 (overhead instructions) = 0x295

When I measured this on an oscilloscope, the actual delay came to be 1.2 ms.
If anything, it should be greater than 2 ms because I did not take the extra
cycles that occur each borrow.  Does each subtraction that does not borrow
take 3us to complete? (1us for decfsz, 2us for goto)

Thanks,
-Mike

--
http://www.piclist.com hint: PICList Posts must start with ONE topic:
[PIC]:,[SX]:,[AVR]: ->uP ONLY! [EE]:,[OT]: ->Other [BUY]:,[AD]: ->Ads


2002\08\05@181645 by sbryden

flavicon
face
I don't really understand your working, but it looks like you have a bug for a
start. When you do the second iteration of the outer loop, you don't
re-initialise Dlay, so the first decfsz wil decrement to 0xff and it will
count from there. So the timing will be as follows between your ----------
delimiters:

initial loading: 4us
first iteration of inner loop: (0x94 * 3) + 2 + 3
second iteration of inner loop: (0xff * 3) + 2 + 2

total delay: 1218us

So, your oscilloscope appears to be well calibrated.

Just to explain the numbers, all PIC instructions (mid-range at least) take
one instruction cycle (clk/4) except those which result in the program counter
being altered. So, with a 4MHz clock, a decfsz will count 1us if there's no
skip and 2us if the skip happens. A goto will always count 2us.

So, the first iteration will be:
0x94 times (a non-skipping decfsz and a goto = 3us) = 444us
the final skipping decfsz (2us)

Then the decfsz as Dlay1 goes from 2 to 1, then the goto, total 3us
The goto takes us (incorrectly I assume) back to the decfsz, which
decrements the zero-value Dlay to 0xff, so:

0xff times (a non-skipping decfsz and a goto = 3us) = 765us
the final skipping decfsz (2us)

plus the final skipping decfsz as Dlay+1 goes from 1 to zero (2us)

I hope this is clear, it's difficult to spell these things out without going
into btuse details, but if you work through it it should become clear.

There is a useful C routine that someone wrote which can calculate these kind
of delay loops for you - I don't remember where it is offhand but I'm sure
someone on the list could poit us to it.

Cheers,
Simon.
---


On Mon, Aug 05, 2002 at 05:19:50PM -0400, Michael A. Powers wrote:
{Quote hidden}

--
http://www.piclist.com hint: PICList Posts must start with ONE topic:
[PIC]:,[SX]:,[AVR]: ->uP ONLY! [EE]:,[OT]: ->Other [BUY]:,[AD]: ->Ads


2002\08\05@233524 by Dwayne Reid

flavicon
face
At 05:19 PM 8/5/02 -0400, Michael A. Powers wrote:

>  bsf PORTB, 4
>  bsf PORTB, 1  ;---------------------
>  ; delay for at least 2ms
>  movlw 0x95
>  movwf Dlay
>  movlw 0x02
>  movwf Dlay + 1
>  decfsz Dlay
>   goto $ - 1
>  decfsz Dlay + 1
>   goto $ - 3
>
>  bcf PORTB, 4 ; --------------------
>
>When I measured this on an oscilloscope, the actual delay came to be 1.2 ms.
>If anything, it should be greater than 2 ms because I did not take the extra
>cycles that occur each borrow.  Does each subtraction that does not borrow
>take 3us to complete? (1us for decfsz, 2us for goto)

The problem is your last 'goto' - you jump back to 'decfsz Dlay', you
should be jumping back to 'movlw 0x02'.

But - you should be using labels in your code!  This business of 'goto $-3'
is BAD PROGRAMMING!  What happens when you add 1 extra line of code?

I cheat too - I will sometimes use 'goto $-1'.  But NO more than 1!

Here is how I think the code should be written:

   movlw     0x95
   movwf     Dlay
Delay_loop
   movlw     0x02
   movwf     Dlay + 1
   decfsz    Dlay
     goto    $ - 1
   decfsz    Dlay + 1
     goto    Delay_loop

dwayne

--
Dwayne Reid   <spam_OUTdwaynerTakeThisOuTspamplanet.eon.net>
Trinity Electronics Systems Ltd    Edmonton, AB, CANADA
(780) 489-3199 voice          (780) 487-6397 fax

Celebrating 18 years of Engineering Innovation (1984 - 2002)
 .-.   .-.   .-.   .-.   .-.   .-.   .-.   .-.   .-.   .-
    `-'   `-'   `-'   `-'   `-'   `-'   `-'   `-'   `-'
Do NOT send unsolicited commercial email to this email address.
This message neither grants consent to receive unsolicited
commercial email nor is intended to solicit commercial email.

--
http://www.piclist.com hint: PICList Posts must start with ONE topic:
[PIC]:,[SX]:,[AVR]: ->uP ONLY! [EE]:,[OT]: ->Other [BUY]:,[AD]: ->Ads


2002\08\06@053852 by sbryden

flavicon
face
Ok, it's the morning and I re-read your original working and I see where
you're going wrong.

Essentially, there are two problems with the original code:

1. The goto bug
2. The reasoning for coming up with 0x295

The first has been well-explained, but just doing as suggested below is not
enough.

You correctly calculated 3us for the inner loop, then reasoned that you needed
660 or so iterations, ignoring all those twos and threes. Then you converted
this to hex, all ok so far, but then you split the resulting figure into two
bytes and used these for the initial values. This is wrong. The number of
iterations is approximately Dlay * Dlay+1, **not** Dlay*256 + (Dlay+1)

So, the reasoning should be something like Dlay * (Dlay+1) = 660

While we're at it, in addition to Dwayne's comment about labels, I would add
the same comment about variable names. It doesn't cost anything to use two
variable names and avoid Dlay+1. Here would be my code to give an approximate
2ms using 3x220 to give the 660:

   ; delay for about 2ms
   movlw  3
   movwf  d1
loop
   movlw  220
   movwf  d2
   decfsz d2,f
   goto   $-1

   decfsz d1,f
   goto   loop

Note that I put the big number in the inner loop to reduce the error from the
loop termination. Note also the ",f" which will avoid assembler warnings.

As I said in my last post, the best way to do this is to use a template and
something to calculate the values. This way is easier, and gives precise
delays. I will get this and post it later.

Simon.
---

On Mon, Aug 05, 2002 at 08:59:00PM -0600, Dwayne Reid wrote:
{Quote hidden}

--
http://www.piclist.com hint: The list server can filter out subtopics
(like ads or off topics) for you. See http://www.piclist.com/#topics


More... (looser matching)
- Last day of these posts
- In 2002 , 2003 only
- Today
- New search...