delay_us()

Gast #598865
Lesenswert?

HY Leute!
Hab ein großes Problem!! Wenn ich eine us erzeugen will, nehme ich diese 
delay_us(1) Funktion her und es funktioniert. Jedoch will ich flexibel 
sein und alle möglichen zeiten einstellen können. Ich hab es zuerst mit 
einer for Schleife probiert, in welcher die Funktion x mal aufgerufen 
wird.
Beim Nachmessen bin ich draufgekommen, dass es die Zeit größer 
ist(warscheinlich + Abarbeitungszeit). Dann hab ich probiert eine 
Variable der delay_us(VAR) zu übergeben - ging auch nicht

Hat von euch irgendwer ne Idee, wie ich das in Griff bekomme?
Vielleicht die FUnktion delay_us(unsigned int n) irgendwie ändern???
Moderator Persönliche Seite #598873
Lesenswert?

Naja, _delay_us() lebt davon, dass das Argument vom Compiler zur
Compilezeit ausgewertet werden kann.  Gerade bei kurzen
Verzögerungen (und dafür ist _delay_us() ja da) kommt bei einer
weiteren Schleife natürlich zusätzlicher Overhead hinzu.

Bei den längeren Schleifen, die _delay_ms() benutzt, ist der
Einfluss einer äußeren Schleife dann deutlich geringer.  Was
daher brauchbar funktioniert ist sowas wie:
1
void delay_1s(void)
2
{
3
  uint8_t i;
4

5
  for (i = 0; i < 100; i++)
6
    _delay_ms(10);
7
}

10 ms sind für alle derzeitigen AVRs (max. 20 MHz Takt) im sicheren
Bereich, der von _delay_ms() erfasst werden kann.

Ansonsten der übliche Hinweis: diese Funktionen sind für kurze
Wartezeiten gedacht, bei denen es sich nicht lohnt, erst einen
Timer anzuwerfen.  Das Timing der gesamten Applikation sollte man
aber bitte denen überlassen, die darauf spezialisiert sind.  Man
muss wohl nicht erst in den Gelben Seiten nachgucken um rauszufinden,
dass dafür die Timer da sind...
#598959
Lesenswert?

Jörg Wunsch wrote:
>> Wirklich genau geht es eigentlich nur in Assembler
>
> Was anderes machen die diversen _delay_XXX-Funktionen nicht.

Das ist schon klar, aber diese sind in diesem Fall nicht nutzbar, 
zumindest nicht unverändert.
Man könnte aber die _delay_loop_2(uint16_t __count) Funktionen aus der 
delay.h aufrufen.
Moderator Persönliche Seite #598964
Lesenswert?

Benedikt K. wrote:

> Das ist schon klar, aber diese sind in diesem Fall nicht nutzbar,
> zumindest nicht unverändert.

Warum nicht?

Du hast halt den Overhead der äußeren Schleife, aber den hast du
bei einer Assemblerimplementierung ebenfalls, da du ja keine
Bruchteile von Befehlen abziehen kannst.

> Man könnte aber die _delay_loop_2(uint16_t __count) Funktionen aus der
> delay.h aufrufen.

Genau das macht ja _delay_ms(), nur dass es den Compiler noch den
Wert __count berechnen lässt.
Moderator Persönliche Seite #599002
Lesenswert?

Naja, viel sinnvoller ist es, dann doch lieber die Timer zu benutzen,
statt endlos Gehirnschmalz darüber zu verbraten, wie man die CPU
möglichst zyklengenau elektrische Energie in Wärme umwandeln lassen
kann...

Die delay-Funktionen (egal welche) sind sinnvoll für Dinge wie das
Timing eines HD44780-Zugriffs oder einer 1-wire-Routine einzustellen,
aber nicht dafür, dass man das Zeitraster der kompletten Applikation
damit zusammenbaut.  Das können Timer viel effektiver.
#599015
Lesenswert?

Damit wären wir wieder bei dem was ich zuerst geschrieben habe: Timer 
sind klar die bessere Wahl, vor allem wenn es genau sein soll.
Ich muss gestehen: Für viele Sachen nutze ich die _delay_ms() Makros 
gerne auch, um einige 100ms oder gar mehrer Sekunden Pause einzufügen. 
Wenn der µC sowiso auf den Benutzer warten muss, dann ist es egal ob 
dieser in einer sinnlosen Warteschlange auf den Timer wartet, oder 
solange Werte runterzählt.
Moderator Persönliche Seite #599020
Lesenswert?

Benedikt K. wrote:

> Damit wären wir wieder bei dem was ich zuerst geschrieben habe: ...

Ich auch. :-)

> Ich muss gestehen: Für viele Sachen nutze ich die _delay_ms() Makros
> gerne auch, um einige 100ms oder gar mehrer Sekunden Pause einzufügen.

Für einen schnellen Prototypen nehme ich sie auch gern.

> Wenn der µC sowiso auf den Benutzer warten muss, dann ist es egal ob
> dieser in einer sinnlosen Warteschlange auf den Timer wartet, oder
> solange Werte runterzählt.

Naja, ich habe mir mittlerweile angewöhnt, am Ende der main loop
immer ein sleep_mode() mit einzubauen.  Egal, wie viel Strom es
wirklich spart, schaden kann's nicht.
Gast #599028
Lesenswert?

@ Benedikt K. (benedikt)

>Ich muss gestehen: Für viele Sachen nutze ich die _delay_ms() Makros
>gerne auch, um einige 100ms oder gar mehrer Sekunden Pause einzufügen.
>Wenn der µC sowiso auf den Benutzer warten muss, dann ist es egal ob
>dieser in einer sinnlosen Warteschlange auf den Timer wartet, oder
>solange Werte runterzählt.

Nöö, bei _delay_ms() verbrät er mit maximalem Takt Energie, beim Timer 
kann man zumindest in den Idle Sleep Mode schalten. Ist in mobilen 
Geräten sicher keine schlechte Idee.

MfG
Falk

#599063
Lesenswert?

Das ist klar, dann kann man sogar den Bedientaster an den INT Pin hängen 
und den µC komplett abschalten.

Wenn das ganze aber sowiso an einem 5V 5A Netzteil hängt, dann sind die 
paar mA sch... egal. Das Backlight des Displays (dessen Text der 
Benutzer gerade liest) verbraucht da schon sehr viel mehr.

Ich versuche generell immer möglichst sparsam zu programmieren, aber man 
muss es ja nicht übertreiben.
Gast #600537
Lesenswert?

> Nöö, bei _delay_ms() verbrät er mit maximalem Takt Energie, beim Timer
> kann man zumindest in den Idle Sleep Mode schalten. Ist in mobilen
> Geräten sicher keine schlechte Idee.

Kommt halt immer auf das Einsatzgebiet an. Ich habe meistens keine so 
eingeschränkte Stromversorgung, dafür aber manchmal recht enge Timings 
einzuhalten. Die Reaktionszeit auf einen Interrupt aus dem Sleep-Mode 
heraus ist aber höher als aus dem Normalbetrieb.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren