This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

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?

Parents
  • 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?

Reply
  • 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?

Children
  • 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

  • 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

  • I don't know how my formatting screwed up or the reply appeared out of order. But the example does work.

  • 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