Forum: Compiler & IDEs switch, include


von C. S. (chappi)


Lesenswert?

hallo,

ich möchte eine Art Menüauswahl mit einer switch case Anweisung 
erzeugen. Per UART wird dann ein Zeichen gesendet, welches der main dann 
sagt, welches Programm benötigt wird.

Mein Programm (welches ich auch so compiliert habe....Hi @ Karl Heinz ;) 
)
sieht wie folgt aus:
1
#include <avr/io.h>
2
#include "uart_init_baud.h"
3
4
//prototypes
5
void uart_init(void);
6
uint8_t uart_getc(void);
7
8
9
int main( void )
10
{
11
  // Portsettings
12
  DDRA  = 0x00;                // PORT A as input
13
  DDRB  = (1<<DDB2)|(1<<DDB3)|(1<<DDB4);  // PIN 2,3,4 as output
14
  PORTB   = 0x00;                // PORT B as input
15
  DDRC   = (1<<DDC0)|(1<<DDC1)|(1<<DDC6);  // PIN 0,1,6 as output for MUX
16
  PORTC   = 0x00;                // PORT C as input
17
  DDRD  = 0xFF;                // PORT  D as output
18
  PORTD  = 0x00;               // LEDs PORT D red ON
19
20
  uart_init();
21
22
// Programme / Prüflinge
23
char choose = '0';            
24
25
  while(1)
26
  {
27
    choose=uart_getc();
28
    switch(choose)
29
    {
30
      case '1': #include "37047009.h";              break;
31
      
32
    }
33
  }
34
return 0;
35
36
}
37
38
/*initialize UART*/
39
void uart_init(void)
40
{
41
42
    UCSR0B |= (1<<TXEN0)|(1<<RXEN0);  // enable UART TX and RX (transmit and receive)
43
    UCSR0C |= (1<<UCSZ01)|(1<<UCSZ00)|(1<<USBS0);  // asynchron 8N1 
44
 
45
    UBRR0H = UBRR_VAL >> 8;
46
     UBRR0L = UBRR_VAL & 0xFF;
47
}
48
49
/* char input */
50
uint8_t uart_getc(void)
51
{
52
    while (!(UCSR0A & (1<<RXC0)))   // hold on until char available
53
        ;
54
    return UDR0;                   // return char
55
}


Ich bekomme bei dem Aufruf mehrere Fehlermeldungen:

"stray '#' in program"
"include undeclared"
"expected ';' before string constant"

sobald ich das "#include" wegnehme und z.b. "int j =0;" hinschreibe ist 
alles i.O.

von Fabian (Gast)


Lesenswert?

Ich glaube das #include muss in einer eigenen Zeile steht, damit es vom 
Precompiler als ein solches erkannt wird.

von Hc Z. (mizch)


Lesenswert?

#include ist eine Präprozessor-Anweisung; sie steuert den 
Kompiliervorgang.  Zur Laufzeit Deines Programms ist das Kompilieren 
längst gegessen und Du kannst so keine Flusssteuerung machen.

Wenn Du einen Programmteil ausführen willst oder nicht (in Abhängigkeit 
von einer Bedingung), musst Du die darin enthaltenen Funktionen aufrufen 
oder nicht.

von C. S. (chappi)


Lesenswert?

