www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Unterschiede bei _delay_ms()


Autor: Matze Niemand (hupe123)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Moin,

ich habe grade etwas zeitkritsches programmiert und mir stellt sich un 
die Frage, warum:
 // Im Programm das hier aufrufen

warten_ms(50);

//Mit warte_ms als

void warten_ms(unsigned int i)
{
for (j=0;j>i;j++)
   _delay_ms(1);
} 

länger dauert als
_delay_ms(50);

Wobei man ja eigentlich den ersten Fall benutzen soll.

Gruß,
Matze

Autor: Andreas K. (derandi)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Weil es wohl einen unterschied machst ob du eine Funktion nur einmal 
oder 50 mal aufrufst?

Autor: Matze Niemand (hupe123)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das würde für zweite Beispiel sprechen. Aber eigentlich soll man doch 
das erste benutzen...

Autor: Alexander Schmidt (esko) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Die Schleife geht bis i größer j ist. So war das sicher nicht gedacht.
Du brauchst:
for (j=0;j<i;j++)
   _delay_ms(1);

Autor: Wolfgang M. (womai)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Die Version mit der Schleife hat viel mehr zu tun: Zaehler erhoehen, 
Schleifenbedingung ueberpruefen, zurueckspringen zumm Anfang der 
Schleife. alles das 50 mal. Ass das braucht extra Zeit.

Autor: Justus Skorps (jussa)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
afaik wird der Compiler bei der zweiten Variante die benötigte Zeit für 
den Funktionsaufruf etc mitberücksichigen, so dass wirklich nur 50 ms 
pausiert wird. Bei der ersten Variante hast du aber 50x 1 ms Delay und 
dazu den Overhead...

Autor: Matze Niemand (hupe123)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ok ok, alles Beispiele für das zweite Beispiel und wieso soll dann das 
erste verbauen?!

gruß

Autor: Alexander Schmidt (esko) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
So sollte es klarer sein:
//Zählt bis 0
for (j=0;j>50;j++)
   _delay_ms(1);

Autor: Michael Lenz (hochbett)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> So sollte es klarer sein:
>
//Zählt bis 0
> for (j=0;j>50;j++)
>    _delay_ms(1);

Weshalb nimmst du ein Größerzeichen und nicht das Kleinerzeichen, also
for (j=0;j<50;j++) ...
statt
for (j=0;j>50;j++) ...

> Wobei man ja eigentlich den ersten Fall benutzen soll.
Wie kommst Du darauf?

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> ich habe grade etwas zeitkritsches programmiert
> ...
> _delay_ms(50);


das widerspricht sich sowieso.
zeitkritisch und Warteschleifen in dieser Dimension passen nicht 
zusammen

Autor: Andreas K. (derandi)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jaa, da isses wieder, der winzige Tippfehler, unbemerkt aber fatal. :)

Vielleicht meint er mit Zeitkritisch ja etwas mit genauen Timing?

