Nanosecond delays with AVR

Go To Last Post
32 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi Guys,

Has anybody tried using nanosecond delays with the AVR? Is there a _delay_ns() function? If my AVR is running at 10MHz what is the approximate minimum delay I can use with the _delay_ns() function if it does exist? Would it be possible to go to 100 ns with a 10MHz signal?

Thanks.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

To get the nanosecond delays you can use the _delay_us() function with a floating point argument, e.g. _delay_us(0.0015) will give you an exact 1.5 nanosecond delay. In a next WinAVR release the new _delay_ns() and delay_ps() functions are expected which should work with all range of AVR MCUs except the Tiny15.

Warning: Grumpy Old Chuff. Reading this post may severely damage your mental health.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The period of a signal is T=1/Frequency expressed in seconds.So 1/10000000=0.1uS=100nS.This is the time that microcontroller takes to execute each cycle.To obtain such a delay time you can use just a simple NOP instruction that takes one cycle to execute and means no operation,just an one cycle delay.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Since 2007 when Atmel changed the AVR core to the enhanced version, all AVRs are able to automatically recognize the extended _delay_us() argument and generate the nanosecond delays if the argument's value is less than 1. A totally new patended technique called "Partial NOP" is used in this case.

Warning: Grumpy Old Chuff. Reading this post may severely damage your mental health.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The previous posting not withstanding, all actions have a "granularity" of 1 clock cycle. That is the smallest time interval that anything can happen inside at the I/O level of any processor.

If you need something to the outside world, the fastest you can do is an SBI/CBI pair, and that will give you a pulse 2 clocks wide. Finest you can get!

Jim

Jim Wagner Oregon Research Electronics, Consulting Div. Tangent, OR, USA http://www.orelectronics.net

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

ka7ehk wrote:
If you need something to the outside world, the fastest you can do is an SBI/CBI pair, and that will give you a pulse 2 clocks wide. Finest you can get!
Not exactly. For XMega and Reduced Core TinyAVR the same pair gives a single clock wide pulse.

Warning: Grumpy Old Chuff. Reading this post may severely damage your mental health.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

That is fully described in the AVR Instruction Set document.

Jim

Jim Wagner Oregon Research Electronics, Consulting Div. Tangent, OR, USA http://www.orelectronics.net

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Indeed:

Quote:

Example:
cbi $12,7 ; Clear bit 7 in Port D

Words : 1 (2 bytes)
Cycles : 2
Cycles XMEGA: 1
Cycles Reduced Core tinyAVR: 1

Warning: Grumpy Old Chuff. Reading this post may severely damage your mental health.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

MBedder wrote:
ka7ehk wrote:
If you need something to the outside world, the fastest you can do is an SBI/CBI pair, and that will give you a pulse 2 clocks wide. Finest you can get!
Not exactly. For XMega and Reduced Core TinyAVR the same pair gives a single clock wide pulse.

Huh? Through code the fastest cycle [2 state changes] you can get is fcpu/2 as each set, clear, or toggle action takes EXACTLY 1 CPU cycle. Therefore to get 2 state changes on an I/O line, it takes at least 2 CPU cycles. There is no magic instructions to do this faster.

As to your previous posts, there is no recognition of "extended _delay_us() argument" _delay_us() is not an AVR instruction, it is a library call within GCC, There is no such thing as a "partial NOP". Put down the crack pipe and keep your bullshit answers to yourself, you are helping nobody by posting them here.

Writing code is like having sex.... make one little mistake, and you're supporting it for life.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
Therefore to get 2 state changes on an I/O line, it takes at least 2 CPU cycles
And for the one cycle SBI/CBI pair, this will then create a one cycle pulse.
Quote:
To get the nanosecond delays you can use the _delay_us() function with a floating point argument, e.g. _delay_us(0.0015) will give you an exact 1.5 nanosecond delay
Not on any AVR that I know. The fastest xmega runs at 32 MHZ, which means that the shortest delay possible (one NOP) is 31.25ns. And further, the shortest delay with _delay_us() is 3 clocks (93.75ns).

Regards,
Steve A.

The Board helps those that help themselves.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

WTFC. (Who The Freak Cares)

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Koshchi wrote:
The fastest xmega runs at 32MHZ

I tested XMEGA up to 64MHz at Vcc=3.3v .

Ozhan KD
Knowledge is POWER

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