ouh man...d.h. also ich muss jedes mal den gesamten Quellcode des 
Programms dann in die case Spalte packen? Ist ja mal voll doof :(

von xXx (Gast)


Lesenswert?

Doof ist nur, C ohne Buch durch Rumprobieren lernen zu wollen...

von C. S. (chappi)


Lesenswert?

1. man kann nicht alles wissen und ich denke das ist ein Fall wo man mal 
ruhig nachfragen kann

2. ist es ja nicht  so, dass ich schonmal gegoogelt hätte oder mich z.B. 
in Galileo Computing eingelesen hätte

Doof sind solche Kommentare!

von Rolf Magnus (Gast)


Lesenswert?

C. S. schrieb:
> 1. man kann nicht alles wissen

Genau deswegen gibt es ja Bücher.

C. S. schrieb:
> ouh man...d.h. also ich muss jedes mal den gesamten Quellcode des
> Programms dann in die case Spalte packen? Ist ja mal voll doof :(

Nein, mußt du nicht. Mach eine Funktion daraus und rufe diese in deinem 
case auf.

von Oliver (Gast)


Lesenswert?

C. S. schrieb:
> Mein Programm (welches ich auch so compiliert habe....Hi @ Karl Heinz ;)
> sieht wie folgt aus:
> <snip>
C. S. schrieb:
> Ich bekomme bei dem Aufruf mehrere Fehlermeldungen:

Selbst Karl Heinz kann nichts daran ändern, daß du nichts "compiliert" 
hast. Fehlerhafte Programme lassen sich nicht kompilieren.


C. S. schrieb:
> ouh man...d.h. also ich muss jedes mal den gesamten Quellcode des
> Programms dann in die case Spalte packen? Ist ja mal voll doof :(

Du könntest dort einen Funktionsaufruf hinschreiben.

xXx schrieb:
> Doof ist nur, C ohne Buch durch Rumprobieren lernen zu wollen...

C. S. schrieb:
> 1. man kann nicht alles wissen und ich denke das ist ein Fall wo man mal
> ruhig nachfragen kann

Na ja, es ist und bleibt der Versuch, in C durch trial and error 
programmieren zu wollen, ohne auch nur die einfachsten, aber notwendigen 
Grundkonzepte zu kennen. Du kommst um RTFM nicht herum.

Oliver

von Tom M. (Gast)


Lesenswert?

Es gibt ein echt gutes deutsches Buch für C Einsteiger online:
http://de.wikibooks.org/wiki/C-Programmierung

Schau dir mal den Abschnitt über den Präprozessor an.

Was du möchtest ist ev. die Funktionalität in eine function packen und 
mehrfach verwenden. Die function muss nicht zwingend in deinem 
Hauptprogramm stehen. Im einfachsten Fall verwendest du zum einbinden 
eben include.

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


Lesenswert?

Man kann ein #include natürlich wirklich immer und überall stehen
haben, also wenn du das partout möchtest, geht sowas:
1
    switch(choice)
2
    {
3
      case '1':
4
#include "37047009.c"
5
              break;
6
      
7
    }

Allerdings empfinden das die meisten C-Programmierer als miserablen
Programmierstil, den man nur dann anwendet, wenn es irgendeinen
nennenswerten Vorteil bringt, das genau so zu tun.  Ich könnte mir
im Moment nahezu keinen Grund vorstellen, warum man das wirklich
will, selbst dann nicht, falls der Inhalt von 37047009.c beispielsweise
automatisch generiert worden ist.  Auch dann sollte es möglich sein,
das über eine Funktion verständlicher aufzuschreiben.  Wo ich es, glaub'
ich, schon mal verwendet habe, war sowas:
1
static uint8_t somearray[] = {
2
#include "arraycontents.c"
3
};
4
5
...

wobei arraycontents.c tatsächlich während des Build-Prozesses automa-
tisch generiert worden ist.

Beachte auch, dass ich die include-Datei bewusst hier auf .c enden
lassen habe, denn sie enthält ja dann nicht nur Deklarationen, sondern
realen Code.

von Karl H. (kbuchegg)


Lesenswert?

Zeig doch mal den Inhalt von 37047009.h

Dann weiß man erst mal wovon du überhaupt redest.


Die normale Vorgehensweise um Code zu modularisieren ist es, Funktionen 
zu schreiben und diese aufzurufen. Und nein, nach Studium eines C-Buchs 
wäre das die absolut naheliegenste Variante und nicht etwa die, da jetzt 
mit #includes rumzumachen. Wenn du dich daher beschwerst ...

> ouh man...d.h. also ich muss jedes mal den gesamten Quellcode
> des Programms dann in die case Spalte packen? Ist ja mal voll
> doof :(

... dann kann man daraus eigentlich nur das ablesen, dass du eben kein 
Buch hast, bzw. es nicht (wenigstens in der ersten Hälfte) 
durchgearbeitet hast, sondern es als eine Art Nachschlagwerk ansiehst. 
Das funktioniert aber nicht. Grundlegende Konzepte, wie zb 
Stringverarbeitung - wie zb Funktionen, kann man nicht im Anlassfall 
lernen, sondern das muss in der Lehre systematisch entwickelt und 
eingeführt werden. Genau so, wie einen eben ein Buch durch die Thematik 
führt.



Ich 'erfinde' mal ein wenig

1
#include <avr/io.h>
2
#include "uart_init_baud.h"
3
4
//prototypes
5
void uart_init(void);
6
uint8_t uart_getc(void);
7
8
void handleADC()
9
{
10
  // tu was auch immer notwendig ist um 1
11
  // ADC Abfrage zu machen
12
}
13
14
int main( void )
15
{
16
  // Portsettings
17
  DDRA  = 0x00;                // PORT A as input
18
  DDRB  = (1<<DDB2)|(1<<DDB3)|(1<<DDB4);  // PIN 2,3,4 as output
19
  PORTB   = 0x00;                // PORT B as input
20
  DDRC   = (1<<DDC0)|(1<<DDC1)|(1<<DDC6);  // PIN 0,1,6 as output for MUX
21
  PORTC   = 0x00;                // PORT C as input
22
  DDRD  = 0xFF;                // PORT  D as output
23
  PORTD  = 0x00;               // LEDs PORT D red ON
24
25
  uart_init();
26
27
// Programme / Prüflinge
28
char choose = '0';            
29
30
  while(1)
31
  {
32
    choose=uart_getc();
33
    switch(choose)
34
    {
35
      case '1':
36
        handleADC();
37
        break;
38
    }
39
  }
40
41
  return 0;
42
}
43
44
...

natürlich kannst du jetzt hergehen und die Funktion handleADC in ein 
eigenes Source Code File auslagern, damit du deren Code nicht im 
Haupt-C-File rumlungern hast:

zb
ADC.c
*****
1
#include "adc.h"
2
3
void handleADC()
4
{
5
  // tu was auch immer notwendig ist um 1
6
  // ADC Abfrage zu machen
7
}


ADC.h
*****
1
void handleADC();

Main.c
******
1
#include <avr/io.h>
2
#include "uart_init_baud.h"
3
#include "ADC.h"
4
5
//prototypes
6
void uart_init(void);
7
uint8_t uart_getc(void);
8
9
int main( void )
10
{
11
  // Portsettings
12
  DDRA  = 0x00;                // PORT A as input
13
  DDRB  = (1<<DDB2)|(1<<DDB3)|(1<<DDB4);  // PIN 2,3,4 as output
14
  PORTB   = 0x00;                // PORT B as input
15
  DDRC   = (1<<DDC0)|(1<<DDC1)|(1<<DDC6);  // PIN 0,1,6 as output for MUX
16
  PORTC   = 0x00;                // PORT C as input
17
  DDRD  = 0xFF;                // PORT  D as output
18
  PORTD  = 0x00;               // LEDs PORT D red ON
19
20
  uart_init();
21
22
// Programme / Prüflinge
23
char choose = '0';            
24
25
  while(1)
26
  {
27
    choose=uart_getc();
28
    switch(choose)
29
    {
30
      case '1':
31
        handleADC();
32
        break;
33
    }
34
  }
35
36
  return 0;
37
}
38
39
...

auf die Art hast du den Inhalt der Funktion aus der Datei mit der 
Hauptschleide ausgelagert. Aber nichts desto trotz, ist das immer noch 
einfach nur ein Funktionsaufruf. Lediglich die Zutaten sind auf mehrere 
*.C Files verteilt.

von C. S. (chappi)


Lesenswert?

Mal kurz eine Zwischenfrage:

Ist es besser bzw. egal, ob ich die source- bzw. headerfiles per AVR 
Studio oder mit einem "klassischen" #include einbinde? Letzteres ist ja 
eigentlich universeller für alle Programme oder?

von Klaus W. (mfgkw)


Lesenswert?

Per #include werden i.d.R. Headerdateien (*.h) eingebunden,
kein sonstigen Quelltexte (*.c, *.cpp).

Letztere werden in das Projekt aufgenommen (makefile,
AVR-Studio, ...) und kompiliert.

Die Headerdateien werden nicht direkt kompiliert.

Ausnahme sind gelegentlich automatisch generierte Teile von
C-Quelltexten, die ebenfalls per #include eingebunden werden
und dementsprechend nicht als eigenständiger Quelltext zum
Kompilieren im Projekt stehen. Beispiel: Initialisierungswerte
für ein Feld oder ähnliches. Ob man die dann *.c nennen will,
muß man selber sehen; besonders geschickt finde ich es nicht.

Steht gelegentlich in einem guten C-Buch...

von C. S. (chappi)


Lesenswert?

so, habe nun vieles ausgelagert etc. Allerdings ist mein Data von 589 
Bytes auf 853 Bytes gestiegen. Habe ich dann zuviele Dateien zu oft 
eingebunden (teilweise musste ich in mehrere Dateien einen Headerfile 
einbinden, damit jede für sich kompiliert auch funktioniert)? Schlucken 
Standardbibliotheken viel von dem Speicherplatz?

Wenn ihr wollt könnte ich natürlich auch mal das Projekt hochladen.

von Karl H. (kbuchegg)


Lesenswert?

C. S. schrieb:
> so, habe nun vieles ausgelagert etc. Allerdings ist mein Data von 589
> Bytes auf 853 Bytes gestiegen.

Das könnte daher kommen, weil der Compiler jetzt ein paar kurze 
Funktionen nicht mehr inlinen kann.
Oder du hast einen Fehler gemacht und hast jetzt ein paar Variablen 
doppelt im System.

Aber wie immer gilt:
Wenn wir nicht die Glaskugeln befragen sollen, musst du schon was 
zeigen.

> Habe ich dann zuviele Dateien zu oft
> eingebunden (teilweise musste ich in mehrere Dateien einen Headerfile
> einbinden, damit jede für sich kompiliert auch funktioniert)?

Das ist egal, weil man in Headerfiles (ausser bei Funktionen die man 
geinlined haben möchte) normalerweise nichts hat, was sich im fertigen 
Programm in Form von Speicherverbrauch niederschlägt.

> Schlucken
> Standardbibliotheken viel von dem Speicherplatz?

Definiere 'viel'.
Der Anteil der Standardbibliothek bewegt sich normalerweise in einem 
gewissen Rahmen. Wird das Programm größer sinkt der prozentuale Anteil 
den die Standardbibliotheken brauchen.

von Hc Z. (mizch)


Lesenswert?

C. S. schrieb:
> Allerdings ist mein Data von 589
> Bytes auf 853 Bytes gestiegen.

Gegenüber wann?  Das Projekt war ja vorher wohl nicht kompilierbar, also 
muss der Vergleichswert schon recht alt sein.

> Habe ich dann zuviele Dateien zu oft
> eingebunden (teilweise musste ich in mehrere Dateien einen Headerfile
> einbinden, damit jede für sich kompiliert auch funktioniert)?

Die Data Section enthält die initialisierten Variablen, keinen 
Programmcode.

Da Headerfiles nur Deklarationen und Präprozessor-Anweisungen enthalten 
sollten, vergrößern sie normalerweise weder Code (text) noch Data.

> Schlucken
> Standardbibliotheken viel von dem Speicherplatz?

Data-Verbrauch dürfte Null bis minimal sein.  Code (text) wird natürlich 
gebraucht -- und zwar abhängig von dem, was Du einbindest.

von Klaus W. (mfgkw)


Lesenswert?

Karl heinz Buchegger schrieb:
> Standardbibliotheken

und definiere: "Standardbibliotheken"
Alles wirst du davon selten in deinem Programm haben.
Der Platzverbrauch könnte u.U. dezent davon abhängen, WAS du davon 
nutzst.

von Hc Z. (mizch)


Lesenswert?

C. S. schrieb:
> Wenn ihr wollt könnte ich natürlich auch mal das Projekt hochladen.

Mach das mal.  Aber bitte als Anhang.  Entweder gezippt oder die 
Einzeldateien (wenns nicht zu viele sind).

von C. S. (chappi)


Angehängte Dateien:

Lesenswert?

Das ist mein Programm vor der Umstellung! (voll funktionsfähig). Nach 
der Umstellung folgt gleich. Falls euch zu diesem noch Verbesserungen 
einfallen....nur zu :).

von Karl H. (kbuchegg)


Lesenswert?

C. S. schrieb:
> Das ist mein Programm vor der Umstellung! (voll funktionsfähig). Nach
> der Umstellung folgt gleich. Falls euch zu diesem noch Verbesserungen
> einfallen....nur zu :).

Deine Data-Section wird hauptsächlich von den Texten gefüllt.
Wenn dir SRAM ausgeht, dann wäre hier der Punkt zum ansetzen, indem man 
diese ins Flash auslagert.

von C. S. (chappi)


Lesenswert?

Karl heinz Buchegger schrieb:
> Deine Data-Section wird hauptsächlich von den Texten gefüllt.

Mit "Texten" meinst du Quellcode oder die UARTs?

von Karl H. (kbuchegg)


Lesenswert?

C. S. schrieb:
> Karl heinz Buchegger schrieb:
>> Deine Data-Section wird hauptsächlich von den Texten gefüllt.
>
> Mit "Texten" meinst du Quellcode oder die UARTs?

Mit Texten meine ich Texte.

So was
1
   .... "12 V Zuleitung" ....

wo und wie der Text verwendet wird, spielt ja keine Rolle. Den Text muss 
es ja erst mal irgendwo geben, damit man ihn verwenden kann. Und bei dir 
ist das im SRAM.
Aber lass das erst mal so. Soweit ich gesehen habe, gibt es keine 
doppelten Texte, d.h. der SRAM Verbrauch sollte eigentlich identisch 
sein und nicht davon abhängen, wie du die Einzelteile in C-Files 
aufteilst.

Nie zuviel auf einmal ändern. Ansonsten kann man keine Vergleiche mehr 
ziehen.

von C. S. (chappi)


Lesenswert?

Würdet ihr mir empfehlen ERR und ERR_FLAG mit Zeigern zu verändern oder 
doch lieber global?

Vorallem: wenn ich die Dateien dann auslager und die Variablen ggf. in 
unterschiedlichen *.c-files brauche. Ich könnte ja auch mit extern 
arbeiten aber zeiger wären dann glaube ich angenehmer oder? Nehme ich 
dann die Adresse mit in den Header oder sollte ich eine Funktion 
schreiben, die dann aufgerufen wird und dann z.B. ERR um 1 erhöht?

von Karl H. (kbuchegg)


Lesenswert?

C. S. schrieb:
> Würdet ihr mir empfehlen ERR und ERR_FLAG mit Zeigern zu verändern oder
> doch lieber global?

global.

Wie gsagt:
Lass die Logik so wie sie ist.

Jetzt geht es nur darum: Warum ist deine Data-Section plötzlich größer 
geworden.

Nicht zuviele Dinge auf einmal ändern!

> unterschiedlichen *.c-files brauche. Ich könnte ja auch mit extern
> arbeiten aber zeiger wären dann glaube ich angenehmer oder?

Und wo kriegst du die Zeiger her?
Die müssen dann ihrerseits wieder global sein

von C. S. (chappi)


Lesenswert?

Karl heinz Buchegger schrieb:
> Und wo kriegst du die Zeiger her?
>
> Die müssen dann ihrerseits wieder global sein

stimmt, gewinne ich nichts bei. Okay ich mache alles nochmal langsam und 
vergleiche Schritt für Schritt....bg :)

von C. S. (chappi)


Lesenswert?

ahhh habe das Problem mit der Data gefunden. Ich musste bei meinem neuen 
Projekt noch die libm.a (aufgrund meiner dtostrf() Funktion) einbinden. 
Daraufhin wurde das Programm sehr viel kleiner!  komisch, dass es 
trotzdem ging...

Das Projekt kommt denke ich mal morgen hoch.

von C. S. (chappi)


Angehängte Dateien:

Lesenswert?

Hier nun das Projekt (AVR Studio). Es funktioniert alles, bis auf die 
Vaiable ERR_FLAG. Die LED löst in der if Bedingung nicht aus. Weiß 
jemand warum nicht? ERR geht soweit ich das bis jetzt getestet habe.Auch 
die Data stimmt.

von Klaus W. (mfgkw)


Lesenswert?

Hc Zimmerer schrieb:
> Mach das mal.  Aber bitte als Anhang.  Entweder gezippt oder die
> Einzeldateien (wenns nicht zu viele sind).

> T2_2098h.rar

Wieso wusste ich vorher, daß das rar wird?

von C. S. (chappi)


Lesenswert?

oh okay, habe "gezippt" im sinne von gepackt verstanden, kann es aber 
noch als *.zip hochladen

von C. S. (chappi)


Angehängte Dateien:

Lesenswert?

tadaaa

von Klaus W. (mfgkw)


Lesenswert?

Danke, jetzt kann ich es auch lesen.

Die Funktion habe ich mir nicht angesehen, nur die Aufteilung an sich.

Das sieht im Prinzip sinnig aus (auch wenn ich es für ein so kleines
Projekt nicht auf soviele Headerdateien verteilt hätte, aber egal).

Bei ein paar Headerdateien (baud_calc.h, debounce.h) fehlt
die #ifndef...#define...#endif-Geschichte.

Aber die Grundifee stimmt: Deklarationen in *.h, Definitinen in *.c.

Die Objektdateien, temporäre Dateien etc. braucht niemand, die
kann man vor dem Hochladen also auch löschen.

von Klaus W. (mfgkw)


Lesenswert?

Ach so: falls man in deiner IDE einstellen kann, daß keine Tabs
gespeichert werden, sondern stattdessen Leerzeichen, dann wäre das
vorteilhaft.
Bei jedem Editor werden Tabs nämlich anders angezeigt, und dann
ist es etwas mühsam zu lesen.

von Klaus W. (mfgkw)


Lesenswert?

Zu deinen
1
uint8_t ERR;
2
uint8_t ERR_FLAG;
in functions.c:

Entweder brauchst du diese Variablen nur in functions.c.
Dann wäre es sinnvoller, sie als static zu vereinbaren.
Globale Variablen, die als static deklariert sind, sind nur in
dieser Übersetzungseinheit erreichbar (also in diesem *.c) und
werden vom Linker gegenüber anderen Objektdateien versteckt.
(static bei globalen Variablen hat nichts mit static bei lokalen
Variablen zu tun!)

Oder du brauchst sie auch aus anderen Dateien (dort als extern
deklariert), dann wäre es innvoll, gleich in der zugehörigen
Headerdatei (also functions.h) sie dort als extern zu vereinbaren.
Dann kommt jeder ran, der functions.h #includet.

von Klaus W. (mfgkw)


Lesenswert?

C. S. schrieb:
> Hier nun das Projekt (AVR Studio). Es funktioniert alles, bis auf die
> Vaiable ERR_FLAG. Die LED löst in der if Bedingung nicht aus.

Die ERR und ERR_FLAG in 3704700911.c (was für ein Name) sind NICHT
dieselben Variablen wie in functions.c!

Du hast die beiden Variablen sowohl in functions.c als globale, als
auch in ME37047009() als lokale vereinbart.
Damit existieren sie doppelt und wissen nichts voneinander.
Warhscheinlich wolltest du sie in ME37047009() als extern vereinbaren,
damit die globalen verwendet werden?

Siehe mein voriges Post.
Am besten die lokalen entfernen und in functions.h gleich als
extern deklarieren.

von C. S. (chappi)


Lesenswert?

aber ich habe sie doch in variables.h als extern deklariert. D.h. doch 
die functions.c und die 3704700911.c greifen auf die selbe Variable 
zurück. Somit verändert eine Funktion in functions.c doch auch die 
Variable, die dann in 3704700911.c (z.B. ErrorFlag zum Auslösen der LED) 
verwendet oder nicht??

Diese Extern deklarierten Variablen muss ich dann in der *.c Datei dann 
nochmal deklarieren (so wie ich das auch gemacht habe) oder nicht?

von Klaus W. (mfgkw)


Lesenswert?

C. S. schrieb:
> aber ich habe sie doch in variables.h

sorry, hatte ich übersehen.
Wenn du sie functions.c definierst, dann gehört sie auch in
functions.h deklariert. Die .c und die .h gehören doch zusammen,
wer such tden dann die Deklaration in einer anderen Headerdatei?

C. S. schrieb:
> Somit verändert eine Funktion in functions.c doch auch die
> Variable, die dann in 3704700911.c (z.B. ErrorFlag zum Auslösen der LED)
> verwendet oder nicht??

Nein, weil du die Variable noch zusätzlich lokal ohne extern
definiert hast. Das verdeckt dann die globale Variable.
Lass die lokale Definition weg, wenn du die globale Variable
nehmen willst!

> Diese Extern deklarierten Variablen muss ich dann in der *.c Datei dann
> nochmal deklarieren (so wie ich das auch gemacht habe) oder nicht?

nicht, wenn die Deklaration mit extern bereits durch die Headerdatei
per #include reinkommt.

von C. S. (chappi)


Lesenswert?

ich muss dich enttäuschen denn jetzt kommt ca. 60 mal die Fehlermeldung 
"undefined reference to temp1" "undefinded reference to temp2"

bei ERR und ERR_FLAG schein das zu klappen. Muss ich wahrscheinlich die 
Adresse als extern übergeben, da ich temp im Funktionsaufruf mit call by 
reference habe. oder ich mache sie auch gleich global und mache call by 
value

von Karl H. (kbuchegg)


Lesenswert?

C. S. schrieb:
> ich muss dich enttäuschen denn jetzt kommt ca. 60 mal die Fehlermeldung
> "undefined reference to temp1" "undefinded reference to temp2"

Was hast du jetzt genau gemacht?

Offenbar hast du die Variablendefinitionen von temp1 und temp2 auch 
rausgenommen. Die sind aber soch gar keine globalen Variablen! Also lass 
sie doch, wo sie sind.


Beachte auch, dass du (Code aus dem Zip-File) hier
1
void ME37047009(void)
2
{
3
4
uint8_t ERR;
5
uint8_t ERR_FLAG;
6
double temp1;
7
double temp2;
8
ADC_init();
9
uart_init();

schon wieder 2 Variablen namens ERR und ERR_FLAG hast. DIe haben aber 
wiederrum nichts mit globalen Variablen gleichen Namens zu tun.


Wenn ich einen Vorschlag machen darf:

*)  Namen ausschliesslich in Grossbuchstaben reservierst du
    auschliesslich für Makros.
    Eine Variable namens ERR kann es daher gar nicht geben.

    Das ist eine übliche Konvention. Eine der wenigen, an die sich
    mehr als 95% aller Programmierer weltweit halten. Es gibt keinen
    Grund, warum ausgerechnet du dich nicht daran halten solltest.

*)  Verpass globalen Variablen einen Prefix. Damit kannst du auch
    im Code erkennen, dass du hier mit einer globalen Variablen
    hantierst.

    zb, bekommen alle globalen Variablen vorweg ein 'g_"


