Searching \ for '[PIC] accurate delay routines' 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/microchip/time.htm?key=delay
Search entire site for: 'accurate delay routines'.

Exact match. Not showing close matches.
PICList Thread
'[PIC] accurate delay routines'
2006\02\23@180149 by Gökhan SEVER

picon face
ive decided to code my own delay routines with HI-TECH PICC for P16F877A
micro. (although picc
compiler itself has samples delay routines they arent so accurate). Before
starting coding i have
looked the other compilers delay library capabilities. First of all the CCS
and MikroC compilers have
built-in delay routines and it seems that they aren't so accurate. They have
us, ms, s, cyclic based
routines. So i passed them at the first stage. So i changed my attention to
the MPLAB-C18 compiler.
Whereas its PIC18 family compiler it has the delay routines what i'm looking
for. The routines are
cycle based and the codes are all open for the routines. I started to
examine the sources but i
realized that they are all ASM based and mostly benefitted of PIC18 ASM. I
dont have much experience
with PIC18 assembly so it will be hard for me to adopt them for PIC16
family. Are there any other
open-source cycle based delay implementations which will facilitate my
coding works?

2006\02\23@201044 by Chen Xiao Fan

face
flavicon
face


> -----Original Message-----
> From: spam_OUTpiclist-bouncesTakeThisOuTspammit.edu
> On Behalf Of Gökhan SEVER
> Sent: Friday, February 24, 2006 7:02 AM
> To: Microcontroller discussion list - Public.
> Subject: [PIC] accurate delay routines
>
> Whereas its PIC18 family compiler it has the delay routines
> what i'm looking for. The routines are cycle based and the
> codes are all open for the routines. I started to
> examine the sources but i realized that they are all ASM based
> and mostly benefitted of  PIC18 ASM. I dont have much experience
> with PIC18 assembly so it will be hard for me to adopt them
> for PIC16 family. Are there any other open-source cycle based
> delay implementations which will facilitate my coding works?

I look into the delay routine source codes of C18 and they
are quite simple. You have to learn some assemblies anyway.

Back to PICC, maybe the following example macros can
serve as a starting point for you.

#define delay_1tcy() asm("\tclrwdt") //(or use nop)
#define delay_2tcy() asm("\tincf pcl, w")
#define delay_4tcy() delay_2tcy();delay_2tcy()
#define delay_5tcy() delay_4tcy();delay_1tcy()
#define delay_10tcy() delay_4tcy();delay_4tcy();delay_2tcy()

Another thing is to use simulator and that will count the
total delay time for you.


Regards,
Xiaofan

2006\02\24@032626 by Gökhan SEVER

picon face
////////////////////////////////////////////////////////////////////////////
////////// Cycle based timing macros (processor speed independent) /////////
////////////////////////////////////////////////////////////////////////////


/* Delay of exactly 1 Tcy */
#define delay_1tcy() asm("nop")

/* Delay of exactly 2 Tcy */
#define delay_2tcy() asm("nop"); asm("nop")

/* Delay of exactly 4 Tcy */
#define delay_4tcy() delay_2tcy(); delay_2tcy()

/* Delay of exactly 5 Tcy */
#define delay_5tcy() delay_4tcy(); delay_1tcy()

/* Delay of exactly 10 Tcy */
#define delay_10tcy() delay_5tcy(); delay_5tcy()

I have started with these macro definitions. But the problem started to
raise when i want to adopt them for proper functions. That will be a bit
trouble for me. But after completing such work we can be competitor tot he
C18 libraries :)



2006/2/24, Chen Xiao Fan <.....xiaofanKILLspamspam@spam@sg.pepperl-fuchs.com>:
>
>
>
> > {Original Message removed}

2006\02\24@081756 by Maarten Hofman

face picon face
> /* Delay of exactly 2 Tcy */
> #define delay_2tcy() asm("nop"); asm("nop")

As Chen Xiao Fan indicated, this could be better done using a "goto
$+1" operation: it would take only one word instead of two.

>
> /* Delay of exactly 4 Tcy */
> #define delay_4tcy() delay_2tcy(); delay_2tcy()

Depending on available stack space, you could implement this by a
"call <return statement somewhere in your current code block>": it
would still only take one word instead of four (or two if you use the
change above).

