Forum: Mikrocontroller und Digitale Elektronik Probleme mit F_CPU not defined, obwohl es eigentlich definiert ist?!


von Student (Gast)


Lesenswert?

Hi!

Anfang meines Codes sieht so aus:
1
#define F_CPU 16000000UL
2
#define UART_BAUD_RATE 57600
3
4
#include "uart/uart.h"
5
#include <stdlib.h>
6
#include <avr/io.h>
7
#include <avr/interrupt.h>
8
#include <avr/pgmspace.h>
9
#include <delay.h>
10
#include <math.h>

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!

von Jim M. (turboj)


Lesenswert?

Poste den kompletten Code mal als Anhang, und auch alle 
Fehlermeldungen.

Mit dem Schnipsel oben ist IMO alles OK.

von Pete K. (pete77)


Lesenswert?

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.

von Tom K. (ez81)


Lesenswert?

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.

von Xirtam (Gast)


Lesenswert?

Tom K. schrieb:
> Den Bug findet man nie.

kapier ich jetzt irgendwie nicht. Warum sollte das ein Bug sein?

von Student (Gast)


Lesenswert?

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

von Bitflüsterer (Gast)


Lesenswert?

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.

von Student (Gast)


Lesenswert?

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_t baud = 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"?

von Bitflüsterer (Gast)


Lesenswert?

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

von Thomas E. (thomase)


Lesenswert?

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:
1
#ifndef F_CPU
2
  #error F_CPU not defined.
3
#endif


mfg.

: Bearbeitet durch User
von Mike (Gast)


Lesenswert?

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.

von Chefkoch (Gast)


Lesenswert?

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.

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.