Forum: Compiler & IDEs Zeitverzögerung mit delay FALSCH


von Hsus (Gast)


Lesenswert?

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!

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

> 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.

von yalu (Gast)


Lesenswert?

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.

von Lutz (Gast)


Lesenswert?

16 mit 6 Nullen sind doch 16 MHz oder nicht ?

Zwischenfrage am Rande: Muß man wirklich auch "UL" bei den defines 
angeben?

von Michael H* (Gast)


Lesenswert?

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

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

> 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.

von Lutz (Gast)


Lesenswert?

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.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

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.

von Rolf Magnus (Gast)


Lesenswert?

> 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.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Na gut. Dann behaupte ich fortan munter das Gegenteil.

von yalu (Gast)


Lesenswert?

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.

von Daniel R. (zerrome)


Lesenswert?

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...

von yalu (Gast)


Lesenswert?

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.

von Hsus (Gast)


Lesenswert?

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.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

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
Noch kein Account? Hier anmelden.