mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Problem mit selbstgemachter header datei


Autor: Oliver D. (highspeed-oliver)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
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?

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Beispiel anhand der Funktion timer_init:
Es gibt drei Dateien: "main.c", "functions.h" und "functions.c".

In "functions.c" steht
void timer_init(void)  
{
  // Timer 0 initialisieren
  TMOD = 0x01;          // 0000 0001B    Timer 0: Mode 1 (16-Bit Z�hler)
  TH0  =  0xAF;      //Ultra short couting time
  TL0  =  0xFF;    

  // Interruptsystem
  ET0  = 1;             // Timer 0, Interruptfreigabe
  EA   = 1;             // generelle Interruptfreigabe
}

In "functions.h" steht
extern void timer_init(void);

In main.c:
#include "functions.c"
//[...]
timer_init();
//[...]

main.c und functions.c werden dem Compiler bekanntgegeben (bei einer IDE 
dem Projekt hinzugefügt).

Autor: I_ H. (i_h)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Oliver D. (highspeed-oliver)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ah ok. Danke.


Also ist es zwingend erfoderlich eine weitere .C datei anzulegen, in die 
ich den C Code packe?!?

Autor: Oliver D. (highspeed-oliver)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Alles klar. Habs gemacht. Die fehlaaas sind weg,

dafür aber MISSING MACRO NAME AFTER DEFINE in der .h datei.

Autor: Oliver D. (highspeed-oliver)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
So habe einfach mal functions dafür eingetippt und meine probleme 
BLEIBEN BESTEHEN!

Autor: I_ H. (i_h)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
sorry,

#ifndef _FUNCTIONS_H
#define _FUNCTIONS_H

sollte das werden. Kannst du mal die genaue Fehlermeldung schreiben?

Autor: Oliver D. (highspeed-oliver)
Datum:
Angehängte Dateien:
  • preview image for tz.JPG
    tz.JPG
    274 KB, 140 Downloads

Bewertung
0 lesenswert
nicht lesenswert
HAllo,

ich hab mal nen Screenshot gemacht.

Autor: I_ H. (i_h)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Oliver D. (highspeed-oliver)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Oliver D. (highspeed-oliver)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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);
{
}
}

Autor: Oliver D. (highspeed-oliver)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: I_ H. (i_h)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Oliver D. (highspeed-oliver)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja die haben selbstverständlich keinen rückgabewert.
Habe ja auch return 0; reingegeschrieben.


Das Problem bleibt also bestehen.

Autor: I_ H. (i_h)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Rooney Bob (rooney)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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...

Autor: Oliver D. (highspeed-oliver)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich habe mir den wiki artikel durchgelesen und danach gearbeitet.

In meinem C buch steht übrigens garnichts zu header datein!

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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%)

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.