Inkludiert ist unter anderem die <util/delay.h>, sowie einige andere
Bibliotheken.
Dann bekomme ich folgende Fehlermeldung:
"F_CPU not defined for <util/delay.h>". Kenne ich eigentlich, wenn ich
eben vergessen habe, die F_CPU zu definieren.
Aber wieso kommt das jetzt bei mir, obwohl ich es ja eigentlich ganz
oben definiert habe?
Grüße und danke schonmal für die Hilfe!
Das F_CPU kommt ins Makefile, auf keinen Fall in das *.c oder *.h.
Der Compiler (Präprozessor) versucht anhand des Makefiles delay.c zu
übersetzen und da ist nun mal F_CPU nicht definiert.
Das F_CPU gehört in die CFLAGS des Compilers (Makefile).
Bei vielen Programmierumgebungen kann man das in den Projektsettings
einstellen.
Pete K. schrieb:> Das F_CPU kommt ins Makefile, auf keinen Fall in das *.c oder *.h.
Dies. Besonders schön wird es, wenn ein Spezialist F_CPU im Code
#definet und in unwichtige_nebenfunktion_wo_man_nie_reinsieht.c sowas
schreibt
1
#ifndef F_CPU
2
#define F_CPU 1000000UL
3
#endif
, um eine Fehlermeldung wegen der doppelter Definition von F_CPU zu
unterdrücken. Den Bug findet man nie.
Servus und danke für die Antworten!
Pete K. schrieb:> Das F_CPU kommt ins Makefile, auf keinen Fall in das *.c oder *.h.
Hmm, also ich habe bis jetzt immer in der main.c das #define ganz oben
hingeschrieben.
Wo finde ich denn das Makefile bei AtmelStudio? Musste mich bis jetzt
noch nie mit dem Makefile herumschlagen, gehört habe ich davon aber
schonmal :D
Es gibt (fast) immer mehrere Wege, und welche genau hängt u.a. auch
davon ab, welche Programmierumgebung Du benutzt. Das Du "AVRStudio"
verwendest, wäre eine Information für Dein erstes Posting gewesen. Aber
gut.
Nehmen wir mal an, Du verwendest AVRStudio 4, dann gibt es unter
Project->CustomOptions in dem Eingabefeld, links neben dem Button "Add"
die Möglichkeit Deine Definition "-DF_CPU 16000000UL" einzugeben. Damit
gelangt die Definition auch in Dein makefile.
Bitflüsterer schrieb:> wäre eine Information für Dein erstes Posting gewesen. Aber> gut.
Sorry!
Hmm, also bis jetzt habe ich das immer im Code direkt definiert und hat
wohl auch ganz gut funktioniert.
Siehe auch AVR GCC Tutorial hier:
1
#include<avr/io.h>
2
3
#ifndef F_CPU
4
#define F_CPU 3686400
5
#endif
6
#define UART_BAUD_RATE 9600
7
8
...
9
uint16_tbaud=F_CPU/(UART_BAUD_RATE*16L)-1;
10
11
UBRRH=(uint8_t)(baud>>8);
12
UBRRL=(uint8_t)baud;
13
...
Quelle: AVR GCC Tutorial
Geht das nicht? Ist das einfach nicht "die feine englische Art"?
>Geht das nicht? Ist das einfach nicht "die feine englische Art"?
Unter "gewissen Umständen" geht das schon. Und es gibt auch einige
Daumenregeln, was man tut und nicht tut.
Das hängt mit der Frage zusammen, wie ein Compilationsvorgang erfolgt,
eine #include-Anweisung behandelt wird und wie das linken erfolgt.
1. Wenn Du nur eine einzige C-Datei hast, in der delay verwendet wird,
reicht eine Definition von F_CPU in der C-Datei hin.
2.a Wenn Du mehrere C-Dateien hast, in denen delay verwendet wird, dann
kannst Du theoretisch in jeder C-Datei, ein Define hinschreiben. Das
ist aber unpraktisch, weil bei einer Änderung jede dieser C-Dateien
geändert werden muss.
2.b Du kannst das in eine H-Datei schreiben, die in allen betroffenen
C-Dateien included wird.
2.c Oder Du kannst das Verfahren mit den "Project-CompilerSettings"
resp. dem makefile verwenden.
Es gibt ohnehin Meinungsverschiedenheiten darüber, aber die meisten
verwenden 2.b oder 2.c. Man hat nur eine Stelle, an der die Definition
steht. 2.b. Erfordert noch eine Abfrage, ob F_CPU schon definiert ist,
falls es (bei grösseren Projekten) sein kann, das die H-Datei mehrfach
included wird.
Student schrieb:> Geht das nicht? Ist das einfach nicht "die feine englische Art"?
Das ist eigentlich völlig in Ordnung, das so zu machen. Solange du nur
ein File hast, das diese Information benötigt. Dem Compiler ist das
vollkommen egal. Aber die Makros, die F_CPU benötigen um die Werte für
Timer, UART, delays etc. zu berechnen, müssen dann in allen möglichen
Files immer wieder neu mit dieser Information versorgt werden. Das kann
man sich ersparen, indem man es einmal zentral ins Makefile schreibt
bzw. in die Configuration Options. Dann erledigt AVR-Studio das für
dich.
Vor allen Dingen ist der Wert dann immer gleich und kann sich auch nicht
verselbständigen wie hier:
1
#ifndef F_CPU
2
#define F_CPU 3686400
3
#endif
Ich finde das eine Scheissidee.
Bei mir steht am Anfang jedes Files:
Student schrieb:> Geht das nicht? Ist das einfach nicht "die feine englische Art"?
Gelesen und verinnerlicht?
Tom K. schrieb:> Besonders schön wird es, wenn ein Spezialist F_CPU im Code> #definet und in unwichtige_nebenfunktion_wo_man_nie_reinsieht.c sowas> schreibt
Mit deinem
Student schrieb:> #ifndef F_CPU> #define F_CPU 3686400
schmeißt dir der Kompiler, falls F_CPU nicht definiet ist und egal
welchen Quarz du in deinem System verwendest, still und heimlich
eine Taktratenberechnung basierend auf 3.6846MHz in den Code. Es wäre
schon ein blöder Zufall, wenn das in deinem System zu sinnvollen
Ergebnissen führt.
Ich würde die Funktion meiner Programme nicht auf Zufall aufbauen.
Ich für meinen Teil (Atmelstudio 6.1) füge das Ganze in den
Projekteigenschaften irgendwo unter Toolchain-Symbols hinzu mit
F_CPU=xxxxx und alles ist gut.