Forum: Mikrocontroller und Digitale Elektronik Headerdatei definieren, kenne mich nicht aus


von Matthias H. (maethes26)


Angehängte Dateien:

Lesenswert?

Hallo zusammen,

ich beschäftige mich als Anfänger gerade damit Code in externen Dateien 
richtig in das Hauptprogramm einzubinden.  AVRStudio 5 Atmega 32

Konkret möchte ich die lcd_tools_2.2.c Datei richtig ins Hauptprogramm 
einbinden.
Bisher habe ich diese Datei includiert und es funktionierte!! Ich habe 
hier im Forum gelesen, das das aber nicht der richtige Weg ist und 
deswegen möchte ich jetzt lernen es richtig zu machen.

Ich habe eine Headerdatei angelegt mit den Definitionen  und den 
Funktionsprototypen aus der LCD_tools Datei.

In der Headerdatei habe ich auch den LCD_Port definiert (#define 
LCD_Port PORTB), dennoch bekomme ich eine Fehlermeldung diesbezüglich 
siehe Bild.

Die externe lcd_tools_datei Datei habe ich folgendermaßen eingebunden. 
siehe Bild


Würdet ihr mir bitte helfen, denn die diversen Dokumentationen habe ich 
noch nicht so richtig verstanden.
http://www.mikrocontroller.net/articles/FAQ#Ich_hab_da_mehrere_.2A.c_und_.2A.h_Dateien._Was_mache_ich_damit.3F

Deswegen habe ich meine Dateien rein gestellt wie weit ich gekommen bin 
und wo ich nicht mehr weiter weiß.

Herzlichsten Dank im voraus,

Matthias.

von Martin (Gast)


Lesenswert?

Woher soll der Preprozessor die Ports kennen, wenn deine Header-Datei 
vor den Portdefinitionen aus io.h steht?

von Philipp (Gast)


Lesenswert?

Das hier kann so auch nicht funktionieren
1
#include "E:\Eigene Dateien\Dropbox\Atmel AVR\AVR Programme\1aVorlagen\lcd_tools_h.h"

eerstmal müssten die Ordnerer Trennzeichen so
1
#include "E:/Eigene Dateien/Dropbox/Atmel AVR/AVR Programme/1aVorlagen/lcd_tools_h.h"
oder so
1
#include "E:\\Eigene Dateien\\Dropbox\\Atmel AVR\\AVR Programme\\1aVorlagen\\lcd_tools_h.h"
aussehen.

Und die Leerzeichen in dem Pfad sind auch nicht gerade vorteilhaft.

von Matthias H. (maethes26)


Lesenswert?

Hallo zusammen,
#
danke für die Hilfe.

Ich probiere es gleich aus und melde mich da, ob es geklappt hat.

Viele Grüße,

Matthias.

von Matthias H. (maethes26)


Angehängte Dateien:

Lesenswert?

Hallo zusammen,

leider klappt es immer noch nicht und ich weiß nicht wieso. Es kann dann 
nicht so schwer sein.

Ich verstehe es so:

als 3. wird die Datei lcd_tools_h.h includiert

und somit auch #define LCD_Port PORTB   festgelegt

dann wird der Code von lcd_tools_2.2.c hinzugefügt

dann dürfte doch keine Fehlermeldung LCD_PORT undeclared first use in 
this function mehr kommen oder was verstehe ich das noch nicht?

Ich versuche mir die grundsätzliche Vorgehensweise zu erarbeiten wie man 
Code aus anderen Dateien ins Hauptprogramm hinzufügt.

Wärt ihr so nett und helft mir weiter?

Herzlichste Grüße,

Matthias.

von Floh (Gast)


Lesenswert?

Das sind Fehler, die in der lcd_tools.c zu finden sind.
Z.B. das DDRB wird außerhalb eines Funktionsblocks gesetzt -> Fehler.

Bereinige erstmal die Datei, dann kanns weitergehen.

von Floh (Gast)


Lesenswert?

PS.:
lcd_tools.h auch in die lcd_tools.c einbinden, sonst ist LCD_PORT nicht 
definiert.

Außerdem solltest du dir angewöhnen, eine Header so aufzubauen:
1
#ifndef LCD_TOOLS_H
2
#define LCD_TOOLS_H
3
//eigentlicher Inhalt
4
5
#endif

So wird beim ersten Mal inkludieren ein Compilerschalter gesetzt (am 
besten den Dateinamen wie oben gezeigt), und bei weiteren Inkludierungen 
wird die Datei nicht nochmal beachtet.
Verhindert also Mehrfachdefinitionen.
:-)

von Philipp (Gast)


Lesenswert?

Wenn du in lcd_tools_2.2.c definitionen aus lcd_tools_h.h und io.h musst 
du die header natürlich auch einbinden.

