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?
Ü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.
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).
Manfred W. schrieb: > Wie geht man da üblicherweise vor? #define F_CPU 8000000UL VOR(!) #include <util/delay.h> mfg.
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?
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.
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.
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.
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.
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.
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.
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?
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.
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.
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.
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.
Muß ich denn jetzt an der Formal etwas anpassen wenn ich mit 4MHz arbeite? Denn die Tastenabfrage funktioniert so überhaupt nicht korrekt.
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.
Manfred W. schrieb: > Dann ist 10e-3 ja eigentlich auch 10 * 10 hoch -3 = 70 oder 97 ? Du machst Deinem Nick alle Ehre!
Ich denke ich habs: TCNT0 = (uint8_t)(int16_t)-(F_CPU / 8192 * 10e-3 + 0.5) Bei 8MHz
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
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.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.