Forum: Mikrocontroller und Digitale Elektronik AVR Frequenz definieren


von Lokus P. (derschatten)


Lesenswert?

Mal eine Verständnisfrage:

Ich verwende das AVR-Studio um meinen AVR zu programmieren.
In der Vordefinierten Delay-Funktion ist ein F_CPU von 1000000 Hz (1MHz) 
eingetragen.
Wenn ich jetzt meinen AVR allerdings mit 8MHz laufen lasse und dies als 
F_CPU in den Einstellungen eintrage, stimmt ja das Timing nicht mehr von 
dem Code.

Nimmt man dann einfach für F_CPU einen anderen passenden Wert oder passt 
man seinen Code für 8MHz an. Wie geht man da üblicherweise vor?

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Üblicherweise schreibt man Funktionen/Makros so, daß sie ihre 
Abhängigkeit vom Takt in F_CPU parametrisieren. Dann genügt es, dieses 
Makro adäquat zu setzen; etwa mittels -D_FCPU=... auf der 
Kommandozeile/im Makefile.

Beispiel für solchermassen parametriesierte Funktionen sind die 
_delay_us  Funktionen aus der avr-libc.

von ulrich (Gast)


Lesenswert?

Normal passt man den Wert von F_CPU, dafür ist das ja ein Parameter und 
kein fester Wert.

Dass kann man entweder irgendwo am Anfang des Programms, über das 
Makefile, oder bei AVRstudio mit GCC auch über die Menüs machen (wird 
dann beim Aufruf von GCC eingesetzt).

von Thomas E. (thomase)


Lesenswert?

Manfred W. schrieb:
> Wie geht man da üblicherweise vor?

#define F_CPU 8000000UL

VOR(!)

#include <util/delay.h>

mfg.

von Lokus P. (derschatten)


Lesenswert?

Also wenn ich das richtig verstanden habe ist F_CPU nur eine 
stinknormale Variable die eigentlich nichts mit der Taktfrequenz des AVR 
zu tun hat. Ist das so?

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Manfred W. schrieb:
> Also wenn ich das richtig verstanden habe ist F_CPU nur eine
> stinknormale Variable die eigentlich nichts mit der Taktfrequenz des AVR
> zu tun hat. Ist das so?

Es ist keine Variable es ist Text (ein Makro).

Sie informiert den Code über die tatsächliche Taktfrequenz.

von Lokus P. (derschatten)


Lesenswert?

Johann L. schrieb:
> Sie informiert den Code über die tatsächliche Taktfrequenz.

Was heißt tatsächlich? Tatsächlich wäre für mich die Frequenz mit der 
der AVR läuft.

von Stephan H. (stephan2807)


Lesenswert?

Manfred W. schrieb:
> Was heißt tatsächlich? Tatsächlich wäre für mich die Frequenz mit der
> der AVR läuft.

Ganz genau. Nahezu jede ausgearbeitete Bibliothek nutzt den Wert (oder 
zumindest vergleichbare Einstellungen) um das Timing an den CPU-Takt 
anzupassen.

Schreibst Du einen falschen Wert rein stimmt das Timing nicht mehr.

Manfred W. schrieb:
> Also wenn ich das richtig verstanden habe ist F_CPU nur eine
> stinknormale Variable die eigentlich nichts mit der Taktfrequenz des AVR
> zu tun hat. Ist das so?

Falsch.

von olibert (Gast)


Lesenswert?

Welche Version ist die avr-lib ? Falls kleiner als 1.6, koennnte das 
dein Problem sein:

http://www.mikrocontroller.net/articles/AVR-GCC
Tutorial#Warteschleifen_.28delay.h.29

Vor kurzem hatte ich ein aehnliches Problem mit der LCD-Ansteuerung, die 
nachdem Erhoehen der Taktfrequenz nicht sauber funktioniert hatte.

von Wolfgang S. (wsm)


Lesenswert?

Nur der Compiler benötigt Taktfrequenz und Laufschleifen für 
Verzögerungen richtig in einen ASS-Code umzusetzen. Auch um Delay's für 
die internen seriellen Schnittstellen zu berechnen oder auch Wartezeiten 
für LCD-Ausgaben u.s.w.
Wird das nicht benötigt, so kann man getrost 100MHz angeben und über die 
Fuses oder Quarz 8MHz (16MHz) einstellen.

W.

von Thomas E. (thomase)


Lesenswert?

Manfred W. schrieb:
> Also wenn ich das richtig verstanden habe ist F_CPU nur eine
> stinknormale Variable die eigentlich nichts mit der Taktfrequenz des AVR
> zu tun hat. Ist das so?

Nein.

Das ist eine symbolische Konstante.

Damit wird dem Compiler die Taktfrequenz mitgeteilt. Woher soll der das 
sonst wissen?

mfg.

von Lokus P. (derschatten)


Lesenswert?

Wenn ich jetzt einen Timer Interrupt von 10ms benötige und ich F_CPU auf 
8000000Hz eingestellt habe, wie berechne ich den dann?

Ich möchte gerne die "Universelle Tastenabfrage" aus dem Tutorial hier 
verwenden. Die geht allerdings von einer Taktfrequenz von 1MHz aus.

Muß ich den Code dann komplett umstricken?

von Karl H. (kbuchegg)


Lesenswert?

Manfred W. schrieb:
> Wenn ich jetzt einen Timer Interrupt von 10ms benötige und ich F_CPU auf
> 8000000Hz eingestellt habe, wie berechne ich den dann?

http://www.mikrocontroller.net/articles/FAQ#Timer

