delay and the clock cycles

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

Hi:
1)How much should the clock cycles be to get the exact delays of the header delay.h?
and
2)Can i use _delay_ms(0.023) to get 23 nano second delay?
I'm using avr studio 5.1...
thanks

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

1) You have to #define the value of F_CPU before #include delay.h. E.g.

#define F_CPU 8000000
#include 
#include 
/* blah blah blah cöde */

2) No. Use NOPs.

/* blah blah */
asm volatile ("nop");
/* blah */

"Maybe happiness is just fragments of existence with better packaging."

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

2a) 0.023ms = 23µs = 23000ns
2b) you can use _delay_ms(0.023) or _delay_us(23) for a 23µs delay
2c) don't even think of 23ns-delay. To get one nop executed in 23ns, the chip had to run on about 44MHz

/Martin.

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

1)i'm defining it by the project properties then choosing toolchain and defining a symbol... it's the same , so i have to define it on 8mhz?
2) sorry i meant _delay_us(0.023)
and nop is 1/frequency so i have to run it in 44MHz as mtaschl said but i'm using atmega16a which provides speed to 16MHZ

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

1) You have to define it according to your settings of the fuses (the device is shipped with 1 MHz RC per default). You can add a 16MHz crystal and run the chip at 16MHz.
2) Up to now there is no AVR8 with 44MHz.

/Martin.

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

Why the 23 ns delay?

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

1)i'm using external crystal which is 7372800Hz so i have to run it at this speed?
2)so it's impossible to have delay in nano seconds?

i need this delay to write/read with a device that requires this delay...

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

1) If the DIV8 fuse is not set, F_CPU should be #define F_CPU 7372800
2) If you absolutely need it, insert an NOP. That's as far down as you can go and it's still more than those nanoseconds. NOP simply means that the ALU does nooothing.

"Maybe happiness is just fragments of existence with better packaging."

Last Edited: Wed. Jun 20, 2012 - 01:46 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

so it's impossible to have delay in nano seconds?

Depends how many. Think about it:
On an AVR clocked at 1MHz one machine cycle is 1us = 1000ns
On an AVR clocked at 2MHz one machine cycle is 0.5us = 500ns
On an AVR clocked at 4MHz one machine cycle is 0.25us = 250ns
On an AVR clocked at 8MHz one machine cycle is 0.125us = 125ns
On an AVR clocked at 16MHz one machine cycle is 0.0625us = 62.5ns
On an AVR clocked at 20MHz one machine cycle is 0.05us = 50ns

You cannot therefore expect to do anything with a finer granularity than that. If 23ns is required then just one NOP will be one of the above 50ns/62.5ns/125ns/250ns/500ns/1000ns depending on the CPU clock speed. Sure you'll get more - but usually timing constraints (such as line settling time) are given as minimum and it doesn't matter if you wait a bit longer.

OTOH if something says "make one pulse that is exactly 23ns" then you need to find a CPU that runs faster so it can perform finer granularity operations - even at 44MHz a 23ns pulse may still not be possible as it could well take more than one opcode to change bit states to create the complete pulse.

==================================================================

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

foxbrain wrote:
i need this delay to write/read with a device that requires this delay...
But the question is, does the device need a delay of exactly 23 ns, or of at least 23 ns? I bet it is the second so simply insert a single NOP (but even that is not necessary).

Stefan Ernst

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

BTW I missed the fact that it was a 7.3 crystal. That makes your minimum granularity 135.633680555ns in fact.

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

Quote:

OTOH if something says "make one pulse that is exactly 23ns" then you need to find a CPU that runs faster so it can perform finer granularity operations - even at 44MHz a 23ns pulse may still not be possible as it could well take more than one opcode to change bit states to create the complete pulse.

I was thinking about that...use an AVR with PLL and set up a timer such that the PWM "on" time/duty cycle is a single timer tick. But the utility of this in practice is dubious.

From the description of the situation I'd speculate that a minimum "setup time" or similar for a device is stated as the 23ns. Triggering a timer will take much longer than that. :)

Also, do you understand

Quote:

(but even that is not necessary).
???

