@@ -119,17 +119,41 @@ void delay(unsigned long ms)
119
119
}
120
120
}
121
121
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. */
123
123
void delayMicroseconds (unsigned int us )
124
124
{
125
+ // call = 4 cycles + 2 to 4 cycles to init us(2 for constant delay, 4 for variable)
125
126
// calling avrlib's delay_us() function with low values (e.g. 1 or
126
127
// 2 microseconds) gives delays longer than desired.
127
128
//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
129
153
// for the 20 MHz clock on rare Arduino boards
130
154
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.
133
157
__asm__ __volatile__ (
134
158
"nop" "\n\t"
135
159
"nop" ); //just waiting 2 cycle
@@ -152,15 +176,31 @@ void delayMicroseconds(unsigned int us)
152
176
if (-- us == 0 )
153
177
return ;
154
178
155
- // the following loop takes a quarter of a microsecond (4 cycles)
179
+ // the following loop takes 1/4 of a microsecond (4 cycles)
156
180
// per iteration, so execute it four times for each microsecond of
157
181
// delay requested.
158
- us <<= 2 ;
182
+ us <<= 2 ; // x4 us
159
183
160
184
// account for the time taken in the preceeding commands.
161
185
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
164
204
165
205
// for a one- or two-microsecond delay, simply return. the overhead of
166
206
// the function calls takes more than two microseconds. can't just
@@ -170,21 +210,39 @@ void delayMicroseconds(unsigned int us)
170
210
if (-- us == 0 )
171
211
return ;
172
212
173
- // the following loop takes half of a microsecond (4 cycles)
213
+ // the following loop takes 1/2 of a microsecond (4 cycles)
174
214
// per iteration, so execute it twice for each microsecond of
175
215
// delay requested.
176
- us <<= 1 ;
216
+ us <<= 1 ; //x2 us
177
217
178
218
// partially compensate for the time taken by the preceeding commands.
179
219
// we can't subtract any more than this or we'd overflow w/ small delays.
180
220
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
181
238
#endif
182
239
183
240
// busy wait
184
241
__asm__ __volatile__ (
185
242
"1: sbiw %0,1" "\n\t" // 2 cycles
186
243
"brne 1b" : "=w" (us ) : "0" (us ) // 2 cycles
187
244
);
245
+ // return = 4 cycles
188
246
}
189
247
190
248
void init ()
0 commit comments