Du hast dann

eine Datei, in der die Variable tatsächlich existiert. Du musst dir 
überlegen, wo die globale Variable konzeptionell dazugehört. In dem 
File, in dem diese Funktionalität in Form von Funktionen behandelt wird, 
dort wird dann die globale Variable tatsächlich angelegt. Also: Eine 
globale Variable, die anzeigt, dass von der UART Werte empfangen wurden 
und in einem Buffer warten, gehört konzeptionell zu den UART Routinen. 
Sie wird daher in dem C File tatsächlich angelegt, in dem auch die UART 
Funktionen sind. Im, zu diesem C File gehörenden, Header File kommt dann 
die extern Deklaration dieser globalen Variablen hinein.


uart.c
***********
1
#include "uart.h"
2
3
uint8_t  g_haveData;     // globale Variable, die anzeigt, dass Daten
4
                         // vorhanden sind
5
6
void uart_init()
7
{
8
   ...
9
10
  g_haveData = 0;
11
}
12
13
char uart_get()
14
{
15
  ....
16
17
  g_haveData = 0;
18
  return ...;
19
}


uart.h
************
1
#ifndef UART_H_INCLUDED
2
#define UART_H_INCLUDED
3
4
extern uint8_t g_haveData;   // hier ist nur die Information, dass es
5
                             // eine globale Variable dieses Namens gibt
