www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik AVR-Delay-Funktion!?


Autor: Enrico. J. (ejoerns)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Moin, was haltet ihr von dieser Konstruktion einer Warte-Funktion?
Habe versucht mit c eine möglichst genaue und gleichzeitig für längere
Zeitintervalle brauchbare Zeitfunktion zu entwickeln.

Ich hoffe mal, dass ich dort keinen Denkfehler hab..


/** Wartet  genau für die angegebene Anzahl Takte
 *  @param  takte  16-Bit Variable für die Anzahl zu wartener Takte.
 *  @note   Bei 14.7456Mhz entsprich das etwa einer maximalen Wartedauer
 *          von 4,444ms
 *  @note   Die minimale Wartezeit liegt bei 17/F_CPU, also etwas über 
1us bei
 *          14,17456Mhz.
 *  @note   Mit avr-gcc-Flag '-s' compilieren!
 **/
void waitTakte(uint16_t takte){
// specifies how long the actions take (for calculating cycle numbers)
#define LOOP_CLOCKS 8
#define CALC_CLOCKS 17
  // takes 17 clock cycles
  takte /= LOOP_CLOCKS;
  // this loop takes 8 cylces with 16-bit var 'takte'!
  while (takte > (uint8_t) (CALC_CLOCKS/LOOP_CLOCKS)) {
    asm volatile("nop");
    takte--;
  }
}

Viele Grüße, Enrico

Autor: STK500-Besitzer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>was haltet ihr von dieser Konstruktion einer Warte-Funktion?
Ich persönlich gar nichts.

>Habe versucht mit c eine möglichst genaue und gleichzeitig für längere
>Zeitintervalle brauchbare Zeitfunktion zu entwickeln.
Dafür kann man auch Timer benutzen...

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@  Enrico J. (ejoerns)

>Moin, was haltet ihr von dieser Konstruktion einer Warte-Funktion?

Sie ist schlecht. Die bereits vorhandenen _delay_ms() und _delay_us() 
sind um Längen besser.

http://www.mikrocontroller.net/articles/AVR-GCC-Tu...

>Habe versucht mit c eine möglichst genaue und gleichzeitig für längere
>Zeitintervalle brauchbare Zeitfunktion zu entwickeln.

Was mal vollkommen daneben gegangen ist. Besser so.

AVR - Die genaue Sekunde / RTC

MFG
Falk

Autor: Christian H. (netzwanze) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wieso verwendest Du Defines innerhalb einer Funktion?

Sowas macht man in einer Header-Datei oder am Programmanfang (wenn es 
nur eine Datei ist), wenn die Konstanten einfach änderbar sein sollen. 
Ansonten kannst Du die Werte (vor allem, wenn sie nur einmal benutzt 
werden) auch direkt in die Funktion schreiben.

Übrigens:
CALC_CLOCKS/LOOP_CLOCKS = 2

Autor: Enrico. J. (ejoerns)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@STK500-Besitzer: Und wenn ich die für was anderes brauche?

@Falk Brunner: Was genau ist daneben gegangen?
Die Funktionen aus delay.h haben doch schon ein sehr eingeschränkten 
Zeitbereich!

@Christian H.: Die Defines sind nur um (mir) klar zu machen wo die Werte 
herkommen ;)
Fühle mich sogar in der Lage 17/8 zu rechnen ;) Aber das tut der 
dortigen Schreibweise, bzw. dem Programmcode, der dabei rauskommt ja 
nicht sonderlich weh...
Des weiteren machts auch kein Sinn alle Defines in ne Header auszulagern 
;)

Danke schonmal für die Kommentare

Autor: Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich code nur ASM, deshalb sorry wenn die Fragen doof sind, aber woher 
weisst du wieviele Takte die while-Abfrage und das "takte--;" brauchen? 
Das kann man doch bei C nie eindeutig vorhersagen wenn ich recht 
informiert bin. Und damit waere das ganze eben nicht Taktgenau.

Autor: Enrico. J. (ejoerns)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich gehe davon aus, dass zumindest für den Controller in der selben 
Optimierungsstufe der Code immer gleich rauskommt.
Hab mir das ganze im erzeugten Assembler angeschaut. Die Befehle die da 
verwendet werden sind soweit ich das überblicke auf den meisten AVR 
vorhanden und somit denke ich, dass er das auch immer gleich erzeugen 
sollte..

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@  Enrico J. (ejoerns)

>@Falk Brunner: Was genau ist daneben gegangen?

Vieles. Wenn man es genau machen will, muss man im WinAVR reine ASM 
Macros nehmen.

>Die Funktionen aus delay.h haben doch schon ein sehr eingeschränkten
>Zeitbereich!

???
6,5s sollten für eine blockierende Warteschleife mehr als reichen. Mal 
meinen Link gelesen?

MFG
Falk

Autor: Enrico. J. (ejoerns)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ Falk Brunner:

6.5 sec will ich garnicht haben, mir gehts um die genaue Auflösung 
(us-bereich). Und zwar für ein paar mehr µs als nur 50... Die ist bei 
den delay.h definitiv nicht gegeben!

Und wie steht es mit meiner annahme zur codeoptimierung? Überzeugen kann 
mich da bisher noch keine aussage...

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@  Enrico J. (ejoerns)

>6.5 sec will ich garnicht haben, mir gehts um die genaue Auflösung
>(us-bereich). Und zwar für ein paar mehr µs als nur 50... Die ist bei
>den delay.h definitiv nicht gegeben!

Aber sicher, schau dir mal die Schleifen an, die hinter den Makros 
stecken. delay_loop_2 etc. Steht alles in der Doku der libc.

MFG
Falk