Autor: Rik Langobar (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich kann mir nicht vorstellen, warum "warten_ms(50)" in diesem Fall 
laenger brauchen sollte als "_delay_ms(50)": schliesslich bricht ...
for (j=0;j>i;j++)
... direkt beim ersten Durchlauf ab.

Autor: hsh (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wo hast du bitte her, dass man für delays Schleifen verwenden soll?
Hinter der Definition von delay_ms() steht in der Regel ein Makro das 
dir entprechend der Taktfrequenz die richtige Anzahl NOPs einfügt.

Die Eigenbauschleife würde auch gehn. Dann musst du aber nachrechnen 
wieviele Takte die Schleife braucht. Damit du das nicht tun musst gibt 
es die vordefinierten delay-Funktionen.

Da es in der Regel unsinnig ist den µC tausende Take lang nichts tun zu 
lassen, verwendet man in der Regel einen Timer mit entsprechendem 
Interrupt.

Dass die erstere Version für Wartezeiten verwendet werden soll ist 
definitiv falsch. Wenn du es aus einem Lehrbuch hast, wirf es weg. Wenn 
dir das jemand sa erklärt hat, hat er keine Ahnung.

Autor: Rik Langobar (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hsh schrieb:
> Wo hast du bitte her, dass man für delays Schleifen verwenden soll?

Ganz Unrecht hat er damit nicht, solange er sich auf die 
delay-Funktionen der avr-libc bezieht: die koennen naemlich, abhaengig 
von der eingestellten Taktfrequenz, nur Werte kleiner als 255 korrekt 
verarbeiten, d.h. _delay_ms(50) geht eventuell schief.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Rik Langobar schrieb:

> Ganz Unrecht hat er damit nicht, solange er sich auf die
> delay-Funktionen der avr-libc bezieht: die koennen naemlich, abhaengig
> von der eingestellten Taktfrequenz, nur Werte kleiner als 255 korrekt
> verarbeiten, d.h. _delay_ms(50) geht eventuell schief.

Besorg dir bitte ein WinAvr Update.
Diese Einschränkung gibt es schon lange nicht mehr.

Autor: Rik Langobar (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Zitat aus 
http://www.nongnu.org/avr-libc/user-manual/group__... :
> The maximal possible delay is 262.14 ms / F_CPU in MHz.

(Im Uebrigen laueft WinAVR nicht unter Linux ;-) )

Autor: Alexander Schmidt (esko) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Die Frage ist auch wie zeitkritisch die 50ms sind.

Autor: Uwe ... (uwegw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Rik Langobar schrieb:
> Zitat aus
> http://www.nongnu.org/avr-libc/user-manual/group__... :
>> The maximal possible delay is 262.14 ms / F_CPU in MHz.
>
> (Im Uebrigen laueft WinAVR nicht unter Linux ;-) )

Der nächste Absatz:
> When the user request delay which exceed the maximum possible one,
> _delay_ms() provides a decreased resolution functionality. In this mode
> _delay_ms() will work with a resolution of 1/10 ms, providing delays up
> to  6.5535 seconds (independent from CPU frequency). The user will not
> be informed about decreased resolution.

Im Übrigen hat das nichts mit WinAVR zu tun, sondern mit der avr-libc, 
und die gibt es natürlich auch für linux.

Autor: Rik Langobar (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Uwe ... schrieb:
> Rik Langobar schrieb:
>> Zitat aus
>> http://www.nongnu.org/avr-libc/user-manual/group__... :
>>> The maximal possible delay is 262.14 ms / F_CPU in MHz.
>>
>> (Im Uebrigen laueft WinAVR nicht unter Linux ;-) )
>
> Der nächste Absatz:
>>When the user request delay which exceed the maximum possible one, >_delay_ms()
> provides a decreased resolution functionality. In this mode >_delay_ms() will 
work
> with a resolution of 1/10 ms, providing delays up to >6.5535 seconds 
(independent
> from CPU frequency). The user will not be >informed about decreased resolution.
>
> Im Übrigen hat das nichts mit WinAVR zu tun, sondern mit der avr-libc,
> und die gibt es natürlich auch für linux.

Das dass nichts mit Linux zu tun ist mir klar, die Aussage bezog sich 
auf den Hinweis ich solle mein WinAVR updaten. Meine Angabe "255" war 
ein Schnellschuss, aendert aber nichts daran, dass die Korrekte 
Verarbeitung von der Taktfrequenz abhaengig ist.

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@  hsh (Gast)

>Wo hast du bitte her, dass man für delays Schleifen verwenden soll?

Aus dem Forum?

>Hinter der Definition von delay_ms() steht in der Regel ein Makro das
>dir entprechend der Taktfrequenz die richtige Anzahl NOPs einfügt.

Das Makro verwendet keinerlei NOP. Es ist nixhts weiter als eine 16 Bit 
Zählschleife in ASM ;-)

>Die Eigenbauschleife würde auch gehn. Dann musst du aber nachrechnen
>wieviele Takte die Schleife braucht. Damit du das nicht tun musst gibt
>es die vordefinierten delay-Funktionen.

Nöö. Denn die kann nur mit konstanten Werten aufgerufen werden. Die 
Schleifenfunktion mit variablen. Und genau DAs ist der Sinn der Sache. 
Der Overhead der Schleife fällt praktisch nicht ins Gewicht, da man 
sowieso nie EXAKT 50ms mit so einem Anstatz erwartet und auch nicht 
braucht.

>Da es in der Regel unsinnig ist den µC tausende Take lang nichts tun zu
>lassen, verwendet man in der Regel einen Timer mit entsprechendem
>Interrupt.

Jain. Für Anfänger und einfache Sachen ist _delay_ms() absolut OK.

MfG
Falk

Autor: ... ... (docean) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.