Let's say you've got a device where you trigger two control inputs, "select" and "go" and the min time between is the given 23ns. On an AVR, you trigger the "select" and then immediate;y trigger the "go" in the next instruction. with some contortions, this could be one AVR clock cycle, more probably two. thus, the spacing is some hundreds of nanoseconds so you need no explicit delay.

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 the question is, does the device need a delay of exactly 23 ns, or of at least 23 ns?

if u see the datasheet that is attachment page 5 u'll see the address r/w setup time is 23ns...

Attachment(s): 

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

Quote:

if u see the datasheet that is attachment page 5 u'll see the address r/w setup time is 23ns...

If you see the datasheet that is attachment page 5 you will see that the address R/W setup time is 23ns MINIMUM with no maximum given.

Thus, as I said in the note above, with an AVR8 it would be impossible to violate with successive operations, no delay or NOP or other consideration needed.

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

if there wasn't maximum given should i take just the minimum?!

Quote:
Thus, as I said in the note above, with an AVR8 it would be impossible to violate with successive operations, no delay or NOP or other consideration needed.

why can't i use nop it may take 100ns

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

-- You are apparently trying to interface to this device with an AVR
-- You want to interface without violating timing parameters
-- The timing parameter in question has a minimum value of 35ns
-- There is no way that you can violate this parameter with an AVR8
-- Your aim is probably to get things done quickly, so don't waste any more than necessary
-- So just do it, then go on to the next operation

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

u mean making that without any delay ... i made that but it didn't work!
i'm thinking of this:
configure the r/w , rs0,cs and the other pins then set the cycle period wait for 0.5us and clear the cycle period , then i make a nop then i disable the chip and get to the next step...
how do u see this?

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

I think you'll find the delay is in there - measure it with an oscilloscope. There is probably a feww instructions executed between outputting the data then asserting the control signal. Put a delay in there if you wish, but I think your problem is elsewhere. Show us your code.

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

i made it but it didn't work...
here is the code :

