Stumpyhuck29
Stumpyhuck29

Reputation: 63

Generic Microcontroller Delay Function

Come someone please tell me how this function works? I'm using it in code and have an idea how it works, but I'm not 100% sure exactly. I understand the concept of an input variable N incrementing down, but how the heck does it work? Also, if I am using it repeatedly in my main() for different delays (different iputs for N), then do I have to "zero" the function if I used it somewhere else? Reference: MILLISEC is a constant defined by Fcy/10000, or system clock/10000.

Thanks in advance.

// DelayNmSec() gives a 1mS to 65.5 Seconds delay
/*  Note that FCY is used in the computation.  Please make the necessary
    Changes(PLLx4 or PLLx8 etc) to compute the right FCY as in the define
    statement above. */
void DelayNmSec(unsigned int N)
{
unsigned int j;
    while(N--)
        for(j=0;j < MILLISEC;j++);
}

Upvotes: 0

Views: 3563

Answers (3)

Soren
Soren

Reputation: 14718

The original author of the code have timed and looked at the assembler generated to get the exact number of instructions executed per Millisecond, and have configured a constant MILLISEC to match that for the for loop as a busy-wait.

The input parameter N is then simply the number of milliseconds the caller want to wait and the number of times the for-loop is executed.

The code will break if

  • used on a different or faster micro controller (depending on how Fcy is maintained), or
  • the optimization level on the C compiler is changed, or
  • c-compiler version is changed (as it may generate different code)

so, if the guy who wrote it is clever, there may be a calibration program which defines and configures the MILLISEC constant.

Upvotes: 3

Richard Chambers
Richard Chambers

Reputation: 17643

This is what is known as a busy wait in which the time taken for a particular computation is used as a counter to cause a delay.

This approach does have problems in that on different processors with different speeds, the computation needs to be adjusted. Old games used this approach and I remember a simulation using this busy wait approach that targeted an old 8086 type of processor to cause an animation to move smoothly. When the game was used on a Pentium processor PC, instead of the rocket majestically rising up the screen over several seconds, the entire animation flashed before your eyes so fast that it was difficult to see what the animation was.

This sort of busy wait means that in the thread running, the thread is sitting in a computation loop counting down for the number of milliseconds. The result is that the thread does not do anything else other than counting down.

If the operating system is not a preemptive multi-tasking OS, then nothing else will run until the count down completes which may cause problems in other threads and tasks.

If the operating system is preemptive multi-tasking the resulting delays will have a variability as control is switched to some other thread for some period of time before switching back.

This approach is normally used for small pieces of software on dedicated processors where a computation has a known amount of time and where having the processor dedicated to the countdown does not impact other parts of the software. An example might be a small sensor that performs a reading to collect a data sample then does this kind of busy loop before doing the next read to collect the next data sample.

Upvotes: 2

Pavel
Pavel

Reputation: 7562

This is referred to as busy waiting, a concept that just burns some CPU cycles thus "waiting" by keeping the CPU "busy" doing empty loops. You don't need to reset the function, it will do the same if called repeatedly.

If you call it with N=3, it will repeat the while loop 3 times, every time counting with j from 0 to MILLISEC, which is supposedly a constant that depends on the CPU clock.

Upvotes: 3

Related Questions