6
7
void uart_init( void );
8
char uart_get( void );
9
10
#endif

Will jetzt jemand die UART Funktionen verwenden, dann inkludiert er 
einfach nur uart.h
1
#include "uart.h"

durch diesen Include, bekommt er auch automatisch (durch das extern im 
Header File) Zugriff auf die globale Variable.
1
#include "uart.h"
2
3
int main()
4
{
5
  uart_init();
6
7
  while( 1 ) {
8
9
     if( g_haveData ) {
10
       c = uart_get();
11
     }
12
  }
13
}


Eine Aufteilung in Header Files nach Funktionen und Variablen ist NICHT 
sinnvoll. Genausowenig wie es sinnvoll ist, die Funktions-Protoypen 
aller Funktionen aus meherern C-Files in einem Header File zu sammeln!

Wenn du die UART Funktionalität in einem anderen Projekt benutzen 
willst, dann kopierst du dir einfach uart.c und uart.h zu diesem Projekt 
dazu und du hast dann in diesen beiden Files alles beisammen, was du 
benötigst um die UART zu verwenden.

Darum geht es bei Header Files: Dass man Funktionalität so aufteilt, 
dass man sie einfach wiederfinden aber auch einfach wiederverwenden 
kann! Ansonsten hätte man ja auch einfach alles in einem einzigen 
riesengroßen C-File lassen können.