npat_avr wrote:
Hi Guys,

Has anybody tried using nanosecond delays with the AVR? Is there a _delay_ns() function? If my AVR is running at 10MHz what is the approximate minimum delay I can use with the _delay_ns() function if it does exist? Would it be possible to go to 100 ns with a 10MHz signal?

Thanks.

I use nanoseconds delays in some low level GLCD library code I wrote that must honor hardware setup times.

While you could, as others have stated, use _delay_us() with a floating point value less than 0 to get shorter than us delays,
i.e. _delay_us(0.500) should be 500 nanoseconds
and _delay_us(0.100) should be 100 nanoseconds.

I would not recommend using it because
you will never be able to get a 100ns or 500ns delay using the current implementation of _delay_us()
in even when using a 10Mhz clock.
With a 10Mhz clock:
_delay_us(0.100) will give you a 300ns delay
_delay_us(0.500) will also give you a 300ns delay.
_delay_us(0.600) will give you a 600ns delay
_delay_us(0.800) will also give you a 600ns delay

If you are looking for more accurate and predictable short delays, I would recommend that you avoid using the _delay_xx() macros that come with the AVR libC library in

The current implementation has rounding issues
that create delays that can be shorter or longer than what
is really possible. This is especially true when the requested delay cycle time is very short.
The current _delay_us() routine rounds in multiples of 3 AVR clock cycles with 3 cycles being the minimum delay.
So if you have a 10mz clock and ask for 100 ns
by using _delay_us(0.100)
You will get a delay of 300 ns (3 clocks) even though
a 100 ns delay is possible with a 10Mhz clock.
This is because of the rounding in the _delay_us()
code implementation.

For the time being I would recommend using this drop
in replacement:
https://www.avrfreaks.net/index.php?module=Freaks%20Academy&func=viewItem&item_id=665&item_type=project

It is full backward compatible with
and will also give you a _delay_ns() function.
It does not have this 3 clock cycle rounding issue
and will round to a single clock cycle.
So with a 10mhz clock you can get delays on every
100ns boundary, something that the routines in
currently cannot do.

Just keep in mind that the actual resolution of the delay is multiples of the CPU clock frequency so depending on the delay you request you may get a delay that is longer.

For example, if you requested a 10ns delay on your
10Mhz clock you would get a 100ns delay because 1 clock
cycle is the shortest delay possible and 1 clock at
10Mhz is 100ns.

So the difference between the Han's routines and the routines in is Han's routines will give you delays in single clock increments while the _delay_us() in will give you delays in 3 clock increments.

In my case, 3 clock increments simply was not good enough
so I switched to Han's routines.

--- bill

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Pity on those who are not even able to distinguish a serious reply from a sarcastic one. Keep explaining why 2*2=4 :D :D

Warning: Grumpy Old Chuff. Reading this post may severely damage your mental health.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

npat_avr,

In case it's not clear, MBedder was having a bit of fun. The cycle time on a 10MHz processor is 100ns so you obviously(?) cannot delay with any finer granularity than this - you can't make a silk purse out of a sow's ear.

I'd say that for anything up to 1us you might as well just use 1/2/3...8/9 NOPs for 100ns/200ns/300ns..800ns/900ns. In C (GCC that you use) you code a NOP with:

asm volatile ("nop");

be warned the compiler may not honour the sequential placement of such asm() statements. I guess if you want to litter your code with macros you could:

#define DELAY_100NS asm volatile("nop")

then for a 500ns delay:

DELAY_100NS;
DELAY_100NS;
DELAY_100NS;
DELAY_100NS;
DELAY_100NS;

or if you want to go overboard with macros:

#define DELAY_500NS DELAY_100NS;DELAY_100NS;DELAY_100NS;DELAY_100NS;DELAY_100NS

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

Pity on those who are not even able to distinguish a serious reply from a sarcastic one.

A noob might not be able to, MBedder. Make your sarcasms and ironies explicit by adding an appropriate smilie.

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
A noob might not be able to, MBedder. Make your sarcasms and ironies explicit by adding an appropriate smilie.

Except 1st. April. :)

Charles Darwin, Lord Kelvin & Murphy are always lurking about!
Lee -.-
Riddle me this...How did the serpent move around before the fall?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I never address my sarcasm to the noobs. It's always addressed only to the idiots whoever they are (or think they are):D :D

