Peter schrieb:
> Die 62.5ns gelten natürlich für einen NOP.
...den _delay_us() selbst nicht erzeugen kann, denn es ist eine
fest vorgegebene Schleife. Die macht mindestens einen Durchlauf
mit 2 Takten (der 3. entfällt, da der branch zurück ja nicht
ausgeführt wird), braucht aber außerdem noch Zeit dafür, dass das
Zählregister initialisiert wird. Je nachdem, ob ein entsprechender
Initialisierungswert bereits in einem Register liegt oder nicht,
braucht das also einen weiteren Takt (Register-Register-Kopie) oder
zwei (zusätzlich noch ein LDI Rx, N).
Der AVR-GCC im neuesten WinAVR enthält einen Patch, der die Funktion
__builtin_avr_delay_cycles() bereitstellt; diese Funktion kann eine
zyklengenaue Verzögerung implementieren, da der Compiler das nötige
Wissen besitzt herauszufinden, ob er beispielsweise den Wert erst
noch in ein Register laden muss oder nicht. Dafür kann diese
Funktion natürlich nur ganzzahlige Werte übernehmen, die Umrechnung
mittels F_CPU muss man hier also wieder selbst machen.
In der aktuellen avr-libc (1.7.0) benutzen _delay_us() und _delay_ms()
automatisch die Funktion __builtin_avr_delay_cycles(), allerdings
runden sie derzeit meines Wissens immer nach unten bei der Berechnung
des Arguments.