Hallo. Ich würde gerne wissen, wie viel Speicherplatz eine delay_ms_(__); verbraucht... Ich habe mal ein Programm mit vielen solcher geschrieben, aber beim ATmega16 war irgendwann der Speicher alle... Da ich für mein Programm warscheinlich ein paar (mehr) Verzögerungen brauche, habe ich Befürchtungen, dass nicht alle delays reinpassen. Gibts sonst noch vergleichbare kleinere Zeitverzögerungen??? Wie viel Speicher verbraucht eine delay-funktion?
Probiers einfach aus. Mach ein Programm, compilier es. Im AVR Studio wird dir danach der Speicherverbrauch angezeigt. Dann machst du einen _delay_ms rein und compilierst wieder. Aus dem Vergleich der Zahlen von jetzt und vorher kannst du ermitteln wieviele Bytes durch den _delay_ms verbraucht wurden. Aber ein einzelnder _delay_ms wird nicht viel Speicher verbrauchen. Aus dem Bauch heraus: vielleicht 10 Bytes Flash, +- ein paar Zerquetschte.
naja teste es doch aus :) mach ein neues programm nur mit einem delay und schau um wie viel es größer ist als ein leeres programm. du kannst das delay ja auch in eine funktion packen, die du immer wieder aufrufst, oder du realisierst es mit nem timer. das dürfte dann fast gar keinen platz verbrauchen
Oftmals ist/war(?) auch der Fehler eine Variable für die Delay-Funktion zu benutzen. Das darf/durfte(?) man nicht...das führte auch immer dazu dass der Code unheimlich groß wurde. Grüße
Wenn ich mal kurz ein Minimalprogramm mit einer _delay_ms(100) reinmache, dann sind es 214 Bytes. Mach ich eine _delay_ms(i) (also über ne Variable) dann sind es 3876 Bytes. Grüße
Klaus der 3. schrieb: > Mach ich eine _delay_ms(i) (also über ne Variable) dann sind es 3876 > Bytes. Das ist jetzt totaler Müll. Die _delay_ms kann nicht mit einer Variablen aufgerufen werden. Geht mit Variable nur so: void Delay (char nDelay) { (for char nInd = 0; nInd < nDelay; nInd++) _delay_ms(1); } mfg.
Thomas Eckmann schrieb: > Das ist jetzt totaler Müll. Les mal oben nach...nicht ich bin der Fragensteller! Ich habe nur dieses Beispiel gebracht um es auszuschließen dass es so gemacht wird ;-)
Thomas Eckmann schrieb: > (for char nInd = 0; nInd < nDelay; nInd++) _delay_ms(1); Die Klammer der For-Schleife sitzt übrigens falsch.
Klaus der 3. schrieb: > Ich habe nur dieses Beispiel gebracht um es auszuschließen dass es so > gemacht wird ;-) Ach so. Aber Müll ist es trotzdem. Klaus der 3. schrieb: > Die Klammer der For-Schleife sitzt übrigens falsch. Mach' ich immer so, um die Aufmerksamkeit der anderen zu testen. mfg.
Thomas Eckmann schrieb: > Die _delay_ms kann nicht mit einer Variablen aufgerufen werden. Warum nicht? > Geht mit Variable nur so: > void Delay (char nDelay) > { > (for char nInd = 0; nInd < nDelay; nInd++) _delay_ms(1); > } Wie genau ist die Zeit dann noch?
Thomas Eckmann schrieb: > Ach so. > Aber Müll ist es trotzdem. Deshalb hab ich es ja auch als Beispiel gebracht ;-) Ist ein altbekannter Fehler der gemacht wird. Thomas Eckmann schrieb: > Mach' ich immer so, um die Aufmerksamkeit der anderen zu testen. Coole Methode...allerdings sollte man dann auch so "Aufmerksam" sein und 2 nebeneinander liegende Posts lesen! Grüße
Micha schrieb: > Wie genau ist die Zeit dann noch? Man könnte sie vielleicht noch als inline definieren, dann könnte man sich die Zeit für den Funktionseinsprung/Registersicherung usw. sparen.
Micha schrieb: > Warum nicht? Weil das keine Funktion, sondern ein Makro ist. Micha schrieb: > Wie genau ist die Zeit dann noch? Ich weiss jetzt nicht wieviele Takte eine For-Schleife pro "Umdrehung" genau verbraucht. Aber ein Inkrement und ein Compare/Jump sind nur ein paar Takte. mfg.
Thomas Eckmann schrieb: > Die _delay_ms kann nicht mit einer Variablen aufgerufen werden. Da irrst du. Oder welche Delay-Bibliothek benutzt du? Thomas Eckmann schrieb: > Mach' ich immer so, um die Aufmerksamkeit der anderen zu testen. Bist du Lehrer?
Michael A. schrieb: > Da irrst du. Michael A. schrieb: > Bist du Lehrer? Weder das eine noch das andere. Das war auch meine erste For-Schleife. Kann ja mal vorkommen. >Oder welche Delay-Bibliothek benutzt du? util/delay.h mfg.
> \note In order for these functions to work as intended, compiler > optimizations <em>must</em> be enabled, and the delay time > <em>must</em> be an expression that is a known constant at > compile-time. If these requirements are not met, the resulting > delay will be much longer (and basically unpredictable), and > applications that otherwise do not use floating-point calculations > will experience severe code bloat by the floating-point library > routines linked into the application. Und daher keine variablen _delay_* :)
Weil es reinpasst und ich mir die Frage schon länger stelle: Warum hat man nicht die eigentliche Delayfunktion in einer Hilfsfunktion mit for-Schleife gekapselt um die Verwendung von Variablen zu ermöglichen? Also statt der aktuellen Funktion (bzw. dem Makro, kompliziertes Zeug) sowas
1 | #define _internal_delay_ms (...irgendwas...) //don't use this directly. delay must be a constant
|
2 | |
3 | void delay_ms (int delay) //use this in your program |
4 | {
|
5 | for(;int;int--) |
6 | _internal_delay_ms(1); |
7 | }
|
Eventuell noch attribute always_inline um den Overhead vom Aufruf zu vermeiden.
Grmpf. Es ist schon spät. -for(;int;int--) +for(;delay;delay--) Gute Nacht.
Daher gibt's nur eins: Vergesst das leidige delay. Ihr könnte in dem Programm zu der Zeit sowieso nichts anderes machen, lange Delays sind also sowieso ein Problem. Der vernünftige Weg ist es, an bestimmten Stellen (eigentlich an einer, in der Hauptscheife des Programms (alternativ: In einer Interrupt-Routine die von eben so einem Timer regelmässig aufgerufen wird)) den Timer abzufragen, und zu prüfen, ob es "schon Zeit ist". Dadurch kann man Programmieren ohne Instruktionen zählen zu müssen, es gibt eine Hardwarezeitbasis nach der man sich richten kann, und es entsteht ein reaktives Programm, weil es eben nicht an einer Stelle hängt, sondern "wenn noch nicht Zeit ist" sich um alles andere kümmern kann. Der Vorteil ist, daß man sich nicht um Unzerbrechungen im Codedurchlauf Gedanken machen muß (wenn man nicht anderswo Interrupts verwendet).
Thomas Eckmann schrieb: > Die _delay_ms kann nicht mit einer Variablen aufgerufen werden. Versuchs mal. Und du wirst merken, dass es nämlich doch geht. Allerdings zu dem Preis, dass die Codegröße ins Unermessliche anwächst. Gruß Skriptkiddy
Skript Kiddy schrieb: > Thomas Eckmann schrieb: >> Die _delay_ms kann nicht mit einer Variablen aufgerufen werden. > Versuchs mal. Und du wirst merken, dass es nämlich doch geht. Allerdings > zu dem Preis, dass die Codegröße ins Unermessliche anwächst. Nun ja. Das wär noch gar nicht mal so schlimm. Das eigentliche Problem ist allerdings: Die Zeiten stimmen hinten und vorne nicht. Und dieses Problem ist schwerwiegend: Denn das 'Setup' welches berechnet, wieviele Durchgänge durch die Verzögerungsschleife notwendig ist, braucht selber Zeit die leider nicht konstant ist. D.h. man hat eine relativ hohe Untergrenze, unter die man prinzipiell bei der Verzögerung nicht kommen kann und der Jitter in der tatsächlichen Wartezeit ist hoch. _delay_ms bzw _delay_us funktionieren nun mal nur dann zufriedenstellend, wenn der Compiler schon während des Übersetzens ausrechnen kann, wieviele Wiederholungen der zentralen Warteschleife notwenig sind und dieses Ergebnis dann auch direkt in Code umsetzt.
a no nym schrieb: > Weil es reinpasst und ich mir die Frage schon länger stelle: Warum hat > man nicht die eigentliche Delayfunktion in einer Hilfsfunktion mit > for-Schleife gekapselt um die Verwendung von Variablen zu ermöglichen? Weil dein präsentierter Code impliziert, dass du niemals bei _delay_ms eine feinere Auflösung als 1 Millisekunde brauchst. Den Zeitbedarf, den das Schleifenkonstrukt selber verbraucht hätte man noch berücksichtigen können. Allerdings impliziert diese nicht-0-Zeit auch, dass es eine Untergrenze gibt, unter die du dann zb mit _delay_ms nicht mehr kommen kannst, während _delay_ms(0.9) absolut legal ist und auch sinnvollen Code produziert.
Die Genauigkeit von _delay_ms() kann man aber sowieso nicht unbedingt ernst nehmen, weil sie mehr oder weniger geschickt eine bestimmte Anzahl an Takten verbrät. Das kann einer gewünschten Zeit entsprechen, muß aber nicht. Und zwar aus dem Grund, daß die Funktion nicht merkt, wenn sie unterbrochen wird. Sie ist so kalibriert, daß es ohne Interrupts passt. Hat man aber Interrupts, die (beispielsweise und meist hoffentlich übertrieben) 50% Last erzeugen, dauert ein _delay_ms(1) auch mal 2 Millisekunden. Bei 90% Last in den ISR dann entsprechend 10 Millisekunden...
MaWin schrieb: > Der vernünftige Weg ist es, an bestimmten Stellen (eigentlich an einer, > in der Hauptscheife des Programms (alternativ: In einer > Interrupt-Routine die von eben so einem Timer regelmässig aufgerufen > wird)) den Timer abzufragen, und zu prüfen, ob es "schon Zeit ist". Jain. Wenn man bzw. der µP sowieso nichts anderes zu tun hat (das soll bei einfachen Programmen vorkommen) kann man auch delay verwenden. Ich hatte mal einen Prof der auch krampfhaft (oder krankhaft?) auf die Verwendung von Timern bestand, macht einfache Programme nur unnötig kompliziert und ist sinnloser Aufwand. Bei komplexeren Sachen ist ein Timer natürlich notwendig. Karl Heinz Buchegger schrieb: > a no nym schrieb: >> Weil es reinpasst und ich mir die Frage schon länger stelle: Warum hat >> man nicht die eigentliche Delayfunktion in einer Hilfsfunktion mit >> for-Schleife gekapselt um die Verwendung von Variablen zu ermöglichen? > > Weil dein präsentierter Code impliziert, dass du niemals bei _delay_ms > eine feinere Auflösung als 1 Millisekunde brauchst. > > Den Zeitbedarf, den das Schleifenkonstrukt selber verbraucht hätte man > noch berücksichtigen können. Allerdings impliziert diese nicht-0-Zeit > auch, dass es eine Untergrenze gibt, unter die du dann zb mit _delay_ms > nicht mehr kommen kannst, während _delay_ms(0.9) absolut legal ist und > auch sinnvollen Code produziert. Gut, ich hatte jetzt vergessen bzw. war mir nicht im klaren dass _delay_ms mit float zurechtkommt. Für feinere Auflösungen gibt es doch aber _delay_µs oder? Demnach könnte man für einfache Zwecke die (vielleicht nicht ganz genaue) Funktion delay verwenden welche auch Variablen akzeptiert und für genauere Auflösung/Genauigkeit wie bisher auf die Makros zurückgreifen welche nur mit Konstanten funktionieren. Eigentlich ist die Diskussion ja überflüssig (eine for-Schleife kann man sich bei Bedarf selber einbauen), aber wenn ich sehe wie oft diese Frage hier kommt... Klaus Wachtler schrieb: > (Interruptproblem bei delay) Das ist wohl wahr.
a no nym schrieb: > Wenn man bzw. der µP sowieso nichts anderes zu tun hat (das soll > bei einfachen Programmen vorkommen) kann man auch delay verwenden. Sofern eben die Genauigkeit keine so große Rolle spielt. > Ich hatte mal einen Prof der auch krampfhaft (oder krankhaft?) auf die > Verwendung von Timern bestand, macht einfache Programme nur unnötig > kompliziert und ist sinnloser Aufwand. Bei komplexeren Sachen ist ein > Timer natürlich notwendig. Naja, eine Timer-ISR, die ein Flag setzt, ist ja nun auch nicht gerade schwarze Magie.
Dominik Honnef schrieb: > Und daher keine variablen _delay_* :) Dann lies mal genauer. Bei variablem Delay wird die Floatingpoint Bibliothek eingebunden und die Vorlaufzeit durch die Berechnung der Float Variablen, d.h. bevor die eigentliche Delay-Schleife läuft, wird nicht kompensiert. Das führt zu einem Delay entsprechend der Rechenzeit. Man kann sogar die Rechenzeit bestimmen und beim Aufruf die im Parameter angegeben Delayzeit entsprechend korrigieren ;-) Pauschalaussagen wie "geht nicht" sind einfach Unfug.
Michael A. schrieb: > Man kann sogar die Rechenzeit bestimmen und beim Aufruf die im Parameter > angegeben Delayzeit entsprechend korrigieren ;-) Da die aber stark vom übergebenen Wert abhängt, wird es schwierig, das zu bestimmen. Man könnte aber natürlich mit einem Timer...
Rolf Magnus schrieb: > a no nym schrieb: >> Wenn man bzw. der µP sowieso nichts anderes zu tun hat (das soll >> bei einfachen Programmen vorkommen) kann man auch delay verwenden. > > Sofern eben die Genauigkeit keine so große Rolle spielt. Wieso? Man kann delays durchaus auf einen Takt genau berechnen bzw. programmieren (Interruptproblematik mal außer acht gelassen, simples Programm ohne Interrupts z.B.), ob die C-Bibliotheken das können ist dann eine andere Frage. > >> Ich hatte mal einen Prof der auch krampfhaft (oder krankhaft?) auf die >> Verwendung von Timern bestand, macht einfache Programme nur unnötig >> kompliziert und ist sinnloser Aufwand. Bei komplexeren Sachen ist ein >> Timer natürlich notwendig. > > Naja, eine Timer-ISR, die ein Flag setzt, ist ja nun auch nicht gerade > schwarze Magie. Nun, für Programmier- und "µC-Anfänger" wie man sie z.B. an der Uni findet ist anfänglich alles was mit/in/ um einen µC passiert schwarze Magie, da sind Timer für den Anfang nur unnötig kompliziert.
a no nym schrieb: > Rolf Magnus schrieb: >> a no nym schrieb: >>> Wenn man bzw. der µP sowieso nichts anderes zu tun hat (das soll >>> bei einfachen Programmen vorkommen) kann man auch delay verwenden. >> >> Sofern eben die Genauigkeit keine so große Rolle spielt. > Wieso? Man kann delays durchaus auf einen Takt genau berechnen bzw. > programmieren (Interruptproblematik mal außer acht gelassen, simples > Programm ohne Interrupts z.B.), ob die C-Bibliotheken das können ist > dann eine andere Frage. Ich dachte da mehr an periodische Vorgänge. Da zum Delay immer auch noch die Zeit für den eigentlichen Algorithmus dazugerechnet werden muß, paßt es da nie. Denk z.B. mal an eine Uhr. >>> Ich hatte mal einen Prof der auch krampfhaft (oder krankhaft?) auf die >>> Verwendung von Timern bestand, macht einfache Programme nur unnötig >>> kompliziert und ist sinnloser Aufwand. Bei komplexeren Sachen ist ein >>> Timer natürlich notwendig. >> >> Naja, eine Timer-ISR, die ein Flag setzt, ist ja nun auch nicht gerade >> schwarze Magie. > Nun, für Programmier- und "µC-Anfänger" wie man sie z.B. an der Uni > findet ist anfänglich alles was mit/in/ um einen µC passiert schwarze > Magie, da sind Timer für den Anfang nur unnötig kompliziert. Klar, für den blutigen Anfänger. Aber wenn der mal ein paar Ports getoggelt und den ADC eingelesent hat, dann ist es bald auch Zeit, sich mal mit Interrupts zu beschäftigen.
a no nym schrieb: > Nun, für Programmier- und "µC-Anfänger" wie man sie z.B. an der Uni > findet ist anfänglich alles was mit/in/ um einen µC passiert schwarze > Magie, da sind Timer für den Anfang nur unnötig kompliziert. Lies mal die Quellen und das Kleingedruckte von _delay_*. Ist das Einfach? Und seit wann ist "an der Uni" sein eine Ausrede vor komplizierten Dingen???
Rolf Magnus schrieb: > Ich dachte da mehr an periodische Vorgänge. Da zum Delay immer auch noch > die Zeit für den eigentlichen Algorithmus dazugerechnet werden muß, paßt > es da nie. Denk z.B. mal an eine Uhr. Ach ok, so war das gemeint. Da hast du wohl recht. Wobei wohl kaum jemand eine Uhr mit delays (und ohne Timer) basteln würde... > Klar, für den blutigen Anfänger. Aber wenn der mal ein paar Ports > getoggelt und den ADC eingelesent hat, dann ist es bald auch Zeit, sich > mal mit Interrupts zu beschäftigen. Stimmt. Trotzdem, für irgendwelches "Kleinzeug". z.B. einen tiny der eine Fernbedienung simuliert bei der immer die gleichen Tasten gedrückt werden (anschalten, Quellenauswahl, ...) kann man imho beruhigt delays nehmen. Was natürlich kein Vorwand ist sich nicht mit Timern zu befassen!
Johann L. schrieb: > a no nym schrieb: >> Nun, für Programmier- und "µC-Anfänger" wie man sie z.B. an der Uni >> findet ist anfänglich alles was mit/in/ um einen µC passiert schwarze >> Magie, da sind Timer für den Anfang nur unnötig kompliziert. > > Lies mal die Quellen und das Kleingedruckte von _delay_*. > Ist das Einfach? Es sollte es imho sein... ;-) > Und seit wann ist "an der Uni" sein eine Ausrede vor komplizierten > Dingen??? Natürlich muss man sich auch mit Timern befassen, aber vielleicht nicht sofort. Für das erste "Hallo Welt" = blinkende LED tut es auch ein delay, ggf. mit Hinweis(en) vom Prof was man da beachten muss, denn da hat man schon genug mit DDR und PORT und Bit setzen usw. zu tun. Später kommen natürlich Timer usw.
(Ich kann übrigens mit Timern umgehen, nicht das einer so rum denkt. Ein Datenblatt muss aber sein, auswendig kenne ich die Register vom AVR nicht.)
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.