#include 
#include 
#include  
#define D0 0
#define D1 1
#define D2 2
#define D3 3
#define RS0 4
#define RW 5
#define CS 6
#define P 7
#define SETBIT(ADDRESS,BIT) (ADDRESS |= (1<<BIT)) 
#define CLEARBIT(ADDRESS,BIT) (ADDRESS &= ~(1<<BIT)) 
#define CHECKBIT(ADDRESS,BIT) (ADDRESS & (1<<BIT)) 
void setsend(void)//to write to registers a and b
{
	DDRD=0xFF;
/////////////////////////////////////the settings to write to the register A
	SETBIT(PORTD,CS);
	CLEARBIT(PORTD,RW);
	SETBIT(PORTD,RS0);
	SETBIT(PORTD,D0);
	SETBIT(PORTD,D2);
	SETBIT(PORTD,D3);
	CLEARBIT(PORTD,D1);
//////////////////////////////////////
	CLEARBIT(PORTD,CS);
	SETBIT(PORTD,P);
	asm("nop");
	# define F_CPU 16000000UL
	asm("nop");
	# define F_CPU 2000000UL
	CLEARBIT(PORTD,P);
////////////////////////////////////the settings to write to the register A
	SETBIT(PORTD,CS);
	CLEARBIT(PORTD,D0);
	CLEARBIT(PORTD,D1);
	CLEARBIT(PORTD,D2);
	CLEARBIT(PORTD,D3);
//////////////////////////////////
	CLEARBIT(PORTD,CS);
	SETBIT(PORTD,P);
	asm("nop");
	CLEARBIT(PORTD,P);
	SETBIT(PORTD,CS);
	SETBIT(PORTC,0);
int main(void)// i made it daily read and write to registers a and b until the status register b1 is set so it's ready to transmit
{
	DDRC=0xFF;
	PORTC=0x00;
	setsend();	
	while (1)/
	{
		setsend();
//////////////////////////////////read the status register
		DDRD=0xF0;
		SETBIT(PORTD,RS0);
		SETBIT(PORTD,RW);
		SETBIT(PORTD,D1);
/////////////////////////////////
		CLEARBIT(PORTD,CS);
		SETBIT(PORTD,P);
		asm("nop");
		CLEARBIT(PORTD,P);
		# define F_CPU 16000000UL
		asm("nop");
		# define F_CPU 2000000UL
		if (CHECKBIT(PIND,1))	//TO SEE THAT IF CM8880 READY TO TRANSMIT
		{
			SETBIT(PORTD,CS);
			SETBIT(PORTC,1);
			SETBIT(PORTC,2);

			break;
		}	
		SETBIT(PORTD,CS);
	}

the clock cycle is 2MHz so i get by one nop 0.5us and 16MHz to get the smallest delay i can get...
the port c is just connected to 3 leds for debugging...
when it's ready to transmit the tree leds should light.
i'm so confused about this because i also tried many different tries...

Last Edited: Thu. Jun 21, 2012 - 11:52 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Your {} still don't match ... you need to post code that, at least, compiles - although that is probably not the problem here.

As advised, remove the nop's - they are NOT the cause of the problem. Concentrate on checking the order of setting the pins...you might find someone here willing to do that, but it's your job really :)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
      # define F_CPU 16000000UL
      asm("nop");
      # define F_CPU 2000000UL 

What on earth are you hoping to achieve here? You do realise that #define are preprocessor commands so the C compiler never even sees those lines and as far as I can see this will do nothing more than lead to a "F_CPU was already defined" warning. How long a NOP takes depends on only one thing and that is how fast the CPU is actually clocking at the moment it fetches the opcode - nothing else. You cannot magically change the CPU speed from code with a #define (on some CPUs there is a CLKPR register but that is NOT the answer here!)

Can we assume that the signal you call P here is what the datasheet describes as Phi2 ? To be honest your code is very confusing with oddly chosen names and no comments to say how any particularly part of it relates to any particular timing diagram in the datasheet. Can I take it that setsend() is trying to perform "Microprocessor Write Cycle" shown at the top right of page 6? If so then why on earth don't you put a comment to that effect in the code. This will benefit anyone else trying to read the code and even you when you come back to it in 6 months and wonder "what the hell was this bit supposed to be doing?"

The 23ns figure being discussed here is shown as trws - the minimum time to allow between taking R/W low and then taking Phi2 (the clock) high. So surely the thing you should be worrying about is the time between:

   CLEARBIT(PORTD,RW);

and

   SETBIT(PORTD,P);

as you have 6 other SET/CLEAR operations between the two and each will be a minimum of 2 CPU cycles (time for CBI or SBI opcode) I see at least 12 cycles between the point you set the R/W state and the time the clock goes high so why are you concerned about 23ns. That is going to have taken hundreds if not thousands of nanoseconds!

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

Quote:
"F_CPU was already defined"

so it won't matter what ever number i put it , i thought i can change the clock cycles by it.
Quote:
P here is what the datasheet describes as Phi2 ?
Can I take it that setsend() is trying to perform "Microprocessor Write Cycle" shown at the top right of page 6?

u r right and i edited the code with comments.
Quote:
as you have 6 other SET/CLEAR operations between the two and each will be a minimum of 2 CPU cycles

23 nano seconds after i clear the CS pin (active the chip) that's why i didn't care about it.

so how can i make this code work?

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

It matters very much what number you put in it, but it's not going to change your clock frequency in any way.
The first step in making your cöde work is to ditch those macros of yours and use commenting instead.

"Maybe happiness is just fragments of existence with better packaging."

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

Quote:

so it won't matter what ever number i put it , i thought i can change the clock cycles by it.

Basic misunderstanding of what F_CPU does and is used for.

It is not used to in any way change the CPU frequency the AVR is running at.

It is the other way around: It is used to tell the compiler what speed the AVR is actually running at.

You change the actual CPU frequency by changing the clock selection fuses, and by changing/modifying the actual clock source. If it is e.g. an external crystal then you can exchange the crystal for one of another frequency. If the clock source is an "external clock" then you could possibly modify whatever generates that clock signal. Etc...

F_CPU is used so as to tell the compielr about the actual clock frequency so that it can then generate the correct number of NOPs etc when you code stuff like

_delay_ms(123);

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

Write your stuff like

   PORTD |= (1 << CS);
   PORTD &= ~(1 << RW);
   PORTD |= ((1 << RS0) | (1 << D0) | (1 << D2) | (1 << D3));
   PORTD &= ~(1 << D1);

Then it does that up to 8 times faster, than with your macros.

"Maybe happiness is just fragments of existence with better packaging."

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

Quote:

Then it does that from 2 to 8 times faster, than with your macros.

Utter piffle. Suggest you get yourself a good book about the C preprocessor, what it is and what it does (and what it doesn't do).

You seem to have mistaken macros for called functions?

If you don't know then don't give misleading answers as it will just further confuse the person we're all trying to help.

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

Perhaps. I never meant to mislead anyone, sorry.

"Maybe happiness is just fragments of existence with better packaging."

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

OK, hanemagne..

Are you saying that
PORTD |= (1 << CS);
will create code running "2 to 8 times faster" than

#define CS 6 
#define SETBIT(ADDRESS,BIT) (ADDRESS |= (1<<BIT)) 
.
.
.
SETBIT(PORTD,CS);

?

SETBIT is a macro which, "at compile time", is expanded. In this case it is expanded into

PORTD |= 1<<CS

which is identical to your code. I would expect the generated and executed machine code to be identical. Also with respect to it's running time.

Now, being a curious fellow, I wonder: What did you base your "2 to 8" metric on?

EDIT: Took too long to compse the post. See that Clif, as usual, got in between..

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:

Now, being a curious fellow, I wonder: What did you base your "2 to 8" metric on?


Probably the difference between an SBI and a PORTx |= with a certain toolchain at -O0.

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

Well, I edited my post almost at once, because I saw that "2 to" wasn't correct.
And what I referred to was this:

PORTD |= ((1 << RS0) | (1 << D0) | (1 << D2) | (1 << D3));

Instead of writing several PORTD |= blah and PORTD &= blah, write it all in one line. It's the same register, why not?

EDIT: In hindsight, maybe I should have been clearer about what I referred to earlier on.

"Maybe happiness is just fragments of existence with better packaging."

Last Edited: Thu. Jun 21, 2012 - 01:13 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

a certain toolchain

Ah, the "infinite value" one, eh..? :wink:

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

For registers in reach of in/out and avr-gcc (-Os), if you set two bits, this is faster

PORTB |= (1<<1);
PORTB |= (1<<2);

than this

PORTB |= (1<<1)|(1<<2);

The first version generates two sbi and the second one in, ori, out. All one clock instructions. For three bits it's the same number of cycles, if you set four or more bits the second version is faster.

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

snigelen wrote:
The first version generates two sbi and the second one in, ori, out. All one clock instructions.
No, sbi takes two cycles.

Stefan Ernst

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

Quote:
It matters very much what number you put in it
Well, in this specific case it doesn't matter at all since there is absolutely nothing in the code that cares what F_CPU is defined as. However, if you went back to use something like _delay_us then it would certainly matter.

Regards,
Steve A.

The Board helps those that help themselves.

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

sternst wrote:
No, sbi takes two cycles.
Hm, I had a brain fart there (I must have been thinking of XMega ;-)).
In that case it's always better to put them in one statement. But maybe that's bitpicking ;-).

Last Edited: Thu. Jun 21, 2012 - 03:12 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

A significant difference between

PORTB |= (1<<1); 
PORTB |= (1<<2);

and

PORTB |= (1<<1)|(1<<2); 

is that for the latter, both pins will be set on the same clock cycle. Might matter to you, or might not..

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

it doesn't how should it be written it's not the problem...
how can i make it ? what is the best delay and the best place to put it?

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

YOU DON'T NEED ANY DELAYS IN YOUR CODE

Do you understand why this is? People here will start to get bored if you keep asking about it...and wander off into diversions about the best way of setting ports rapidly/with minimum code etc etc

You (almost certainly) have:
- a wiring problem
- a hardware problem - does your LCD actually work?
- a software problem - you are not twiddling the ports in the right order/with the right sychronisation

If you want help with your code, I suggest posting code that:
- compiles
- has comments in it (and you may find that by commenting it, if you think about each comment carefully, you will find the problem yourself)

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

ok i'll see thanks :D
BTW:

Quote:
- a hardware problem - does your LCD actually work?

i didn't use LCD

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

Google "arduino cm8880" do you get anthing useful?

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

foxbrain wrote:
i didn't use LCD
Sorry - I had it in my mind it was a LCD