Sieh es so:
Wenn du für deinen Aussendienst Werkzeugkoffer zusammenstellen musst, 
dann ist es sinnvoll einen Koffer zu machen, in dem er alles findet was 
er zum Löten braucht. Es ist auch sinnvoll, einen Koffer zu machen in 
dem er alles vorfindet was er zum Schweißen braucht.
Muss er rausfahen überlegt er was es zu tun gibt und greift sich den 
richtigen Koffer. Er weiß dann, das er alles dabei hat, was er benötigt 
um zb in einem Schaltschrank Fehler zu suchen und zu reparieren. Da 
braucht er keine Düse für den Autogenschweißbrenner. Also ist die auch 
nicht in diesem Werkzeugkoffer enthalten.

Es ist hingegen nicht sinnvoll, Werkzeugkoffer herzurichten, wo in einem 
Koffer alle möglichen Zangen enthalten sind, in einem anderen sind alle 
möglichen Hämmer enthalten, etc.
Da muss er dann erst recht wieder in den Werkzeugkoffern rumsuchen um 
sich das Werkzeug zusammenzusuchen, dass er für einen ganz bestimmten 
Job benötigt.

von C. S. (chappi)


Lesenswert?

ahhh thx okay....funktioniert soweit alles, ich melde mich bei weiteren 
Problemen

