mikrocontroller.net

Forum: Compiler & IDEs mulible definition


Autor: Alex (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hallo,

ich habe ein Problem mit dem Kompelieren meiner dateien, da ich ständig 
eine Fehlermeldung bekomme die ich nicht weg bekomme


main.o: In function `initusart':
C:\Dokumente und Einstellungen\Projektrechner E\Eigene Dateien\Uarttestausbuch\default/../initusart1.c:14: multiple definition of `initusart'
initusart1.o:C:\Dokumente und Einstellungen\Projektrechner E\Eigene Dateien\Uarttestausbuch\default/../initusart1.c:14: first defined here
main.o: In function `putch':
C:\Dokumente und Einstellungen\Projektrechner E\Eigene Dateien\Uarttestausbuch\default/../putch1.c:9: multiple definition of `putch'
putch1.o:C:\Dokumente und Einstellungen\Projektrechner E\Eigene Dateien\Uarttestausbuch\default/../putch1.c:9: first defined here
main.o: In function `getch':
C:\Dokumente und Einstellungen\Projektrechner E\Eigene Dateien\Uarttestausbuch\default/../getch1.c:11: multiple definition of `getch'
getch1.o:C:\Dokumente und Einstellungen\Projektrechner E\Eigene Dateien\Uarttestausbuch\default/../getch1.c:11: first defined here
main.o: In function `getche':
C:\Dokumente und Einstellungen\Projektrechner E\Eigene Dateien\Uarttestausbuch\default/../getche1.c:9: multiple definition of `getche'
getche1.o:C:\Dokumente und Einstellungen\Projektrechner E\Eigene Dateien\Uarttestausbuch\default/../getche1.c:9: first defined here
main.o: In function `kphit':
C:\Dokumente und Einstellungen\Projektrechner E\Eigene Dateien\Uarttestausbuch\default/../kphit1.c:9: multiple definition of `kphit'
kphit1.o:C:\Dokumente und Einstellungen\Projektrechner E\Eigene Dateien\Uarttestausbuch\default/../kphit1.c:9: first defined here
make: *** [Uarttestausbuch.elf] Error 1
Build failed with 1 errors and 0 warnings...

kann mir jemand sagen wass ich da falsch mache

Ich habe die Main und weitere 5 Dateien.
in allen 5 Dateien binde ich mit #include die avr/io.h ein und mache ein 
Fkt. den den gleichen Namen hat wie die Datei nur ohne "1".
In der Main rufe ich auch die avr/io.h auf und binde zusätzlich noch die 
.h datei konsole ein, in der alle .c Dateien bis auf die Main enthalten 
sind.
Dann mache ich in der Main einen 3 Funktionsaufrufe und nehem dazu die 
Name aus den Dateien, also Dateiname ohne "1".

Nun frage ich mich wo denn da eine multible defintion ist????

Vielen Dank an den der mir eine tolle Antwort gibt.

Viele Grüße

Alex

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

Bewertung
0 lesenswert
nicht lesenswert
Alex schrieb:

> Ich habe die Main und weitere 5 Dateien.
> in allen 5 Dateien binde ich mit #include die avr/io.h ein und mache ein
> Fkt. den den gleichen Namen hat wie die Datei nur ohne "1".
> In der Main rufe ich auch die avr/io.h auf und binde zusätzlich noch die
> .h datei konsole ein, in der alle .c Dateien bis auf die Main enthalten
> sind.

*.c Files werden nicht includiert.

Im übrigen ist deine Beschreibung (wie nicht anders zu erwarten) mehr 
als schwammig. Zeige deine Dateien! Dann brauchst du nichts beschreiben 
und wir müssen auch nicht entziffern was das wohl heißen mag, was du 
beschreibst.

Autor: Alex (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hier mein Quellcode

//test_uart.c (MAINFUNKTION)
#include<avr/io.h>
#include "konsole.h"


//#define TAKT 3686400UL
//#define BAUD 9600UL



int main(void)

{

initusart();
putch('>');

while(1)

{

getch();

}
}


//initusart.c Usart initialisieruen

#include <avr/io.h>


void initusart(void)

{

unsigned char x;
//UBRRL = (TAKT /16UL*BAUD)-1;
UBRRL=23;
UCSRB |=(1<< TXEN)|(1<<RXEN);
UCSRC |=(1<< URSEL) |(1<<UCSZ1);
x=UDR;
}


//putch.c Zeichen an Sender

#include<avr/io.h>

void putch (unsigned char x)

{
loop_until_bit_is_set(UCSRA,UDRE);
UDR=x;
}

//getch.c warten auf Zeichen abholen

#include<avr/io.h>



unsigned char getch(void)

{

loop_until_bit_is_set(UCSRA, RXC);

return UDR;
}
//getche.c warte, Zeichen abholen und im Echo senden
#include<avr/io.h>


unsigned char getche(void)
{
unsigned char x;

loop_until_bit_is_set(UCSRA,RXC);

x=UDR;

loop_until_bit_is_set(UCSRA, TXC);

UDR=x;
return x;
}
//kbhit.c Empfänger testen kein Zeichen: Rückgabewert 0

#include<avr/io.h>

unsigned char kphit(void)

{

if(bit_is_set(UCSRA,RXC)) return UDR; else return 0;

}

//konsole.h

#include "initusart.c"
#include "putch.c"
#include "getch.c"
#include "getche.c"
#include "kphit.c"


Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
#include "initusart.c"
#include "putch.c"
#include "getch.c"
#include "getche.c"
#include "kphit.c"

Genau das tut man nicht, wie Karl Heinz ja schon geschrieben hat.

Autor: Rufus Τ. Firefly (rufus) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Was sollen denn die mehrfachen #includes von <avr/io.h>?

Außerdem ist der Code nicht nur grauenerregend formatiert, es fehlen 
auch sämtliche Prototypen.

Ich empfehle ganz dringend die Lektüre eines C-Buches, oder eines der 
vielen, vielen Beiträge hier im Forum von Karl Heinz Buchegger, der 
schon mehrfach mit einer wahrhaften Engelsgeduld erklärt hat, wie 
Funktionen auf Sourcefiles und Headerfiles aufzuteilen sind und warum 
man C-Code auch einrücken sollte.

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

Bewertung
0 lesenswert
nicht lesenswert
Im übrigen ist es Unsinn, für jede Funktion ein eigenes File zu 
schreiben.
Eigene *.c Files werden nach Themenkreis gebildet!

Also alle LCD Funktionen in einem File
Alle UART Funktionen in einem File
Alle Funktionen, die mit Regelung zu tun haben in einem File
Alle Hilfsfunktionen (sofern man sie im weitesten Sinne als 
zusammengehörig betrachten kann) in einem File


Mit deiner Aufteilerei übertreibst du die Sache! Es hat keinen Sinn für 
jede Funktion ein eigenes File zu machen. Dann landest du in einem Wust 
von Files und verlierst erst recht wieder den Überblick.

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

Bewertung
0 lesenswert
nicht lesenswert
Sieh dir deine Funktion getche() an. Du hast eine Funktion getch() und 
du hast eine Funktion putch(). Es ist ein leichtes, aus diesen beiden 
Funktionen die Funktion getche() zusammenzusetzen. Was du aber nicht tun 
solltest: In der Funktion getche() die Funktionalität wieder 
auszuprogrammieren. Trachte danach Funktionen wiederzuverwenden! Du 
möchtest die hardwareabhängigen Dinge nach Möglichkeit nicht über viele 
Funktionen verstreut haben, sondern wenn irgendwie geht, in nur 1 
Funktion beisammen haben.

So könnte zb eine sinnvolle Aufteilung in Funktionalitäten aussehen:

File: test_uart.c
*****************
#include <avr/io.h>
#include "uart.h"

//#define TAKT 3686400UL
//#define BAUD 9600UL

int main(void)
{
  initusart();
  putch('>');

  while(1) {
    getch();
  }
}

File: uart.c
************
#include <avr/io.h>
#include "uart.h"

void initusart( void )
{
  unsigned char x;

  //UBRRL = (TAKT /16UL*BAUD)-1;
  UBRRL = 23;
  UCSRB |= (1<< TXEN) | (1<<RXEN);
  UCSRC |= (1<< URSEL) | (1<<UCSZ1);
  x = UDR;
}

void putch( unsigned char x )
{
  loop_until_bit_is_set( UCSRA, UDRE );
  UDR = x;
}

unsigned char getch( void )
{
  loop_until_bit_is_set( UCSRA, RXC );
  return UDR;
}

unsigned char getche( void )
{
  unsigned char x = getch();
  putch( x );
  return x;
}

unsigned char kbhit( void )
{
  if( bit_is_set( UCSRA, RXC ) )
    return UDR;
  else
    return 0;
}

File: uart.h
************
void initusart( void );
void putch( unsigned char x );
unsigned char getch( void );
unsigned char getche( void );
unsigned char kbhit( void );

In uart.c sind alle Funktionen beisammen, die man benötigt wenn man mit 
der UART arbeiten will. Ein Programm, welches das tun will, includiert 
das File "uart.h". Dadurch bekommt es die Funktionsprotoypen aller 
verfügbaren Funktionen und kann sie benutzen. Der Inhalt von uart.c 
interessiert das Testprogramm nicht weiter. Alles was es wissen muss, 
findet es in uart.h

Ins Projekt (AVR-Studio) bzw. Makefile, werden das Testprogramm bzw 
uart.c als Source File eingetragen. uart.h kommt im Makefile in die 
Anhängigkeiten bzw. im AVR STudio unter die Header Files.
Und dann hast du dein Projekt sauber aufgesetzt und es gibt auch keine 
multiple Definitions mehr.


Alle C Files werden einzeln compiliert und zum EXE zusammengelinkt

An der Konstanten 23 in initusart solltest du noch arbeiten, die gehört 
da in dieser Form nicht hin

Und arbeite an deiner Formatierung. Da hat Rufus völlig recht.

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Karl heinz Buchegger schrieb:
> Im übrigen ist es Unsinn, für jede Funktion ein eigenes File zu
> schreiben.

Mit einer Ausnahme: für echte Bibliotheken, also solche, die dann mal
zu einem libblafasel.a gebündelt werden sollen.  Aus denen holt sich
der Linker ja jeweils einen Objektmodul (was in erster Näherung einer
Quelldatei entspricht).

Aber ich glaube, das ist noch lange kein Problem für Alex. ;-)

Autor: Alex (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Die 23 habe ich eingefügt, da der Compiler einen Fehler für die 
#define(s) in der der test_uart.c gemeldet hat.

Wenn die diese in der .h-Datei schreibe, müsste es dann gehen?

Viele Grüße


Alex

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

Bewertung
0 lesenswert
nicht lesenswert
Alex schrieb:
> Die 23 habe ich eingefügt, da der Compiler einen Fehler für die
> #define(s) in der der test_uart.c gemeldet hat.

Dann muss man dem Fehler nachgehen!
Dazu ist es vorteilhaft, wenn man die Fehlermeldung liest. Manchmal sind 
sie irreführend, aber meistens geben sie einen guten Hinweis, was das 
Problem ist.

>
> Wenn die diese in der .h-Datei schreibe, müsste es dann gehen?

Es geht auch so. Aber trozdem willst du die 23 da nicht drinnen haben. 
Wenn du eine andere Baudrate haben willst, dann willst du auf keinen 
Fall in der UART.C zu händisch mit Taschenrechner zu rechnen anfangen 
müssen. Du hast einen Compiler, der für dich einfache Berechnungen 
machen kann! Die 23 kann der Compiler auch selber aus der Taktfrequenz 
und der Baudrate ausrechnen.

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Karl heinz Buchegger schrieb:
> Die 23 kann der Compiler auch selber aus der Taktfrequenz
> und der Baudrate ausrechnen.

http://www.nongnu.org/avr-libc/user-manual/group__...

Autor: Alex (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich habe jetzt mal versucht etwas über die Seriele Schnittstelle mit 
Hilfe von HTerm zu empfangen.

Es kommt aber leider nicht.

Was kann denn der Grund dafür sein?

Viele Grüße

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.