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
>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...
@ 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-Tutorial#Warteschleifen_.28delay.h.29 >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
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
@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
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.
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..
@ 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
@ 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...
@ 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
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.
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
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 ..
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
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 ;)
@ 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
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?..
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
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.