von Klaus W. (mfgkw)


Lesenswert?

C. S. schrieb:
> ich muss dich enttäuschen denn jetzt kommt ca. 60 mal die Fehlermeldung
> "undefined reference to temp1" "undefinded reference to temp2"

Wenn du temp1 und trmp2 löschst, enttäuschst du nicht mich, sondern 
dich! :-)

von C. S. (chappi)


Lesenswert?

:D

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


Lesenswert?

Klaus Wachtler schrieb:

>> T2_2098h.rar
>
> Wieso wusste ich vorher, daß das rar wird?

Nanu, ist dein unrar(1) kaputt gegangen? ;-)
1
UNRAR 3.70 beta 3 freeware      Copyright (c) 1993-2007 Alexander Roshal
2
3
Usage:     unrar <command> -<switch 1> -<switch N> <archive> <files...>
4
               <@listfiles...> <path_to_extract\>
5
6
<Commands>
7
  e             Extract files to current directory
8
  l[t,b]        List archive [technical, bare]
9
  p             Print file to stdout
10
  t             Test archive files
11
  v[t,b]        Verbosely list archive [technical,bare]
12
  x             Extract files with full path
13
14
<Switches>
15
  -             Stop switches scanning
16
  ad            Append archive name to destination path
17
  ap<path>      Set path inside archive
