@@ -119,17 +119,41 @@ void delay(unsigned long ms)
119119 }
120120}
121121
122- /* Delay for the given number of microseconds. Assumes a 8 or 16 MHz clock. */
122+ /* Delay for the given number of microseconds. Assumes a 1, 8, 12, 16, 20 or 24 MHz clock. */
123123void delayMicroseconds (unsigned int us )
124124{
125+ // call = 4 cycles + 2 to 4 cycles to init us(2 for constant delay, 4 for variable)
125126 // calling avrlib's delay_us() function with low values (e.g. 1 or
126127 // 2 microseconds) gives delays longer than desired.
127128 //delay_us(us);
128- #if F_CPU >= 20000000L
129+ #if F_CPU >= 24000000L
130+ // for the 24 MHz clock for the aventurous ones, trying to overclock
131+
132+ // for a one-microsecond delay, simply wait 6 cycles and return. The overhead
133+ // of the function call yields a delay of exactly one microsecond.
134+ __asm__ __volatile__ (
135+ "nop" "\n\t"
136+ "nop" "\n\t"
137+ "nop" "\n\t"
138+ "nop" "\n\t"
139+ "nop" "\n\t"
140+ "nop" ); //just waiting 6 cycles
141+ if (-- us == 0 )
142+ return ;
143+
144+ // the following loop takes a 1/6 of a microsecond (4 cycles)
145+ // per iteration, so execute it six times for each microsecond of
146+ // delay requested.
147+ us *= 6 ; // x6 us
148+
149+ // account for the time taken in the preceeding commands.
150+ us -= 2 ;
151+
152+ #elif F_CPU >= 20000000L
129153 // for the 20 MHz clock on rare Arduino boards
130154
131- // for a one-microsecond delay, simply wait 2 cycle and return. The overhead
132- // of the function call yields a delay of exactly a one microsecond.
155+ // for a one-microsecond delay, simply wait 2 cycles and return. The overhead
156+ // of the function call yields a delay of exactly one microsecond.
133157 __asm__ __volatile__ (
134158 "nop" "\n\t"
135159 "nop" ); //just waiting 2 cycle
@@ -152,15 +176,31 @@ void delayMicroseconds(unsigned int us)
152176 if (-- us == 0 )
153177 return ;
154178
155- // the following loop takes a quarter of a microsecond (4 cycles)
179+ // the following loop takes 1/4 of a microsecond (4 cycles)
156180 // per iteration, so execute it four times for each microsecond of
157181 // delay requested.
158- us <<= 2 ;
182+ us <<= 2 ; // x4 us
159183
160184 // account for the time taken in the preceeding commands.
161185 us -= 2 ;
162- #else
163- // for the 8 MHz internal clock on the ATmega168
186+
187+ #elif F_CPU >= 12000000L
188+ // for the 12 MHz clock if somebody is working with USB
189+
190+ // for a one-microsecond delay, simply return. the overhead
191+ // of the function call yields a delay of approximately 1.5 us.
192+ if (-- us == 0 )
193+ return ;
194+
195+ // the following loop takes 1/3 of a microsecond (4 cycles)
196+ // per iteration, so execute it three times for each microsecond of
197+ // delay requested.
198+ us = (us << 1 ) + us ; // x3 us
199+
200+ // account for the time taken in the preceeding commands.
201+ us -= 2 ;
202+ #elif F_CPU >= 8000000L
203+ // for the 8 MHz internal clock
164204
165205 // for a one- or two-microsecond delay, simply return. the overhead of
166206 // the function calls takes more than two microseconds. can't just
@@ -170,21 +210,39 @@ void delayMicroseconds(unsigned int us)
170210 if (-- us == 0 )
171211 return ;
172212
173- // the following loop takes half of a microsecond (4 cycles)
213+ // the following loop takes 1/2 of a microsecond (4 cycles)
174214 // per iteration, so execute it twice for each microsecond of
175215 // delay requested.
176- us <<= 1 ;
216+ us <<= 1 ; //x2 us
177217
178218 // partially compensate for the time taken by the preceeding commands.
179219 // we can't subtract any more than this or we'd overflow w/ small delays.
180220 us -- ;
221+
222+ #else
223+ // for the 1 MHz internal clock (default settings for common Atmega microcontrollers)
224+
225+ // the overhead of the function calls takes about 16 microseconds.
226+ if (us <= 16 ) //4 cycles spent here
227+ return ;
228+ if (us <= 22 ) { //4 cycles spent here
229+ return ;
230+ }
231+
232+ // compensate for the time taken by the preceeding and next commands.
233+ us -= 22 ;
234+
235+ // the following loop takes 4 microseconds (4 cycles)
236+ // per iteration, so execute it us/4 times
237+ us >>= 2 ; // us div 4
181238#endif
182239
183240 // busy wait
184241 __asm__ __volatile__ (
185242 "1: sbiw %0,1" "\n\t" // 2 cycles
186243 "brne 1b" : "=w" (us ) : "0" (us ) // 2 cycles
187244 );
245+ // return = 4 cycles
188246}
189247
190248void init ()
0 commit comments