Autor: Christian H. (netzwanze) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Enrico J. schrieb:
> Und wie steht es mit meiner annahme zur codeoptimierung? Überzeugen kann
> mich da bisher noch keine aussage...

Es gibt auch nur einen einzigen C-Compiler in einer Version. Daher 
machen auch alle immer genau das gleiche. Genauso gibt es nur eine 
einzige Optimierungsoption (naja, gibt es nicht, wenn sie die einzige 
ist).

Wer sagt Dir, dass mein Compiler nicht jedesmal CALC_CLOCKS/LOOP_CLOCKS 
neu ausrechnet?

Überzeugt?

Ach ja, ich verwende gerne 16MHz oder 20MHz Takt. Muss mir wohl doch 
eine eigene Version schreiben.

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Enrico J. schrieb:
> Moin, was haltet ihr von dieser Konstruktion einer Warte-Funktion?
> Habe versucht mit c eine möglichst genaue und gleichzeitig für längere
> Zeitintervalle brauchbare Zeitfunktion zu entwickeln.

Für Genauigkeit sind ja die Timer da.

Da keines meiner Programme ohne Interrupts auskommt, geb ich auf die 
Genauigkeit von Delays keinen Pfifferling.

Ich benutze sie zur Einhaltung von Minimalzeiten, z.B. bei LCD-Ausgaben.
Daß die Zeiten durch Interrupts größer werden, kann man nicht verhindern 
und darf daher nicht stören.


Peter

Autor: gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
delays nutz ich nur mein sachen wo sinnlos zeit vertrödelt werden kann
also LCD ausgane im neü und ma ne sek warten

ansonst ... garkeit delay
das ganze eben so bauen das man sowas ganrnicht erst brauch
LCDs laufen dank busyabfrage auch ganz ohne delays

die _delay_ms() sollten opimiert genug sein ..

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
gast schrieb:
> LCDs laufen dank busyabfrage auch ganz ohne delays

Das ist Quatsch.
Du wartest dann auch, bloß die Zeitdauer ist etwas kürzer.
Ich denke nicht, daß die Zeitangaben im Datenblatt wesentlich über den 
Busy-Zeiten liegen.
D.h. die CPU-Last durch das LCD sinkt vielleicht von 1% auf 0,5%.
Da spare ich mir lieber den extra Pin für das Busy-Waiting.


Peter

Autor: Enrico. J. (ejoerns)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
So, jetzt bin ich auch mal wieder on board^^

Aaalso...

@Falk Brunner
>Aber sicher, schau dir mal die Schleifen an, die hinter den Makros
>stecken. delay_loop_2 etc. Steht alles in der Doku der libc.

War aus unerfindlichen Gründen davon ausgegangen, dass die Funktionen 
Integer übernehmen, was ja bedeuten würde, dass bei ner etwas längeren 
Wartezeit nur noch ne ms-auflösung bereitgestellt würde... ;)
Dafür sollte aber die für die Vorberechnung die Genauigkeit schon etwas 
drunter leiden (zumindest bei kurzen Wartezeiten die Relaitve), oder?

Aber die delay.h ist ja schon iwie fast was ich gemacht hab, mit dem 
Unterschied, dass bei meiner Version die direkte Anzahl Takte angegeben 
werden kann.

@Christian H.
>Es gibt auch nur einen einzigen C-Compiler in einer Version. Daher
>machen auch alle immer genau das gleiche. Genauso gibt es nur eine
>einzige Optimierungsoption (naja, gibt es nicht, wenn sie die einzige
>ist).

Exzessiver Gebrauch von Ironie ist selten förderlich, aber 
nichtsdestotrotz hab ich ja beschrieben, dass das ganze nur unter 
bestimmten Einschränkungen läuft (avr-gcc, -s). Und vorrangig soll sie 
erstmal für meine Zwecke funktionieren ;).

>Wer sagt Dir, dass mein Compiler nicht jedesmal CALC_CLOCKS/LOOP_CLOCKS
>neu ausrechnet?

Alles andere wäre doch seehr stupide...

@Peter Dannegger:
>Für Genauigkeit sind ja die Timer da.

Mal schaun, vllt. muss ich doch noch einen Timer opfern, den ich eig. 
nicht habe.. mal sehn ;)

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@  Enrico J. (ejoerns)

>Dafür sollte aber die für die Vorberechnung die Genauigkeit schon etwas
>drunter leiden (zumindest bei kurzen Wartezeiten die Relaitve), oder?

???
Keinesfalls.

>Unterschied, dass bei meiner Version die direkte Anzahl Takte angegeben
>werden kann.

Kann man auch in den delay Funktionen. Einfach _delay_loop_2 nehmen.

MFG
Falk

Autor: Enrico. J. (ejoerns)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
aus delay.h:

>Delay loop using a 16-bit counter __count, so up to 65536 iterations are
>possible. (The value 65536 would have to be passed as 0.) The loop
>executes four CPU cycles per iteration, not including the overhead the
>compiler requires to setup the counter register pair.

oder was verstehe ich da nicht?..

Autor: Johann L. (gjlayde) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Falls die Makros der avr-libc zu ungenau sind:

Es gibt auch
  Beitrag "Delay: Exakt n Ticks erzeugen (avr-gcc)"

Damit lassen sich Ticks im Bereich von 0 bis 2^18 exakt erzeugen, also 
ohne einen Tick mehr oder weniger als angefordert! Die Anzahl der Ticks 
muss dazu allerdings zur Compilezeit (bzw. Assemble-Zeit) bekannt sein.

Johann

Autor: Enrico. J. (ejoerns)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das schaut doch mal sehr brauchbar aus :) Danke!

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.