Forum: Mikrocontroller und Digitale Elektronik Externe Variabeln


von Ma B. (drumstick)


Lesenswert?

Guten Tag!

Ich arbeite mit dem STM32F107VC, uVision von Keil.

Ich möchte mit externen Variabeln arbeiten. Meine Idee, in einem 
header-file deklariere ich meine Variable. Dieses headerfile include ich 
dann in jedem c-file, in dem ich die Variable verwenden möchte.

1
var.h
2
3
extern unsigned char drivefirst;
1
main.c
2
3
#include <var.h>
4
5
void main (void)
6
{
7
drivefirst = 1;
8
9
while(1){}
10
}
1
ADC.c
2
3
#include <var.h>
4
5
void ADC (void)
6
{
7
drivefirst = 2;
8
}


folgender Fehler erscheint:

Frontego_ARM_2011_MAB.axf:

Error: L6218E: Undefined symbol drivefirst (referred from main.o).


was bedeuted dies??? Ist meine Anwendung mit externen Variabeln falsch??


Danke und Gruss!

M.B.

von ttl (Gast)


Lesenswert?

du hast in dem heder file keine Variable deklariert !! C lernen !!!

von (prx) A. K. (prx)


Lesenswert?

ttl schrieb:

> du hast in dem heder file keine Variable deklariert !! C lernen !!!

Daklariert hat er sie sehr wohl. Er hat sie aber nirgends definiert.

von Ma B. (drumstick)


Lesenswert?

Also bin ich nicht komplett auf dem Holzweg??

Eine Variable wird ja im c-file definiert?!

dies würde ganau gleich aussehen!??

1
extern unsigned char drivefirst = 0;

Danke und Gruss!


M.B.

von (prx) A. K. (prx)


Lesenswert?

Deklaration, beliebig oft:
  extern unsigned char drivefirst;
Definition, genau einmal:
  unsigned char drivefirst; // mit oder ohne "= 0"

von Ma B. (drumstick)


Lesenswert?

Jetzt hab ichs kapiert! Vielen Dank!!

gruss


M.B.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

A. K. schrieb:
> Deklaration, beliebig oft:
>   extern unsigned char drivefirst;
> Definition, genau einmal:
>   unsigned char drivefirst; // mit oder ohne "= 0"

Da gibt es übrigens einen netten Trick, wie man seine globalen Variablen 
nur 1x statt 2x aufschreiben muss und das Problem der 
Definition/Deklaration mit einer Klappe erschlagen kann:

main.c:
1
#define C_MAIN
2
#include "vars.h"

adc.c:
1
#include "vars.h"

vars.h:
1
#ifdef C_MAIN
2
#define EXT
3
#define EXT_INIT(x) = x
4
#else
5
#define EXT extern
6
#define EXT_INIT
7
#endif
8
9
EXT unsigned char drivefirst EXT_INIT(7);
10
....

Das hat einen weiteren Vorteil: Bei späteren Typ-Änderungen einer 
globalen Variablen muss man nur an einer Stelle ändern.

von Ma B. (drumstick)


Lesenswert?

Hallo.


Das hab ich jetzt noch nicht kapiert!
Dies ist mein reales Beispiel!

1
#ifdef C_MAIN
2
#define EXT
3
#define EXT_Init(x) = 0
4
#else
5
#define EXT extern
6
#define EXT_Init
7
#endif
8
9
EXT int r1 EXT_Init(0);
10
EXT int l1 EXT_Init(0);
11
EXT int r2 EXT_Init(0);
12
EXT int l2 EXT_Init(0);


Was setze ich für das x in der Klammer (3. Zeile) ein??
Warum klappt das mit dem extern nicht?? Das extern (5. codzeile) wird 
als normaler Text angezeigt!?


Danke und Gruss!

M.B.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

M. B. schrieb:

> Was setze ich für das x in der Klammer (3. Zeile) ein??

Den initialen Wert der Variablen - wenn er von 0 abweicht. Globale 
Variablen werden standardmäßig mit 0 initialisiert, deshalb kannst Du 
das EXT_Init(0) auch weglassen, wenn der initiale Wert 0 sein soll. 
Schreibe dann einfach:

EXT int r1;
EXT int l1;
EXT int r2;
EXT int l2;

> Warum klappt das mit dem extern nicht?? Das extern (5. codzeile) wird
> als normaler Text angezeigt!?

Diesen Satz habe ich nicht verstanden. Gibt es eine 
Compiler-Fehlermeldung? Wenn ja, welche.

Zur Erklärung: Der Preprocessor ist ein normaler, dummer Text-Ersetzer.
Wenn C_MAIN gesetzt ist, wird aus:
1
EXT int r1 EXT_Init(0)     ---> int r1 = 0;

denn "EXT" wird mit "" (Leerstring) und "EXT_Init(x)" wird mit "= x"
ersetzt.

Wenn C_MAIN NICHT gesetzt ist:
1
EXT int r1 EXT_Init(0)     ---> extern int r1;

denn dann wird "EXT" mit "extern" und "EXT_Init(x)" mit "" (Leerstring) 
ersetzt.

Wichtig: Das ganze klappt nur, wenn in GENAU EINEM Source "#define 
C_MAIN" VOR dem include Deiner var.h setzt

von Ulrich (Gast)


Lesenswert?

M. B. schrieb:
> #define EXT_Init(x) = 0

Hier sollt aber =x stehen, damit du auf den angegebenen Wert 
initialisieren kannst. So wie hier:

Frank M. schrieb:
> #define EXT_INIT(x) = x

Sonst bist du auf =0 festgelegt, was auch weggelassen werden kann.

von Ma B. (drumstick)


Lesenswert?

1
Main.c
2
3
#include <STM32F10x.h>                                             
4
#define C_MAIN                                                          
5
#include <Init.h>
1
Init.h
2
3
#ifdef C_MAIN
4
#define EXT
5
#define EXT_Init(x) = x
6
#else
7
#define EXT extern  // Dieses extern erscheint als Text
8
#define EXT_Init
9
#endif
10
11
EXT int r1;
12
EXT int l1;
13
EXT int r2;
14
EXT int l2;
15
EXT int r3;
16
EXT int l3;

So, jetzt werden keine Fehler angezeigt! Super Danke!

Also ist dies Deklaration und definition in einem???

Das mit dem extern , ich dachte diese müsse sich blau färben (keyword 
des System wie z.B.  int oder while) ????!!!


Vielen Dank und Gruss!

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

M. B. schrieb:
> So, jetzt werden keine Fehler angezeigt! Super Danke!

Prima.

> Also ist dies Deklaration und definition in einem???

Sozusagen. Beim Compilieren von main.c werden die Variablen definiert, 
beim Compilieren von adc.c werden sie deklariert.

> Das mit dem extern , ich dachte diese müsse sich blau färben (keyword
> des System wie z.B.  int oder while) ????!!!

Manche Editoren färben es nur ein, wenn es auch das erste Wort in der 
Zeile ist. Das ist bei der #define-Zeile nicht der Fall.

Du solltest Dich beim Lernen von C auch mit dem C-Preprocessor 
beschäftigen - insbesondere was Macros betrifft (wie z.B. EXT_INIT(x)). 
Damit kann man sich oft das Leben erleichtern.

Viel Spaß,

Frank

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.