Hallo Atmega Fans! Ich benutze delay.h und Atmega 644 mit 16 MHz Quarz. Ich weiß, dass delay.h eine begrenzung hat. Deswegen benutze ich die Schleife for (i=1; i<=1000, i++) { _delay_ms(1); } In der delay.h habe ich F_CPU = 16000000UL angegeben. Mit der oberen Schleife, müsste ich eine Verzögerung von 1s erreichen. Das ist aber nicht so, die Zeitverzögerung ist viel viel kleiner! Ich denke, dass sind etwa 100ms oder so... Warum stimmt, die delay Funktion nicht? Hat jemand schon das gleiche Problem gehabt? Danke!
> In der delay.h habe ich F_CPU = 16000000UL angegeben.
Davon abgesehen, daß das da nicht* hingehört, hast Du auch die Fuses des
Controllers entsprechend gesetzt?
*) Nie, niemals verändert man zum Compiler gehörende Headerdateien.
Da der Controller wahrscheinlich nicht mit 160 MHz läuft, kann es nicht an den Fuses liegen. Der gelistete Code kann aber nicht der gleiche sein, der auf dem Controller läuft, da er einen Syntaxfehler enthält. Vielleicht enthält der Originalcode einen anderen Fehler. Deswegen immer Originaldateien posten oder copy-paste machen, aber nicht den Code abtippen oder (noch schlimmer) aus dem Kopf eingeben.
16 mit 6 Nullen sind doch 16 MHz oder nicht ? Zwischenfrage am Rande: Muß man wirklich auch "UL" bei den defines angeben?
Lutz wrote: > 16 mit 6 Nullen sind doch 16 MHz oder nicht ? ich komm auch auf 16mhz > Zwischenfrage am Rande: Muß man wirklich auch "UL" bei den defines > angeben? mein make-file-editor sagt mir: Do NOT tack on a 'UL' at the end, this will be done automatically to create a 32-bit value in your source code. außerdem sollte ein compiler auch selbst wissen, wie er variablen am dümmsten anlegt ^^ und meiner meinung nach am geschicktesten gehts so: #ifndef F_CPU #define F_CPU 16000000 #endif
> Zwischenfrage am Rande: Muß man wirklich auch "UL" bei den defines > angeben? Ja, sonst ist das ein int. Und der kann auf einem 8/16-Bit-System wie dem AVR nicht andeutungsweise so groß werden.
mein make-file-editor sagt mir: Do NOT tack on a 'UL' at the end, this will be done automatically Ja, sonst ist das ein int. Und der kann auf einem 8/16-Bit-System wie dem AVR nicht andeutungsweise so groß werden. Danke. Grundsätzlich sieht C es also nicht automatisch vor und man muß sich selbst drum kümmern, es kann einem aber natürlich preprozessor- oder compilerabhängig auch abgenommen werden. Wieder was wichtiges gelernt.
Rufus t. Firefly wrote: >> Zwischenfrage am Rande: Muß man wirklich auch "UL" bei den defines >> angeben? > Ja, sonst ist das ein int. Nein, weil's da nicht reinpasst, aber es wäre ein (signed) long, denn da passt die Zahl rein.
> Ja, sonst ist das ein int. Nein. > Und der kann auf einem 8/16-Bit-System wie dem AVR nicht > andeutungsweise so groß werden. Eben, und das merkt der Compiler und wählt deshalb automatisch long als Typ, so wie es die C-Norm vorschreibt.
Lutz schrieb: > 16 mit 6 Nullen sind doch 16 MHz oder nicht ? Michael H* schrieb: > ich komm auch auf 16mhz Falls das auf meine Aussage von oben > Da der Controller wahrscheinlich nicht mit 160 MHz läuft, kann es > nicht an den Fuses liegen. bezogen sein sollte: > F_CPU = 16000000UL ist natürlich richtig, wenn tatsächlich ein 16MHz-Quarz verwendet wird. Hsus schreibt aber: > Mit der oberen Schleife, müsste ich eine Verzögerung von 1s > erreichen. Das ist aber nicht so, die Zeitverzögerung ist viel viel > kleiner! Ich denke, dass sind etwa 100ms oder so... Die Zeitverzögerung ist also um den Faktor 10 zu kurz. Bei korrekter Software könnte dies nur durch einen um den Faktor 10 erhöhten CPU-Takt erklärt werden. Da ein CPU-Takt von 16MHz*10 = 160MHz aber praktisch unmöglich ist, ist auf jeden Fall ein Softwareproblem vorhanden, das man erst beseitigen sollte, bevor man Fehler in den Fuses sucht. Der Softwarefehler kann von uns aber schlecht gefunden werden, weil Hsus nicht seinen Originalcode gepostet hat. Nur falls es jemand noch nicht entdeckt haben sollte: Das Komma nach der 1000 sollte ein Semikolon sein.
Hatte das auch mal, musste die optimierung beim compilieren anschalten, mindestens -O1 am besten aber sowieso -Os, dann gings bei mir, sogar vergleichsweise so genau wie mit einem timer...
Es ist natürlich richtig und wichtig, die Optimierung einzuschalten. Allerdings ist das keine Erklärung für das beschriebene Phänomen: Das Einschalten der Optimierung, falls es tatsächlich vergessen wurde, würde die Delay-Schleife nicht langsamer (was gewünscht wird), sondern noch viel schneller machen.
Bei mir im Code stand es so: #ifndef F_CPU /* prevent compiler error by supplying a default */ # warning "F_CPU not defined for <util/delay.h>" # define F_CPU 16000000UL #endif Komisch ist, dass zwischen # und define ein Leerzeichen ist, und define nicht in blau angezeigt ist. Könnte das der Fehler sein? Ich habe das geändert und werde heute Nachmittag es ausprobieren und euch berichten.
Hsus wrote: > Bei mir im Code stand es so: Nicht bei dir, sondern im Headerfile der Bibliothek. Wie Rufus dir schon im Beitrag "Re: Zeitverzögerung mit delay FALSCH" schrieb, sind diese Dateien für dich erstmal tabu (zumindest, solange du noch gar nicht verstehst, was du da tust, weil dir noch nichtmal die Syntax wirklich klar ist). > Komisch ist, dass zwischen # und define ein Leerzeichen ist, Das dient der optischen Verdeutlichung dessen, was zum #if-Block gehört, er ist gewissermaßen eingerückt. Ein Leerzeichen zwischen dem # und der eigentlichen Direktive ist ausdrücklich zulässig. > und define > nicht in blau angezeigt ist. Das ist eine Macke deines Editors und hat mit dem C-Code nichts zu tun.
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.