>
> /* Delay of exactly 5 Tcy */
> #define delay_5tcy() delay_4tcy(); delay_1tcy()
>
> /* Delay of exactly 10 Tcy */
> #define delay_10tcy() delay_5tcy(); delay_5tcy()

Note that at some point it will become better making a small loop
using decfsz and goto $-1.

Good luck!

Greetings,
Maarten Hofman.

2006\02\24@090046 by olin piclist
face picon face
Maarten Hofman wrote:
>> /* Delay of exactly 2 Tcy */
>> #define delay_2tcy() asm("nop"); asm("nop")
>
> As Chen Xiao Fan indicated, this could be better done using a "goto
> $+1" operation: it would take only one word instead of two.

Even better is to use a macro that you simply tell the number of cycles to
waste and it figures out when to use GOTO $+1, BRA $+2, and NOP.  That's
what my WAITCY macro in STD.INS.ASPIC at http://www.embedinc.com/pic does.

However in most cases of inserting NOPs, you are really trying to do timing.
Just iserting a fixed number of instruction cycles is a bad idea since that
makes your source code implicitly dependent on the processor clock speed.
WAITCY should only be used when you want to wait a specific number of
*instructions*, which is rare.

An even better answer is to specify the amount of *time* to waste.  Let the
assembler calculate how many instruction cycles that is, then calclulate the
least number of instructions to take that many cycles.  But there's another
wrinkle.  Often you need two instructions to be a fixed minimum time apart,
but you have other things you can do during those instructions although they
don't guarantee taking that minimum amount of time.  So you want a minimum
guaranteed delay in time, but are going to spend some of that with a fixed
number of instruction cycles.  Therefore what you really need is a way of
saying, for example, "Take 2uS, but I've already used 5 instruction cycles
out of that 2uS.".  This shows the part you know about and can control in
the source code without any implicit reliance on the processor clock speed.

This is exactly what my WAITNS and WAITUS macros in STD.INS.ASPIC do.

> Note that at some point it will become better making a small loop
> using decfsz and goto $-1.

As long as the side effect on the additional state and the status flags are
clearly documented.


******************************************************************
Embed Inc, Littleton Massachusetts, (978) 742-9014.  #1 PIC
consultant in 2004 program year.  http://www.embedinc.com/products

2006\02\24@095153 by Gökhan SEVER

picon face
Thanks Mr Lathrop for your suggestions on my subject. I looked at some to
your asm codes but i have to admit that the routines on MCC18 directory
seems more convenient to adopt. Though i have some problems with pic18 asm,
i will try my best to benefit the C18's powerfull open-source library. It
also includes very neat and well-commented  peripheral libraries which i
will try to port them to PICC in future.  I had written a similar post to
the Hi-tech's forum for general-purpose library development request but they
didnt interested much. What's wrong with this kind of general C coded
peripheral library?


2006/2/24, Olin Lathrop <olin_piclistspamKILLspamembedinc.com>:
{Quote hidden}

> -

2006\02\24@100029 by Larry G. Nelson Sr.

picon face
---- Olin Lathrop <.....olin_piclistKILLspamspam.....embedinc.com> wrote:
> Maarten Hofman wrote:
You really want to use a NOP for things like the read / modify / write you see in a BCF or BSF situation. That 1 cycle delay gives time to let things settle on a port under most circumstances. I have had to use a 2 cycle delay a couple times on a fast clock speed with a line driving a lot of capacitance.
Larry

{Quote hidden}

> --

2006\02\24@104857 by Scott Dattalo

face
flavicon
face
On Fri, 2006-02-24 at 01:01 +0200, Gökhan SEVER wrote:

> Are there any other
> open-source cycle based delay implementations which will facilitate my
> coding works?

While I haven't looked at Olin's delay macros, I suspect from his
description they're similar to the ones I use in gpsim's regression tests.
For example, check out this:

http://cvs.sourceforge.net/viewcvs.py/gpsim/regression/tmr0_16bit/

This simulation regression test is for TMR0 in the 18F family and the
delay routines are used to synchronize the code flow with the TMR0 time
outs. This code is also for the 18F family, but it's easily adaptable to
the 16F family.

Scott

2006\02\24@122154 by Danny Sauer