Wenn du in header abc.h eine definition xyz hast, musst du sie auch in 
jeder quelldatei einbinden, in der du diese definition verwenden willst.

von Matthias H. (maethes26)


Lesenswert?

Hallo zusammen,

vielen Dank für Eure Tipps.

Könntet ihr mir nicht diese beiden Dateien beispielhaft schreiben wie 
sie lauten müßten?
Das ist ja nicht viel Code und ich kann es dann daran verstehen.

Bei mir klappt es noch nicht und ich suche noch rum.

Viele Grüße,

Matthias.

von Matthias H. (maethes26)


Angehängte Dateien:

Lesenswert?

Hallo,

jetzt habe ich es hoffentlich nach Euren Hinweisen gemacht. Dennoch ist 
eine Fehlermeldung übrig und ich weiß nicht wieso.


Auch habe ich diese SAche nicht verstanden:

Außerdem solltest du dir angewöhnen, eine Header so aufzubauen:

#ifndef LCD_TOOLS_H
#define LCD_TOOLS_H
//eigentlicher Inhalt

#endif

So wird beim ersten Mal inkludieren ein Compilerschalter gesetzt (am
besten den Dateinamen wie oben gezeigt), und bei weiteren Inkludierungen
wird die Datei nicht nochmal beachtet.
Verhindert also Mehrfachdefinitionen.

warum soll ich das definieren? ich habe die Headerdatei doch über 
#include eingebunden.
Was bringt das dies zu definieren und in welcher Datei soll das stehen?

Viele Grüße,

Matthias.

von Floh (Gast)


Lesenswert?

Matthias H. schrieb:
> Was bringt das dies zu definieren und in welcher Datei soll das stehen?

Folgendes Szenario:

du hast eine funktion int foo(). Diese ist in einer Datei foo.c 
implementiert.
Dazu schreibst du noch eine Headerdatei (foo.h), die die Signatur der 
Funktion enthält.

Jetzt benötigst du die Funktion foo() in main.c und in anderswo.c
Also musst du die foo.h überall dort einbinden, wo die Deklaration 
bekannt sein muss.
Jetzt gibts aber plötzlich 2 Signaturen zur Funktion foo()
Um das zu vermeiden, wird beim Aufruf der Datei abgefragt, ob sie schon 
bekannt ist (ifndef = if not defined), falls nicht, mach sie bekannt 
(define) und lese sie durch. Ansonsten kommt man direkt zum Ende und tut 
nix (endif).

Für solche Sachen sollte man aber mal ein C-Buch lesen ;-)

von Matthias H. (maethes26)


Lesenswert?

Hallo zusammen,das einbinden von Headerdateien und externen Dateien 
klappt jetzt ganz gut.

So schwer ist es gar nicht, wenn man es erst mal verstanden hat.

Viele Grüße,

Matthias.

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


Lesenswert?

Floh schrieb:
> Jetzt gibts aber plötzlich 2 Signaturen zur Funktion foo()

Nein.  Du kannst die Funktion foo() so häufig deklarieren, wie du
nur möchtest.  Dabei darfst du optional noch das Schlüsselwort
"extern" voranstellen, um zu kennzeichnen, dass dies nur eine
Deklaration ist, die den Compiler über die Funktion informiert.

Wofür man dieses #ifdef (im Englischen typischerweise "idempotence"
genannt) jedoch braucht ist, wenn im Headerfile noch weitere Dinge
definiert oder deklariert werden, bei denen ein mehrfaches Auftreten
innerhalb einer Übersetzungseinheit nicht wünschenswert oder nicht
zulässig ist.  Erstgenannter Fall trifft auf #defines zu, wenn
während eines Übersetzungsgangs sowas auftritt
1
#define FOO 42
2
#define FOO 42

dann ist das zwar zulässig, aber kann je nach Compiler durchaus eine
Warnung produzieren.  Schlimmer wird es jedoch mit
1
enum foo {
2
  A, B, C
3
};
4
...
5
enum foo {
6
  A, B, C
7
};

Hier wird die zweite Definition von enum foo vom Compiler abgelehnt.

Warum kann es nun überhaupt dazu kommen, dass man das zweimal hat?
Ganz einfach: Headerfiles sollte für sich immer "self contained"
sein, d. h. sie ziehen sich alle nötigen `prerequisites' vorab
mit rein.  Man kann nun zwei Headers haben a.h und b.h, die jeweils
aus diesem Grunde c.h mit #includen, weil sie einen Teil der
Definitionen und Deklarationen aus c.h benötigen.  Wenn nun main.c
sowohl a.h als auch b.h selbst benötigt, dann wird auf diese Weise
c.h zweimal verarbeitet.  Mit dem #ifdef kümmert man sich darum,
dass es beim zweiten #include (egal, welches von beiden das zweite
ist) keinerlei Inhalt mehr generiert.

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.