Forum: Compiler & IDEs mulible definition


von Alex (Gast)


Lesenswert?

hallo,

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


1
main.o: In function `initusart':
2
C:\Dokumente und Einstellungen\Projektrechner E\Eigene Dateien\Uarttestausbuch\default/../initusart1.c:14: multiple definition of `initusart'
3
initusart1.o:C:\Dokumente und Einstellungen\Projektrechner E\Eigene Dateien\Uarttestausbuch\default/../initusart1.c:14: first defined here
4
main.o: In function `putch':
5
C:\Dokumente und Einstellungen\Projektrechner E\Eigene Dateien\Uarttestausbuch\default/../putch1.c:9: multiple definition of `putch'
6
putch1.o:C:\Dokumente und Einstellungen\Projektrechner E\Eigene Dateien\Uarttestausbuch\default/../putch1.c:9: first defined here
7
main.o: In function `getch':
8
C:\Dokumente und Einstellungen\Projektrechner E\Eigene Dateien\Uarttestausbuch\default/../getch1.c:11: multiple definition of `getch'
9
getch1.o:C:\Dokumente und Einstellungen\Projektrechner E\Eigene Dateien\Uarttestausbuch\default/../getch1.c:11: first defined here
10
main.o: In function `getche':
11
C:\Dokumente und Einstellungen\Projektrechner E\Eigene Dateien\Uarttestausbuch\default/../getche1.c:9: multiple definition of `getche'
12
getche1.o:C:\Dokumente und Einstellungen\Projektrechner E\Eigene Dateien\Uarttestausbuch\default/../getche1.c:9: first defined here
13
main.o: In function `kphit':
14
C:\Dokumente und Einstellungen\Projektrechner E\Eigene Dateien\Uarttestausbuch\default/../kphit1.c:9: multiple definition of `kphit'
15
kphit1.o:C:\Dokumente und Einstellungen\Projektrechner E\Eigene Dateien\Uarttestausbuch\default/../kphit1.c:9: first defined here
16
make: *** [Uarttestausbuch.elf] Error 1
17
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

von Karl H. (kbuchegg)


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.

von Alex (Gast)


Lesenswert?

Hier mein Quellcode
1
//test_uart.c (MAINFUNKTION)
2
#include<avr/io.h>
3
#include "konsole.h"
4
5
6
//#define TAKT 3686400UL
7
//#define BAUD 9600UL
8
9
10
11
int main(void)
12
13
{
14
15
initusart();
16
putch('>');
17
18
while(1)
19
20
{
21
22
getch();
23
24
}
25
}
26
27
28
//initusart.c Usart initialisieruen
29
30
#include <avr/io.h>
31
32
33
void initusart(void)
34
35
{
36
37
unsigned char x;
38
//UBRRL = (TAKT /16UL*BAUD)-1;
39
UBRRL=23;
40
UCSRB |=(1<< TXEN)|(1<<RXEN);
41
UCSRC |=(1<< URSEL) |(1<<UCSZ1);
42
x=UDR;
43
}
44
45
46
//putch.c Zeichen an Sender
47
48
#include<avr/io.h>
49
50
void putch (unsigned char x)
51
52
{
53
loop_until_bit_is_set(UCSRA,UDRE);
54
UDR=x;
55
}
56
57
//getch.c warten auf Zeichen abholen
58
59
#include<avr/io.h>
60
61
62
63
unsigned char getch(void)
64
65
{
66
67
loop_until_bit_is_set(UCSRA, RXC);
68
69
return UDR;
70
}
71
//getche.c warte, Zeichen abholen und im Echo senden
72
#include<avr/io.h>
73
74
75
unsigned char getche(void)
76
{
77
unsigned char x;
78
79
loop_until_bit_is_set(UCSRA,RXC);
80
81
x=UDR;
82
83
loop_until_bit_is_set(UCSRA, TXC);
84
85
UDR=x;
86
return x;
87
}
88
//kbhit.c Empfänger testen kein Zeichen: Rückgabewert 0
89
90
#include<avr/io.h>
91
92
unsigned char kphit(void)
93
94
{
95
96
if(bit_is_set(UCSRA,RXC)) return UDR; else return 0;
97
98
}
99
100
//konsole.h
101
102
#include "initusart.c"
103
#include "putch.c"
104
#include "getch.c"
105
#include "getche.c"
106
#include "kphit.c"

von Rolf Magnus (Gast)


Lesenswert?

1
#include "initusart.c"
2
#include "putch.c"
3
#include "getch.c"
4
#include "getche.c"
5
#include "kphit.c"

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

von Rufus Τ. F. (rufus) Benutzerseite


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.

von Karl H. (kbuchegg)


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.

von Karl H. (kbuchegg)


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
*****************
1
#include <avr/io.h>
2
#include "uart.h"
3
4
//#define TAKT 3686400UL
5
//#define BAUD 9600UL
6
7
int main(void)
8
{
9
  initusart();
10
  putch('>');
11
12
  while(1) {
13
    getch();
14
  }
15
}

File: uart.c
************
1
#include <avr/io.h>
2
#include "uart.h"
3
4
void initusart( void )
5
{
6
  unsigned char x;
7
8
  //UBRRL = (TAKT /16UL*BAUD)-1;
9
  UBRRL = 23;
10
  UCSRB |= (1<< TXEN) | (1<<RXEN);
11
  UCSRC |= (1<< URSEL) | (1<<UCSZ1);
12
  x = UDR;
13
}
14
15
void putch( unsigned char x )
16
{
17
  loop_until_bit_is_set( UCSRA, UDRE );
18
  UDR = x;
19
}
20
21
unsigned char getch( void )
22
{
23
  loop_until_bit_is_set( UCSRA, RXC );
24
  return UDR;
25
}
26
27
unsigned char getche( void )
28
{
29
  unsigned char x = getch();
30
  putch( x );
31
  return x;
32
}
33
34
unsigned char kbhit( void )
35
{
36
  if( bit_is_set( UCSRA, RXC ) )
37
    return UDR;
38
  else
39
    return 0;
40
}

File: uart.h
************
1
void initusart( void );
2
void putch( unsigned char x );
3
unsigned char getch( void );
4
unsigned char getche( void );
5
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.

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


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

von Alex (Gast)


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

von Karl H. (kbuchegg)


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.

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


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

von Alex (Gast)


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

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.