Also, im Anhang mal das Programm. Ich würde gerne hingehen und den ganzen krams, bis auf die Hauptfunktion, in eine .h datei auslagern. Sowas habe ich bisher noch nie gemacht und mit einem einfachen billigen printf befehle, ausgelagert in einer Funktion, die wiederrum in einer .h datei steht, klappt das einwandfrei. Mein Sourcecode läuft ebenfalls einwandfrei, allerdings lässt er sich nicht auslagern. Ich habe einfach alles, bis auf Programm hauptteil in eine .h datei gepackt. Natürlich oben schön include "displayinit.h". Dann zeigt mir der Compiler aber in allen funktionsaufrufen beim compilieren das an: ERROR 104: MULTIPLE PUBLIC DEFINITIONS SYMBOL: delay(DISPLAYINIT) Woran liegt es und wo mache ich da den fehler?
Vielleicht wäre es sinnvoll, Deinen Header-Versuch auch mal zu posten. Ich vermute aber stark, dass Du da was falsch verstanden hast: In eine Header-Datei werden keine Funktionen an sich ausgelagert. Die Header-Datei enthält ausschließlich Variablen- und Funktions-(Prototypen) Deklarationen. Die eigentlichen Funktionen kommen in eine .c-Datei, die separat kompiliert wird. Und drauf achten, dass in der Header-Datei "extern"-Deklarationen verwendet werden.
Beispiel anhand der Funktion timer_init: Es gibt drei Dateien: "main.c", "functions.h" und "functions.c". In "functions.c" steht
1 | void timer_init(void) |
2 | {
|
3 | // Timer 0 initialisieren
|
4 | TMOD = 0x01; // 0000 0001B Timer 0: Mode 1 (16-Bit Z�hler) |
5 | TH0 = 0xAF; //Ultra short couting time |
6 | TL0 = 0xFF; |
7 | |
8 | // Interruptsystem
|
9 | ET0 = 1; // Timer 0, Interruptfreigabe |
10 | EA = 1; // generelle Interruptfreigabe |
11 | }
|
In "functions.h" steht
1 | extern void timer_init(void); |
In main.c:
1 | #include "functions.c" |
2 | //[...]
|
3 | timer_init(); |
4 | //[...]
|
main.c und functions.c werden dem Compiler bekanntgegeben (bei einer IDE dem Projekt hinzugefügt).
Das extern weg, das gehört da net hin. Ganz oben in die .h #ifndef _FUNCTIONS_H #define und ganz unden #endif rein, sonst knallts wenn du das mehrfach einbindest.
Ah ok. Danke. Also ist es zwingend erfoderlich eine weitere .C datei anzulegen, in die ich den C Code packe?!?
Alles klar. Habs gemacht. Die fehlaaas sind weg, dafür aber MISSING MACRO NAME AFTER DEFINE in der .h datei.
So habe einfach mal functions dafür eingetippt und meine probleme BLEIBEN BESTEHEN!
sorry, #ifndef _FUNCTIONS_H #define _FUNCTIONS_H sollte das werden. Kannst du mal die genaue Fehlermeldung schreiben?
Bei den letzten beiden Funktionen hast du keinen Rückgabetyp angegeben, sowas kann zu merkwürdigen Fehlermeldungen führen. Und zeig mal die beiden anderen Dateien, so wie das aussieht kommt das nicht (nur) von der functions.h.
Also wenn ich bei den letzten beiden ein void davor setze, erhalte ich nurnoch den fehler Type error in second_byte redeclaration und put_to_lcd redeclaration. Der Fehler tritt dann also bei den beiden Funktionen auf.
Das ist die test.c #include "functions.c" #include <reg51.h> #include "displayinit.h" sfr leds=0x80; //Hier ist die led low activ verschaltet. sbit DB4=0xB0;// Die Bezeichnungen der Ports des Displays sbit DB5=0xB1;//1 zu 1 verkabel wie der Name, also DB5 an D5 sbit DB6=0xB2; sbit DB7=0xB3; sbit RS=0xB4; sbit EN=0xB5; sfr port_B0=0xB0; void main (void) { char display_ausgabe[12]; int i=0,length=12; timer_init(); //Zuerst timer initialisieren! display_init(); //Display init ausführen! clear_display(); strcpy(display_ausgabe, "Hello World!");//SPEICHERRAUBEND und schreibt müll in leere Zeichen bei length 20 do{ put_to_lcd(display_ausgabe[i]); i++; } while (i<length); while(1); { } }
Das ist die functions.h #ifndef _FUNCTIONS_H #define _FUNCTIONS_H void delay(unsigned int delay_multi); void enable_routine(void) ; void turnoff_display(void); void turnon_display(void); void clear_display(void); void timer_init(void); void display_init (void); second_byte(char uebergabewert); put_to_lcd (char uebergabewert); #endif
Aaalso: > Das ist die test.c #include "functions.c" macht man üblicherweise nicht, geht aber. Normalerweise wird das beides getrennt kompiliert (.o) und dann erst zusammengelinkt. Geht aber auch so. > Type error in second_byte redeclaration und put_to_lcd redeclaration. Guck mal in die functions.c welchen Rückgabetyp du den beiden funktionen dort gegeben hast. Der muss mit dem in der functions.h übereinstimmen.
Ja die haben selbstverständlich keinen rückgabewert. Habe ja auch return 0; reingegeschrieben. Das Problem bleibt also bestehen.
Also mal langsam, kein Rückgabewert bedeutet "void" (das ist dann der Rückgabetyp) und dann schreibst du in den Code "return;" ohne irgend'nen Wert. Funktionen ohne Angabe vom Rückgabetyp gibt es nämlich nicht, das läuft dann zwangsläufig auf einen Fehler hinaus. Und "return 0;" könnte alles mögliche sein. Poste doch mal die functions.c, die fehlt. Vielleicht solltest du dich erstmal ein bisschen mit C beschäftigen, das gehört schon zu den grundlegendsten Grundlagen.
displayInit.h != displayinit.h Also probiers mal mit gleicher Schreibweise... Der findet vielleicht nicht mal die Datei. Wenn du keinen Rückgabewert hast, muss die Funktion als void deklariert werden, jeder anständige Compiler würde da meckern.
I_ H. wrote: > Das extern weg, das gehört da net hin. Stimmt natürlich, bei Funktionsprototypen ist es überflüssig (schadet aber auch nicht)... Hab grad gesehen, dass der gute Karl Heinz einen Wiki-Artikel zu dem Thema verfasst hat: http://www.mikrocontroller.net/articles/Funktionen_auslagern_%28C%29
Ich habe mir den wiki artikel durchgelesen und danach gearbeitet. In meinem C buch steht übrigens garnichts zu header datein!
I_ H. wrote: > Also mal langsam, kein Rückgabewert bedeutet "void" (das ist dann der > Rückgabetyp) Fast. Kein angegebener Rückgabetyp bedeutet 'int' @Oliver Es ist aber trotzdem besser, man nutzt dieses 'Feature' nicht aus, sondern gewöhnt sich gleich guten Stil an: Wenn eine Funktion einen int retourniert, dann lautet das int foo() { return 0; } Wenn eine Funktion keinen Rückgabewert hat, dann lautet das void foo() { // eventuell ein mglw. vorzeitiger return; } Lass den Compiler sowenig Annahmen wie möglich treffen.
Oliver D. wrote: > Ich habe mir den wiki artikel durchgelesen und danach gearbeitet. Der Artikel ist nicht besonders gut, weil er eigentlic aus einer Anfrage, bei der es um 'extern' gegangen ist stammt. Hat es denn trotzdem funktioniert? > > In meinem C buch steht übrigens garnichts zu header datein! In deinem C-Buch stehen wahrscheinlich noch viele anderen Praxistips zu C nicht drinnen :-) Ich versuch mal eine Wette: Ich wette, dass in deinem Buch eine Fahrenheit / Celsius umrechnung drinnen ist und in dieser Umrechnung der Datentyp float vorkommt, während double da drinn überhaupt nicht vorkommt. Generell kann man sagen, dass im Buch als Standard-Gleitkommatyp meistens float verwendet wird. (Die Chancen für ein gewinnen der Wette stehen bei ca. 60%)
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.