18
  av-           Disable authenticity verification check
19
  c-            Disable comments show
20
  cfg-          Disable read configuration
21
  cl            Convert names to lower case
22
  cu            Convert names to upper case
23
  dh            Open shared files
24
  ep            Exclude paths from names
25
  ep3           Expand paths to full including the drive letter
26
  f             Freshen files
27
  id[c,d,p,q]   Disable messages
28
  ierr          Send all messages to stderr
29
  inul          Disable all messages
30
  kb            Keep broken extracted files
31
  n<file>       Include only specified file
32
  n@            Read file names to include from stdin
33
  n@<list>      Include files in specified list file
34
  o+            Overwrite existing files
35
  o-            Do not overwrite existing files
36
  or            Rename files automatically
37
  ow            Save or restore file owner and group
38
  p[password]   Set password
39
  p-            Do not query password
40
  r             Recurse subdirectories
41
  sl<size>      Process files with size less than specified
42
  sm<size>      Process files with size more than specified
43
  ta<date>      Process files modified after <date> in YYYYMMDDHHMMSS format
44
  tb<date>      Process files modified before <date> in YYYYMMDDHHMMSS format
45
  tn<time>      Process files newer than <time>
46
  to<time>      Process files older than <time>
47
  ts<m,c,a>[N]  Save or restore file time (modification, creation, access)