flavicon
face
Olin wrote regarding 'Re: [PIC] accurate delay routines' on Fri, Feb 24 at 08:03:
> Even better is to use a macro that you simply tell the number of cycles to
> waste and it figures out when to use GOTO $+1, BRA $+2, and NOP.  That's
> what my WAITCY macro in STD.INS.ASPIC at http://www.embedinc.com/pic does.

Since I'll probably never do any more than possibly adding a zif
socket to my pickit1 and will therefore likely never use an 18*, this
is mostly just curiosity, but why does the 18*'s BRA instruction need
$+2?  The goto $+1 makes sense - use up two instruction cycles with
one word and end up at the next instruction - but why move ahead two
places with branch?

I'm still trying to decide whether I want to use delay loops like that
in serial communication, or use the onboard timer and sample on the
overflow interrupt.  To keep this on topic, I'm curious if the
insert-N-instructions-here method would be preferable to just
calibrating the timer, potentially initializing the counter to
something other than zero, and then continuing on after the interrupt
(either sleeping and waiting for the interrupt to awaken the
processor, or doing other calculations in the delay)?  In my
application, I'm working with a relatively slow 8192 baud signal, so
I'd be wasting a lot of cycles waiting for the next bit to come along.
I'm also needing to store a lot of strings, so it seems like the
timer-overflow-interrupt method would save some memory as opposed to
the insertion of a whole bunch of instructions.  But, is there any
drawback to using the interrupt-based method that my lack of
experience in this realm might cause me to overlook?

Thanks.
--Danny

2006\02\24@123516 by David VanHorn

picon face
I've done it that way in the AVR, nice and simple.
Take the start bit edge interrupt, and start your timer with half a bit
time.
When the int fires, if the pin is still low, then load a full bit time, and
start shifting bits. After 8 bits of data, you can optionally look at the
stop bit.

2006\02\24@130346 by olin piclist

face picon face
Danny Sauer wrote:
> but why does the 18*'s BRA instruction need $+2?

Because PIC 18 uses byte addressing for program memory and instruction words
are two bytes long.  Therefore $+2 refers to the next instruction.


******************************************************************
Embed Inc, Littleton Massachusetts, (978) 742-9014.  #1 PIC
consultant in 2004 program year.  http://www.embedinc.com/products

2006\02\24@131312 by Danny Sauer

flavicon
face
Olin wrote regarding 'Re: [PIC] accurate delay routines' on Fri, Feb
24 at 12:06:
> Danny Sauer wrote:
> > but why does the 18*'s BRA instruction need $+2?
>
> Because PIC 18 uses byte addressing for program memory and
> instruction words are two bytes long.  Therefore $+2 refers to the
> next instruction.

Well, that makes sense. :)  Thanks.

--Danny

2006\02\24@165620 by William Chops Westfield

face picon face
>> cycle based delay implementations

Who has a cycle-based delay routine that does the calculations
at runtime?  I assume that ought to be possible for anything
above about 20 cycles, shouldn't it?

BillW

2006\02\24@185002 by andrew kelley

picon face
> Because PIC 18 uses byte addressing for program memory and instruction words
> are two bytes long.  Therefore $+2 refers to the next instruction.

So can you jump to the middle of the instruction? I've seen this done on x86's..

andrew

2006\02\24@191436 by olin piclist

face picon face
andrew kelley wrote:
> So can you jump to the middle of the instruction? I've seen this done
> on x86's..

The low bit of the PC is always 0, so you can't jump to an odd address.
However, some instruction use two words, like MOVFF and GOTO, and it is
possible to jump to the second word of a two-word instruction.  The encoding
of the second word of all two word instructions were deliberately chosen so
that they would be NOP instructions if executed as the first word of an
instruction.  Among other things, this allows for conditional skips over
GOTO instructions.


******************************************************************
Embed Inc, Littleton Massachusetts, (978) 742-9014.  #1 PIC
consultant in 2004 program year.  http://www.embedinc.com/products

2006\02\25@141717 by Peter

picon face


On Fri, 24 Feb 2006, William Chops Westfield wrote:

>>> cycle based delay implementations
>
> Who has a cycle-based delay routine that does the calculations
> at runtime?  I assume that ought to be possible for anything
> above about 20 cycles, shouldn't it?

Also below (you can jump into it with 1T granularity). Depending on how
you define 'calculations' you can load the counters from variables
instead of constants.

Peter

