-
-
Notifications
You must be signed in to change notification settings - Fork 7k
delayMicroseconds(): added support for 1Mhz, 12Mhz and 24Mhz #1678
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
Conversation
1Mhz is a default clock speed on Atmega328, many users run it on the internal 1Mhz clock to save battery power. Up until now delayMicroseconds() function wasn't taking this frequencies into an account.
Could you perhaps add support for 10MHz as well? |
Nativelly arduino has support for 20Mhz? 'cause I use 20Mhz clock and it will be great to have supported that hz to. Thanks for your work |
The branch I edited already had 20Mhz support, I can add 10Mhz support later, right now 10Mhz will default to 8Mhz, with 20% error, close enough :) |
Thanks. I would really appreciate that :) |
Thanks |
I fixed the problem with zero delay, I also fixed the problem with ADC prescaler. I tested the microdelay with an oscilloscope, everything works fine now. |
Can I build this pull request? |
Yes, please. |
@cano64 sorry for the arduinobot comment. we are setting up automatic build of pull requests |
Can we please merge it already? It's been open for a year and half. I spent a lot of time writing and fine tuning it and it has been working fine over the past year and half. |
Rebased and merged the fix. |
Just checked the 1.6.4 (AVR) code and you still cannot call delayMicroSeconds(0) as the --us statement wraps around. Apparently nobody tested it ... The patch was in already in my issue of 18 nov 2012 The code below is FAULTY! 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 == 0)
return;
// 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.
if (--us == 0)
return;
// 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;
// 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
);
} |
@RobTillaart |
@cmaglie Please check the wiring.c in that zip (1.6.4 of course) |
Right, the patch has been merged after IDE 1.6.4. BTW IDE 1.6.5 should ship the latest or, alternatively, you can update the AVR core through Cores Manager. |
Thanks, I'll check the 1.6.5. instead. |
1Mhz is a default clock speed on Atmega328, many users run stand alone microcontroller on the
internal 1Mhz clock to save battery power. Up until now delayMicroseconds() function wasn't taking this frequencies into an account defaulting to 8Mhz resulting incorrect timing. Patch includes support for 12 and 24 Mhz clock as well