BTW, adding smiles to the obviously mocking message kills the whole idea to stimulate the poster using his own brain (if any of course :D ).

Warning: Grumpy Old Chuff. Reading this post may severely damage your mental health.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

No-one has yet mentioned delay_cycles()?

It appears to be more "intrinsic" than "library" as it doesn't appear in the library function listing.

berryap says it is part of GCC and "fully debugged" and exact for cycle counts. That's as close as you wil get, I'd say.
https://www.avrfreaks.net/index.p...

[Looking back, how do we know/why are we assuming GCC?]

Lee

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
[Looking back, how do we know/why are we assuming GCC?]

That is Easy.
Other compilers never made a cock-up of .
Other compiler users are not so obsessive.

QED.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

[Looking back, how do we know/why are we assuming GCC?]

The asked for _delay_ns() has an initial underscore, and avrlibc is the only one having underscore-prefixed _delay_ms() and _delay_us() IIRC?

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
BTW, adding smiles to the obviously mocking message kills the whole idea to stimulate the poster using his own brain

I must say, i'm with MBedder about his way of not declaring obvious sarcasm as being sarcastic. This is not a "house-wife tries to understand Einstein's theories" forum, here AVR users discuss their usage of AVRs. And if someone indeed is asking about nanosecond delays being generated by a chip that is clocked in cycles being multiples of nanoseconds in width, then this guy didn't get the picture at all.

Einstein was right: "Two things are unlimited: the universe and the human stupidity. But i'm not quite sure about the former..."

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

[Looking back, how do we know/why are we assuming GCC?]

There speaks a man who hasn't read npat_avr's other 973 posts!

Don't know about anyone else here but for anyone with over about 50 posts I remember exactly which toolchain they are using.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

MBedder wrote:
Pity on those who are not even able to distinguish a serious reply from a sarcastic one.

While I would accept sarcasim on a single post, extending it across multiple posts treads into the waters of deliberate mis-direction. If you are to use sarcasim and not mark it with a smiley, then at least follow up with a proper response that addresses the question posed.

Writing code is like having sex.... make one little mistake, and you're supporting it for life.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
...then at least follow up with a proper response that addresses the question posed.

Yup, Daddy - I shall undoubtfully start doing that... tomorrow. And from now on I do promise to always ask your kind permission first :D :D :D

Warning: Grumpy Old Chuff. Reading this post may severely damage your mental health.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
I never address my sarcasm to the noobs. It's always addressed only to the idiots whoever they are
There was nothing in your first post that did not indicate that you were the idiot.

Regards,
Steve A.

The Board helps those that help themselves.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

My fault. I also did not indicate that you aren't - sorry for that :D

Warning: Grumpy Old Chuff. Reading this post may severely damage your mental health.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Given the very broad range of backgrounds and experience levels I would agree that a :) is appropriate.

Remember that when someone asks a "dumb" question it is only because they have not yet learned the principles underlying the issue, (or the occassional troll just stirring the pot).

I'm still laughing over fractional NOPs. But my preference would be to have followed it with a valid explaination.

JC

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

And back on the original topic...

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

Quote:

[Looking back, how do we know/why are we assuming GCC?]

The asked for _delay_ns() has an initial underscore, and avrlibc is the only one having underscore-prefixed _delay_ms() and _delay_us() IIRC?


I thought IAR also had leading _.

In any case, given the discussion in the link I gave it seems delay-cycles would be the best solution to the original question. I can see that a few apps where people are playing with VGA timing and the like it might matter. Not in real microCONTROLLER apps that AVR's are designed for.

For a few cycles, string the right number of NOPs in macros or whatever. After that one gets into delay-us range anyway. Much ado about nothing. WTFC. I'd be a LOT more interested if we hear about the requirements of these fine [pun intended] delays.

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
But my preference would be to have followed it with a valid explaination.

I just have decided to leave that piece of cake to others, which undoubtfully was a wise idea as you can see now ;)

Warning: Grumpy Old Chuff. Reading this post may severely damage your mental health.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

People are getting a little too serious.

I think that most people can recognise a genuine innocent.
Their postings tend to be in single or double figures.

There are also others that are in a genuine panic.
We have all been there. They get help and reassurance.

The world is a sad place if Mbedder cannot poke a little fun!

Who has never been sent to the Stores for a 'long weight', 'greased nuts', 'skyhooks', ... ?

We can now add 'partial nops' to the list of essential components.

David.