2006\02\26@161052 by Wouter van Ooijen

face picon face
> Are there any other
> open-source cycle based delay implementations which will
> facilitate my coding works?

If you like creative (mis)use of macros you could take a look at my WISP
(not wisp628) code: http://www.voti.nl/wisp/index.html

warning: Scot once said this was the only MPASM code that did not work
correctly on gpasm (but maybe gpasm was more right that mpasm in
refusing my code).

Wouter van Ooijen

-- -------------------------------------------
Van Ooijen Technische Informatica: http://www.voti.nl
consultancy, development, PICmicro products
docent Hogeschool van Utrecht: http://www.voti.nl/hvu


2006\02\26@161055 by Wouter van Ooijen

face picon face
> An even better answer is to specify the amount of *time* to waste.
Let the
> assembler calculate how many instruction cycles that is, then
calclulate the
> least number of instructions to take that many cycles.  But there's
another
> wrinkle.  Often you need two instructions to be a fixed minimum time
apart,
> but you have other things you can do during those instructions
although they
> don't guarantee taking that minimum amount of time.  So you want a
minimum
> guaranteed delay in time, but are going to spend some of that with a
fixed
> number of instruction cycles.  Therefore what you really need is a way
of
> saying, for example, "Take 2uS, but I've already used 5 instruction
cycles
> out of that 2uS.".  This shows the part you know about and can control
in
> the source code without any implicit reliance on the processor clock
speed.

One step better, and one level up in the language picking order: I'd
like to specify that, and not have to worry about how many instructions
I spent doing those other things. And I want to be able to specify that
in loops too. Does anyone know of a HLL syntax (or even an
implementation) for this?

Like:

  timing_start;
  for( i = 0; i <= 8; i ++ ){
     timing_interval( 1.0 / 115200 );
     outpin = data : 0;
     data = data >> 1;
  }
  timing_interval( 1.0 / 115200 );
  outpin = 1;
  timing_interval( 2.0 / 115200 );      

Wouter van Ooijen

-- -------------------------------------------
Van Ooijen Technische Informatica: http://www.voti.nl
consultancy, development, PICmicro products
docent Hogeschool van Utrecht: http://www.voti.nl/hvu


2006\02\26@174603 by Gerhard Fiedler

picon face
Wouter van Ooijen wrote:

> One step better, and one level up in the language picking order: I'd
> like to specify that, and not have to worry about how many instructions
> I spent doing those other things. And I want to be able to specify that
> in loops too. Does anyone know of a HLL syntax (or even an
> implementation) for this?

