mikrocontroller.net

Forum: Compiler & IDEs switch, include


Autor: C. S. (chappi)
Datum:

Bewertung
0 lesenswert
nicht 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:
#include <avr/io.h>
#include "uart_init_baud.h"

//prototypes
void uart_init(void);
uint8_t uart_getc(void);


int main( void )
{
  // Portsettings
  DDRA  = 0x00;                // PORT A as input
  DDRB  = (1<<DDB2)|(1<<DDB3)|(1<<DDB4);  // PIN 2,3,4 as output
  PORTB   = 0x00;                // PORT B as input
  DDRC   = (1<<DDC0)|(1<<DDC1)|(1<<DDC6);  // PIN 0,1,6 as output for MUX
  PORTC   = 0x00;                // PORT C as input
  DDRD  = 0xFF;                // PORT  D as output
  PORTD  = 0x00;               // LEDs PORT D red ON

  uart_init();

// Programme / Prüflinge
char choose = '0';            

  while(1)
  {
    choose=uart_getc();
    switch(choose)
    {
      case '1': #include "37047009.h";              break;
      
    }
  }
return 0;

}

/*initialize UART*/
void uart_init(void)
{

    UCSR0B |= (1<<TXEN0)|(1<<RXEN0);  // enable UART TX and RX (transmit and receive)
    UCSR0C |= (1<<UCSZ01)|(1<<UCSZ00)|(1<<USBS0);  // asynchron 8N1 
 
    UBRR0H = UBRR_VAL >> 8;
     UBRR0L = UBRR_VAL & 0xFF;
}

/* char input */
uint8_t uart_getc(void)
{
    while (!(UCSR0A & (1<<RXC0)))   // hold on until char available
        ;
    return UDR0;                   // return char
}


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.

Autor: Fabian (Gast)
Datum:

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

Autor: Hc Zimmerer (mizch)
Datum:

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

Autor: C. S. (chappi)
Datum:

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