> Ich möchte gerne die "Universelle Tastenabfrage" aus dem Tutorial hier
> verwenden. Die geht allerdings von einer Taktfrequenz von 1MHz aus.
>
> Muß ich den Code dann komplett umstricken?

Nein.
Ob die den Interrupt alle 5 oder alle 10 oder alle 20 ms aufruft, ist 
ziemlich wurscht. Die Zeit sollte sich irgendwo im Bereich 5 bis 50ms 
bewegen. Dann passt das schon. Du kannst das Nachladen auch komplett 
rauswerfen, wenn die ISR Aufruffrequenz sich in diesem Bereich bewegt.

von Thomas E. (thomase)


Lesenswert?

Manfred W. schrieb:
> wie berechne ich den dann?

Du rechnest aus, wie lang ein Takt ist:

Timerprescaler / F_CPU

Dann musst du den Timer so lange zählen lassen, bis die gewünschte Zeit 
erreicht ist.

Manfred W. schrieb:
> Muß ich den Code dann komplett umstricken?
Nein.
Damit wird der Timer eingestellt:
>TCNT0 = (u8)(s16)-(XTAL / 1024 * 10e-3 + 0.5);  // preload for 10ms

XTAL entspricht deinem F_CPU
Das ist oben definiert:
>#define  XTAL    1e6    // 1MHz


mfg.

von Lokus P. (derschatten)


Lesenswert?

Genau dieses Beispiel.

Wie kommt man da eigentlich auf 10ms? Wenn wir mal von 1MHz ausgehen und 
ich mir die Formel XTAL / 1024 * 10e-3 + 0.5 ausrechne kommt bei mir ein 
Wert von 6836,4375 heraus.

Andererseits wenn ich das ganze mit 4MHz rechne bekomme ich einen Wert 
von 27344,25.

Das wäre doch um einiges mehr.
Warum eigentlich überhaupt die + 0,5? Die machen das Kraut doch auch 
nicht mehr Fett.

von Thomas E. (thomase)


Lesenswert?

Manfred W. schrieb:
> Wert von 6836,4375 heraus.
Das ist eine Dezimalzahl. Ins Register wird aber ein Integer 
geschrieben. D.h. die Nachkommastellen werden abgeschnitten.

Manfred W. schrieb:
> von 27344,25.

Bei 4 MHz ist ein Takt 4 mal kürzer als bei 1 MHz. Also muß der Timer 4 
mal weiter zählen. Und 4 * 6836 ist 27344.

Manfred W. schrieb:
> Warum eigentlich überhaupt die + 0,5?
Das dient zum Runden, da die Nachkommastellen abgeschnitten werden.

>Die machen das Kraut doch auch nicht mehr Fett.
Wir sind hier aber auch nicht auf'm Wochenmarkt.

mfg.

von Lokus P. (derschatten)


Lesenswert?

Muß ich denn jetzt an der Formal etwas anpassen wenn ich mit 4MHz 
arbeite?

Denn die Tastenabfrage funktioniert so überhaupt nicht korrekt.

von Thomas E. (thomase)


Lesenswert?

Manfred W. schrieb:
> Muß ich denn jetzt an der Formal etwas anpassen wenn ich mit 4MHz
> arbeite?

Ja.
Aber da kommst du jetzt mal selber drauf. Wenn du dir die letzten Posts 
durchliest, findest du das schon.

1e6 ist übrigends 1 * 10 hoch 6 = 1000000

mfg.

von Lokus P. (derschatten)


Lesenswert?

Dann ist 10e-3 ja eigentlich auch 10 * 10 hoch -3 = 70 oder 97 ?

von guenther_w (Gast)


Lesenswert?

Manfred W. schrieb:

> Dann ist 10e-3 ja eigentlich auch 10 * 10 hoch -3 = 70 oder 97 ?

Du machst Deinem Nick alle Ehre!

von Lokus P. (derschatten)


Lesenswert?

Ich denke ich habs: TCNT0 = (uint8_t)(int16_t)-(F_CPU / 8192 * 10e-3 + 
0.5)
Bei 8MHz

von Achim M. (minifloat)


Lesenswert?

Manfred W. schrieb:
> 10e-3
1
           (-3)     (-2)
2
ist 10 * 10     = 10     = 0.01
Klärt den armen Schatten doch mal auf!
mfg mf

von Thomas E. (thomase)


Lesenswert?

Manfred W. schrieb:
> Ich denke ich habs: TCNT0 = (uint8_t)(int16_t)-(F_CPU / 8192 * 10e-3 +
> 0.5)
> Bei 8MHz

Aus welchem Hut hast du jetzt die 8192 gezaubert?
Du probierst einfach nur rum, anstatt mal drüber nachzudenken.

mfg.

von Michael (Gast)


Lesenswert?

Manfred W. schrieb:
> In der Vordefinierten Delay-Funktion ist ein F_CPU von 1000000 Hz (1MHz)
> eingetragen.

Das ist nur die halbe Wahrheit.

Normalerweise steht da
1
#ifndef F_CPU
2
/* prevent compiler error by supplying a default */
3
# warning "F_CPU not defined for <util/delay.h>"
4
# define F_CPU 1000000UL
5
#endif

Damit ist der dort eingetragene Wert nur ein Default-Wert, der zum 
Tragen kommt, wenn vorher im Code bzw. über die Entwicklungsumgebung 
keine Taktfrequenz als F_CPU festgelegt ist. In delay.h muß folglich 
überhaupt nicht angepaßt werden, sondern nur vorher F_CPU über eine 
Preprozessordirektive festgelegt sein.

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.