With a rather high overhead (between too high and much too high for the
typical applications we're talking about :), this is what a preemptive
realtime OS provides.

I don't know of any HLL that has support for timing at this level.

Gerhard

2006\02\26@224052 by William Chops Westfield

face picon face
>  I'd like to specify that, and not have to worry about how many
> instructions I spent doing those other things. And I want to be able
> to specify that in loops too.

We have something trivial like:

#define TIMER_START(timer, ms) (timer = msclock() + ms)
#define TIMER_RUNNING(timer) (msclock() < timer)

where msclock() returns some automatically-incremented counter
(interrupt driven here, but it could be a cycle counter if you
have one, or a bare timer register.)

Then you can do

       TIMER_START(my_timer, 10);  /* Wait for at least 10 ms */
       do_some_work();
    do_some_more_work();
          :
    work_almost_done();
    while (TIMER_RUNNING(my_timer))
           ;                /* Wait for rest of 10mS to pass */

Beware counter wraparound and sign changes...

BillW

2006\02\27@013929 by Wouter van Ooijen

face picon face
> With a rather high overhead (between too high and much too
> high for the typical applications we're talking about :)

As I think you understand I was talking about timing at the ~ 10's of
instructions level, which is out of reach of even the fastest context
switching.

Wouter van Ooijen

-- -------------------------------------------
Van Ooijen Technische Informatica: http://www.voti.nl
consultancy, development, PICmicro products
docent Hogeschool van Utrecht: http://www.voti.nl/hvu


2006\02\27@040938 by Gökhan SEVER

picon face
I have to admit that subject has gone away a bit  from my first posting.


Btw, i have found what i was looking for on Microchip's froums.

Please check the froum posting.

*Need perfect delays?*
http://forum.microchip.com/tm.aspx?m=135820


And i have succesfully adopted _WAIT_10us routine with HI-TECH PICC
compiler.

void _WAIT_10usX (unsigned char) {

   unsigned char micro;

   #asm
       movwf __WAIT_10usX$micro
       goto dec5
       NOP
       goto $+1
       goto $+1
       goto $+1
   dec5
       decfsz __WAIT_10usX$micro,F
       goto $-5
       return
   #endasm
}

But this only works exactly if i compile the code with optimizations
disabled. I will try to port others as soon as possible.

2006\02\27@075037 by Gerhard Fiedler

picon face
Wouter van Ooijen wrote:

>> With a rather high overhead (between too high and much too
>> high for the typical applications we're talking about :)
>
> As I think you understand I was talking about timing at the ~ 10's of
> instructions level, which is out of reach of even the fastest context
> switching.

Doesn't have to include context switching. Waiting for a timer signal would
be enough; something along the lines of what Bill described. Setting a
timer and waiting for its end is part of a usual RTOS, normally both
blocking (without context switch) and non-blocking (with context switch).

Maybe you're up to something here... but I suspect something like this will
only find its way into special languages like your Jal. I can't see the C
standard group for example adopting such an extension. It just "feels" to
low-level.

Gerhard

2006\02\27@082839 by Wouter van Ooijen

face picon face
> Doesn't have to include context switching. Waiting for a
> timer signal would
> be enough; something along the lines of what Bill described. Setting a
> timer and waiting for its end is part of a usual RTOS, normally both
> blocking (without context switch) and non-blocking (with
> context switch).

But that would not realy work on the level of accuracy I am aiming at:
from 1's of instructions up. And one more ting: of course the compiler
must give an error when the specified interval can not be met. And it
must work on non-timer chips too...

> Maybe you're up to something here... but I suspect something
> like this will only find its way into special languages like your Jal.

> I can't see the C
> standard group for example adopting such an extension. It
> just "feels" to low-level.

The trouble is that it is too high for assembler, and the next common
step up is C.

This is one of the few features that I have dreamed about to implement,
but I found it too difficult to *define* (I think the actual
implementation will be easier than defining it). So it would be
interesting to see an existing language with this feature.

Wouter van Ooijen

-- -------------------------------------------
Van Ooijen Technische Informatica: http://www.voti.nl
consultancy, development, PICmicro products
docent Hogeschool van Utrecht: http://www.voti.nl/hvu


2006\02\27@144149 by Gerhard Fiedler

picon face
Wouter van Ooijen wrote:

> This is one of the few features that I have dreamed about to implement,
> but I found it too difficult to *define* (I think the actual
> implementation will be easier than defining it).

I think in principle there are two structural possibilities: a block with a
defined (minimum) run time or markers with a defined (minimum) run time
between them.

A block doesn't seem to be a good choice, because it would have to coincide
with other blocks (like loops etc), which restricts it too much.

But I can't see a problem in using a syntax similar to what you proposed.
What are the shortcomings you see?

{Quote hidden}

Maybe an added identifier makes sense... it would make overlapping timing
possible. Possibly using similar rules as for variable names, so it would
look like a variable name. Maybe it even would have to be declared
similarly. But it isn't really a variable, it only serves to identify the
markers and associate sets of markers with each other. But this doesn't
change the basic syntax and semantic.

Gerhard

2006\02\27@164204 by Wouter van Ooijen

face picon face
> But I can't see a problem in using a syntax similar to what
> you proposed. What are the shortcomings you see?

I could not write a short and clear definition. Note that you'd have to
cover overlapping time zones, backwards timezones (in loops), timezones
that enter and leave loops, timezones that have multiple begins and ends
(in if branches, but also inside and outside loops) and possibly more.
Maybe even time markers and/or zones as compile-time parameters.

And I could not find any exsiting definition and/or implementation,
which means that I would probably make all the firts-timer mistakes.

> Maybe it even would have to be declared
> similarly. But it isn't really a variable, it only serves to
> identify the
> markers and associate sets of markers with each other.

It is more like a goto label.

Wouter van Ooijen

-- -------------------------------------------
Van Ooijen Technische Informatica: http://www.voti.nl
consultancy, development, PICmicro products
docent Hogeschool van Utrecht: http://www.voti.nl/hvu


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