Autor: xXx (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Doof ist nur, C ohne Buch durch Rumprobieren lernen zu wollen...

Autor: C. S. (chappi)
Datum:

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

Autor: Rolf Magnus (Gast)
Datum:

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

Autor: Oliver (Gast)
Datum:

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

Autor: Tom M. (Gast)
Datum:

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

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

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

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:
static uint8_t somearray[] = {
#include "arraycontents.c"
};

...

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.

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

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

#include <avr/io.h>
#include "uart_init_baud.h"

//prototypes
void uart_init(void);
uint8_t uart_getc(void);

void handleADC()
{
  // tu was auch immer notwendig ist um 1
  // ADC Abfrage zu machen
}

int main( void )
{
  // Portsettings
  DDRA  = 0x00;                // PORT A as input
  DDRB  = (1<<DDB2)|(1<<DDB3)|(1<<DDB4);  // PIN 2,3,4 as output
  PORTB   = 0x00;                // PORT B as input
  DDRC   = (1<<DDC0)|(1<<DDC1)|(1<<DDC6);  // PIN 0,1,6 as output for MUX
  PORTC   = 0x00;                // PORT C as input
  DDRD  = 0xFF;                // PORT  D as output
  PORTD  = 0x00;               // LEDs PORT D red ON

  uart_init();

// Programme / Prüflinge
char choose = '0';            

  while(1)
  {
    choose=uart_getc();
    switch(choose)
    {
      case '1':
        handleADC();
        break;
    }
  }

  return 0;
}

...

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
*****
#include "adc.h"

void handleADC()
{
  // tu was auch immer notwendig ist um 1
  // ADC Abfrage zu machen
}


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

Main.c
******
#include <avr/io.h>
#include "uart_init_baud.h"
#include "ADC.h"

//prototypes
void uart_init(void);
uint8_t uart_getc(void);

int main( void )
{
  // Portsettings
  DDRA  = 0x00;                // PORT A as input
  DDRB  = (1<<DDB2)|(1<<DDB3)|(1<<DDB4);  // PIN 2,3,4 as output
  PORTB   = 0x00;                // PORT B as input
  DDRC   = (1<<DDC0)|(1<<DDC1)|(1<<DDC6);  // PIN 0,1,6 as output for MUX
  PORTC   = 0x00;                // PORT C as input
  DDRD  = 0xFF;                // PORT  D as output
  PORTD  = 0x00;               // LEDs PORT D red ON

  uart_init();

// Programme / Prüflinge
char choose = '0';            

  while(1)
  {
    choose=uart_getc();
    switch(choose)
    {
      case '1':
        handleADC();
        break;
    }
  }

  return 0;
}

...


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.

Autor: C. S. (chappi)
Datum:

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

Autor: Klaus Wachtler (mfgkw)
Datum:

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

Autor: C. S. (chappi)
Datum:

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

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

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

Autor: Hc Zimmerer (mizch)
Datum:

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

Autor: Klaus Wachtler (mfgkw)
Datum:

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

Autor: Hc Zimmerer (mizch)
Datum:

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

Autor: C. S. (chappi)
Datum:
Angehängte Dateien:

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

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

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

Autor: C. S. (chappi)
Datum:

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

Mit "Texten" meinst du Quellcode oder die UARTs?

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

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

Autor: C. S. (chappi)
Datum:

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

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

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

Autor: C. S. (chappi)
Datum:

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

Autor: C. S. (chappi)
Datum:

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

Autor: C. S. (chappi)
Datum:
Angehängte Dateien:

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

Autor: Klaus Wachtler (mfgkw)
Datum:

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

Autor: C. S. (chappi)
Datum:

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

Autor: C. S. (chappi)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
tadaaa

Autor: Klaus Wachtler (mfgkw)
Datum:

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

Autor: Klaus Wachtler (mfgkw)
Datum:

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

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Zu deinen
uint8_t ERR;
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.

Autor: Klaus Wachtler (mfgkw)
Datum:

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

Autor: C. S. (chappi)
Datum:

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

Autor: Klaus Wachtler (mfgkw)
Datum:

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

Autor: C. S. (chappi)
Datum:

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

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

Bewertung
0 lesenswert
nicht 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
void ME37047009(void)
{

uint8_t ERR;
uint8_t ERR_FLAG;
double temp1;
double temp2;
ADC_init();
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
***********
#include "uart.h"

uint8_t  g_haveData;     // globale Variable, die anzeigt, dass Daten
                         // vorhanden sind

void uart_init()
{
   ...

  g_haveData = 0;
}

char uart_get()
{
  ....

  g_haveData = 0;
  return ...;
}


uart.h
************
#ifndef UART_H_INCLUDED
#define UART_H_INCLUDED

extern uint8_t g_haveData;   // hier ist nur die Information, dass es
                             // eine globale Variable dieses Namens gibt

void uart_init( void );
char uart_get( void );

#endif

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

durch diesen Include, bekommt er auch automatisch (durch das extern im 
Header File) Zugriff auf die globale Variable.
#include "uart.h"

int main()
{
  uart_init();

  while( 1 ) {

     if( g_haveData ) {
       c = uart_get();
     }
  }
}


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.

Autor: C. S. (chappi)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ahhh thx okay....funktioniert soweit alles, ich melde mich bei weiteren 
Problemen

Autor: Klaus Wachtler (mfgkw)
Datum:

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

Autor: C. S. (chappi)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
:D

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

Bewertung
0 lesenswert
nicht lesenswert
Klaus Wachtler schrieb:

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

Nanu, ist dein unrar(1) kaputt gegangen? ;-)

UNRAR 3.70 beta 3 freeware      Copyright (c) 1993-2007 Alexander Roshal

Usage:     unrar <command> -<switch 1> -<switch N> <archive> <files...>
               <@listfiles...> <path_to_extract\>

<Commands>
  e             Extract files to current directory
  l[t,b]        List archive [technical, bare]
  p             Print file to stdout
  t             Test archive files
  v[t,b]        Verbosely list archive [technical,bare]
  x             Extract files with full path

<Switches>
  -             Stop switches scanning
  ad            Append archive name to destination path
  ap<path>      Set path inside archive
  av-           Disable authenticity verification check
  c-            Disable comments show
  cfg-          Disable read configuration
  cl            Convert names to lower case
  cu            Convert names to upper case
  dh            Open shared files
  ep            Exclude paths from names
  ep3           Expand paths to full including the drive letter
  f             Freshen files
  id[c,d,p,q]   Disable messages
  ierr          Send all messages to stderr
  inul          Disable all messages
  kb            Keep broken extracted files
  n<file>       Include only specified file
  n@            Read file names to include from stdin
  n@<list>      Include files in specified list file
  o+            Overwrite existing files
  o-            Do not overwrite existing files
  or            Rename files automatically
  ow            Save or restore file owner and group
  p[password]   Set password
  p-            Do not query password
  r             Recurse subdirectories
  sl<size>      Process files with size less than specified
  sm<size>      Process files with size more than specified
  ta<date>      Process files modified after <date> in YYYYMMDDHHMMSS format
  tb<date>      Process files modified before <date> in YYYYMMDDHHMMSS format
  tn<time>      Process files newer than <time>
  to<time>      Process files older than <time>
  ts<m,c,a>[N]  Save or restore file time (modification, creation, access)
  u             Update files
  v             List all volumes
  ver[n]        File version control
  vp            Pause before each volume
  x<file>       Exclude specified file
  x@            Read file names to exclude from stdin
  x@<list>      Exclude files in specified list file
  y             Assume Yes on all queries

Autor: Klaus Wachtler (mfgkw)
Datum:

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

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

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

Autor: Klaus Wachtler (mfgkw)
Datum:

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

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.