Discussion Forum

Coding short delays

Next Thread | Thread List | Previous Thread Start a Thread | Settings

DetailsMessage
Read-Only
Author
Graham Cole
Posted
17-Oct-2002 12:16 GMT
Toolset
None
New! Coding short delays
I would like to be able to write code that implements short delays (a few microseconds) but where the code generated automatically adapts to the speed of the processor. i.e. as the processor speed is changed, the delay remains constant.

I don't suppose there is a predefined macro constant available (that Keil hasn't told us about) that makes the cycle time available to the source code?

I guess this is quite a common problem.

uVision seems to know all about time, so would it be difficult for a predefined constant to be provided?
Read-Only
Author
Jon Ward
Posted
29-Oct-2002 16:44 GMT
Toolset
None
New! RE: Coding short delays
Graham,

This is a really good idea. The reason we haven't implemented so far is because there are many devices that have PLLs and clock scalers. So, the oscillator frequency is not enough.

In my applications I manually define a clock value for each target (that runs at different speeds).

Jon
Read-Only
Author
Graham Cole
Posted
31-Oct-2002 09:39 GMT
Toolset
None
New! RE: Coding short delays
Jon,

I appreciate the point about the potential problems, but the simulator does attempt to give a real-time measure of running time. It seems to do a pretty good job in all the instances where I have used it. So, most of the information required must be available to uVision.

This kind of feature would be very useful, even if it did have to carry a "health warning".
Read-Only
Author
Andrew Neil
Posted
31-Oct-2002 14:01 GMT
Toolset
None
New! RE: Coding short delays
"most of the information required must be available to uVision."

Digressing somewhat, an awful lot of information is available to uVision which would be very useful to the application; eg, uVision already informs the C51 source code of the Memory Model selected by means of the __MODEL__ Predefined Macro Constant.

This could easily be extended to include things like:
__XTAL__ - The Crystal frequency entered in the 'Target' options (obviously, it would be up to the user to apply a suitable interpretation to this value);
__XRAM_START0__, __XRAM_SIZE0__, __XRAM_START1__, __XRAM_SIZE1__ etc - the XRAM details entered in the 'Target' options.

These needn't even require any change to the C51 compiler - they could just be (optionally?) placed explicitly on the command line by uVision

It would also be useful if the Linker could provide a symbolic name which would allow the application to determine the last used (or first free) location in XRAM - eg, for buffering.
Read-Only
Author
Bob Horeck
Posted
31-Oct-2002 23:22 GMT
Toolset
None
New! RE: Coding short delays
This may help you out ... in "Delays.h" have the following:
// NOTE: "Crystal" as used below is best defined in some other header unique to your project.

unsigned char Delay8Plus2xCycles (unsigned char x);

#define Crystal  18432000L          /* Crystal speed */
#define ClockRes (Crystal/12)       /* Clock ticks per second */

#define NanoSecondsPerCycle (1000000000L / ClockRes)
#define uSecToInstCycles(x) ((1000L * (x)) / NanoSecondsPerCycle)

#define uSecDelay(InstCycles) \ 
     (((InstCycles) &  1) ? _nop_() : 0), \ 
     (((InstCycles) &  2) ? _nop_(),_nop_() : 0), \ 
     (((InstCycles) & ~7) ? Delay8Plus2nCycles(((InstCycles/4)-2)*2) \ 
     : (((InstCycles) & 4) ? _nop_(),_nop_(),_nop_(),_nop_() : 0))
Then in one of your "C" modules add:
unsigned char Delay8Plus2nCycles (unsigned char LoopCount)
{
    while (--LoopCount);
    return (LoopCount);
}
When you want to delay simply:
#include "Delays.h"

uSecDelay (uSecToInstCycles(15));
As Jon pointed out, this is very efficient with constants. It generates more code if a variable is used.
Read-Only
Author
Bob Horeck
Posted
31-Oct-2002 16:10 GMT
Toolset
None
New! RE: Coding short delays
Getting back to Grahams original issue ... short delays.

Regardless of the way that instruction time is conveyed to the program, it is often desirable to delay for SHORT periods of time.

If this could be done through a macro (assuming that clock speed doesn't change while running) it would be great.

Obviously, one can make a simple loop of the form:
{
unsigned char Delay = DelayTimeInCycles/2;
while (--Delay);
}

This would take care of multiples of two cycles, providing that the delay is longer than the minimum 4 cycles needed, two to load Delay and two for the decrement.

It would seem to me that this code is tight enough so that a call to the delay would provide only a very slight advantage in size.

Now the hard part ... how do you generate a macro that calculates DelayTimeInCycles from an argument specified in microseconds, handles the odd count, and produces a variable number of _nop_() statements to deal with delays shorter than 4 cycles.

I keep looking for a simple recursive macro to do the job, but never seem to get it right. Any ideas?

Read-Only
Author
Jon Ward
Posted
31-Oct-2002 17:18 GMT
Toolset
None
New! RE: Coding short delays
Now the hard part ... how do you generate a macro that calculates DelayTimeInCycles from an argument specified in microseconds, handles the odd count, and produces a variable number of _nop_() statements to deal with delays shorter than 4 cycles.

You ask ME. That's how!

The following macro

#define NOPS(x)		\ 
	(((x) & 1) ? _nop_() : 0), \ 
	(((x) & 2) ? _nop_(),_nop_() : 0), \ 
	(((x) & 4) ? _nop_(),_nop_(),_nop_(),_nop_() : 0), \ 
	(((x) & 8) ? _nop_(),_nop_(),_nop_(),_nop_(),_nop_(),_nop_(),_nop_(),_nop_() : 0)

inserts the number of NOPs specified as the argument. The valid range of values is 0-15. However, I'm sure you can easily modify this baby.

Jon
Read-Only
Author
Jon Ward
Posted
31-Oct-2002 17:23 GMT
Toolset
None
New! RE: Coding short delays
NOTE: Do not use variables with this macro. Use constants only. Using a variable causes actual code to be generated for each ternary operator. Using constants causes the ternary operator to be evaluated by the preprocessor (which is what we want).

Jon
Read-Only
Author
Bob Horeck
Posted
31-Oct-2002 23:30 GMT
Toolset
None
New! RE: Coding short delays
I don't know how my formatting screwed up or the reply appeared out of order. But the example does work.
Read-Only
Author
Jon Ward
Posted
1-Nov-2002 14:33 GMT
Toolset
None
New! RE: Coding short delays
The problem (and I had this, too) is the \ at the end of the line. Aparently, this causes some problems in SQL server. I had to add a space after my \ for it to format correctly.

Jon

Next Thread | Thread List | Previous Thread Start a Thread | Settings