48
  u             Update files
49
  v             List all volumes
50
  ver[n]        File version control
51
  vp            Pause before each volume
52
  x<file>       Exclude specified file
53
  x@            Read file names to exclude from stdin
54
  x@<list>      Exclude files in specified list file
55
  y             Assume Yes on all queries

von Klaus W. (mfgkw)


Lesenswert?

Natürlich habe ich unrar, aber das geht nicht mit allen rar-Dateien.
Ich habe mich aber auch nie darum gekümmert warum das so ist, weil
ich es nicht brauche.
Warum soll ich mich mit dem 7845. Kompressionsformat rumplagen,
nur weil manche Leute das unbedingt nehmen wollen?

von Karl H. (kbuchegg)


Lesenswert?

Klaus Wachtler schrieb:
> Natürlich habe ich unrar, aber das geht nicht mit allen rar-Dateien.
> Ich habe mich aber auch nie darum gekümmert warum das so ist, weil
> ich es nicht brauche.
> Warum soll ich mich mit dem 7845. Kompressionsformat rumplagen,
> nur weil manche Leute das unbedingt nehmen wollen?

Ich seh das mitlerweile pragmatisch:
Krieg ich ein File im Anhang nicht durch Draufklicken auf - dann lass 
ich es. Es ist nicht mein Problem, ob ich das File entpacken kann oder 
nicht. Extra Arbeit mach ich mir deswegen nicht.

von Klaus W. (mfgkw)


Lesenswert?

Ebend, deshalb ignoriere ich rar auch.
Manchmal bin ich dann so nett (ja, kann ich auch) und
sage wenigstens, warum ich nicht antworte.

Wenn dann darauf eine zip kommt, muß ich dummrweise
anstandshalber doch wieder etwas tun :-(

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.