-
-
Notifications
You must be signed in to change notification settings - Fork 7k
delayMicroseconds(0) delays far longer than expected. [imported] #576
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Patched version of the function delayMicroseconds() /* Delay for the given number of microseconds. Assumes a 8 or 16 MHz clock. */ #if F_CPU >= 16000000L
#else
#endif
} |
updated for 20Mhz void delayMicroseconds(unsigned int us)
{
// calling avrlib's delay_us() function with low values (e.g. 1 or
// 2 microseconds) gives delays longer than desired.
//delay_us(us);
#if F_CPU >= 20000000L
// for the 20 MHz clock on rare Arduino boards
// for a one-microsecond delay, simply wait 2 cycle and return. The overhead
// of the function call yields a delay of exactly a one microsecond.
__asm__ __volatile__ (
"nop" "\n\t"
"nop"); //just waiting 2 cycle
if (us <= 1)
return;
us--;
// the following loop takes a 1/5 of a microsecond (4 cycles)
// per iteration, so execute it five times for each microsecond of
// delay requested.
us = (us<<2) + us; // x5 us
// account for the time taken in the preceeding commands.
us -= 2;
#elif F_CPU >= 16000000L
// for the 16 MHz clock on most Arduino boards
// for a one-microsecond delay, simply return. the overhead
// of the function call yields a delay of approximately 1 1/8 us.
// FIX
// if (--us == 0)
// return;
if (us < 2) return;
us--;
// the following loop takes a quarter of a microsecond (4 cycles)
// per iteration, so execute it four times for each microsecond of
// delay requested.
us <<= 2;
// account for the time taken in the preceeding commands.
us -= 2;
#else
// for the 8 MHz internal clock on the ATmega168
// for a one- or two-microsecond delay, simply return. the overhead of
// the function calls takes more than two microseconds. can't just
// subtract two, since us is unsigned; we'd overflow.
// if (--us == 0)
// return;
// if (--us == 0)
// return;
if (us < 3) return;
us -= 2;
// the following loop takes half of a microsecond (4 cycles)
// per iteration, so execute it twice for each microsecond of
// delay requested.
us <<= 1;
// partially compensate for the time taken by the preceeding commands.
// we can't subtract any more than this or we'd overflow w/ small delays.
us--;
#endif
// busy wait
__asm__ __volatile__ (
"1: sbiw %0,1" "\n\t" // 2 cycles
"brne 1b" : "=w" (us) : "0" (us) // 2 cycles
);
} |
See #1121 |
This is Issue 576 moved from a Google Code project.
Added by 2011-08-05T07:49:00.000Z by [email protected].
Please review that bug for more context and additional comments, but update this bug.
Original labels: Type-Defect, Priority-Medium
Original description
What steps will reproduce the problem?
See - http://arduino.cc/forum/index.php/topic,68383.0.html
Due to predecrement of the param us, the function does not work as expected when the param is 0.
snippet of the code:
void delayMicroseconds(unsigned int us)
{
if (--us == 0)
return;
...
What is the expected output? What do you see instead?
Expected an immediate return;
See, long busy wait
Please provide any additional information below.
Fix proposed - http://arduino.cc/forum/index.php/topic,68383.msg504892.html#msg504892
replace
if (--us == 0)
return;
with (16 Mhz)
if (us < 2)
return;
us--;
Fix not tested.
The text was updated successfully, but these errors were encountered: