Forum: Mikrocontroller und Digitale Elektronik [AS7] Probleme mit Präprozessor Direktiven


von Draco (Gast)


Lesenswert?

Ich habe hier ein "Problem", welches bestimmt kein größeres ist.

Ich arbeite in Atmel Studio 7 und auf einem MEga32u4 und komme irgendwie 
mit den Präprozessor Abfragen nicht so klar. Hintergrund: Es gibt die 
Software für den µC welchen es aber in zwei verschiedenen Ausführungen 
gibt (Mit unterschiedlichen Anzeigeelementen). Die Software ist aber im 
Grunde die gleiche, so das sich zwei unterschiedliche Projekte nicht 
lohnen.

Momentan habe ich es mit ner normalen If Abfrage gelößt, was aber im 
Grunde quark ist, da der jeweils andere Code auf dem µC sinnlos ist, da 
nie gebraucht:

1
void SetGearPosition(uint8_t Gear)
2
{
3
4
  if (ucVersion == 0)
5
  {
6
  DDRB &= ~(1<<4);
7
  DDRD &= ~((1<<0)|(1<<1)|(1<<2)|(1<<4)|(1<<7));
8
  DDRE &= ~(1<<6);
9
    
10
  switch (Gear)
11
  {
12
    case 0:
13
    DDRB |= (1<<4);
14
    break;
15
    case 1:
16
    DDRE |= (1<<6);
17
    break;
18
    case 2:
19
    DDRD |= (1<<7);
20
    break;
21
    case 3:
22
    DDRD |= (1<<4);
23
    break;
24
    case 4:
25
    DDRD |= (1<<0);
26
    break;
27
    case 5:
28
    DDRD |= (1<<1);
29
    break;
30
    case 6:
31
    DDRD |= (1<<2);
32
    break;
33
    default:
34
    break;
35
  }
36
  }
37
38
  if (ucVersion == 1)
39
  {
40
  if(Gear >= 0 && Gear <= 9)
41
  {
42
    DracoMAX7219_send(Gear);
43
  }
44
  }
45
}

Wenn ich dies aber mit Präprozessorabfragen versuche, schlage ich aber 
fehl (Ich muss zugeben das ich das auch vorher nie gemacht habe):


1
#define __DracoV0_ 1
2
#define __DracoV1_ 0
3
4
//...
5
6
void SetGearPosition(uint8_t Gear)
7
{
8
9
#ifdef __DracoV0_
10
11
  DDRB &= ~(1<<4);
12
  DDRD &= ~((1<<0)|(1<<1)|(1<<2)|(1<<4)|(1<<7));
13
  DDRE &= ~(1<<6);
14
    
15
  switch (Gear)
16
  {
17
    case 0:
18
    DDRB |= (1<<4);
19
    break;
20
    case 1:
21
    DDRE |= (1<<6);
22
    break;
23
    case 2:
24
    DDRD |= (1<<7);
25
    break;
26
    case 3:
27
    DDRD |= (1<<4);
28
    break;
29
    case 4:
30
    DDRD |= (1<<0);
31
    break;
32
    case 5:
33
    DDRD |= (1<<1);
34
    break;
35
    case 6:
36
    DDRD |= (1<<2);
37
    break;
38
    default:
39
    break;
40
  }
41
#endif //__DracoV0_
42
43
44
45
#ifdef __DracoV1_
46
47
  if(Gear >= 0 && Gear <= 9)
48
  {
49
    DracoMAX7219_send(Gear);
50
  }
51
#endif //__DracoV1_
52
}

Er springt dennoch durch beide Zweige und kompiliert auch alle beide 
zweige. Jemand einen Rat?!

von Wolfgang (Gast)


Lesenswert?

Draco schrieb:
> Ich arbeite in Atmel Studio 7 und auf einem MEga32u4 und komme irgendwie
> mit den Präprozessor Abfragen nicht so klar.

Erstmal: Präprozessorabfragen haben nichts mit Atmel Studio sondern nur 
mit der Programmiersprache etwas zu tun.

Draco schrieb:
> #define _DracoV0 1
> #define _DracoV1 0
> ...
> #ifdef __DracoV0_
> ...

> Er springt dennoch durch beide Zweige und kompiliert auch alle beide
> zweige.

Wenn du beide definierst (egal wie), wird natürlich auch der Code für 
beide Fälle erzeugt. Du könntest eines der #define auskommentieren.

von Draco (Gast)


Lesenswert?

Ahhhh..... vielen Dank :D

Zum Thema C / Atmel Studio etc... das heißt quasi das es 
Compilerunabhängig ist und in allen C Compilern gleich behandelt wird?! 
Gut zu wissen, danke.


Ich habe das auch jetzt geblickt, hätte ich das nach meinem "Beispiel" 
machen wollen hätte ich es mit #if (_DracoV1 == 1) machen müssen. Aber 
so ist das mit dem einen Define ja auch wesentlich übersichtlicher. 
Danke dir fürs Licht ins Dunkel bringen :)

von Daniel (Gast)


Lesenswert?

Nimm anstatt #ifdef ein #if und dein Problem sollte gelöst sein...

Ansonsten kannst du auch einfach ein define auskommentieren.

Gruß,
Daniel

von Wolfgang (Gast)


Lesenswert?

Draco schrieb:
> Zum Thema C / Atmel Studio etc... das heißt quasi das es
> Compilerunabhängig ist und in allen C Compilern gleich behandelt wird?!

Da bringst du mehrere Dinge durcheinander.
1. Atmel Studio ist die Entwicklungsumgebung.
2. C ist die Programmiersprache
3. Die #define haben nichts mit dem Compiler zu tun
4. Zu C gehört ein Präprozessor, der soetwas wie #define abarbeitet, 
bevor der C Compiler den Source Code überhaupt zu Gesicht bekommt.

Vielleicht solltest du mal ein Blick in ein C Grundlagenbuch werfen.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

1
#define __DracoV0_ 1
2
#define __DracoV1_ 0
3
4
//...
5
6
void SetGearPosition(uint8_t Gear)
7
{
8
9
#ifdef __DracoV0_

Beide Macros sind definiert, deswegen wird #ifdef immer glücklich.

Alternative:
1
#define __DracoV0_ 
2
// #define __DracoV1_ 
3
4
//...
5
6
void SetGearPosition(uint8_t Gear)
7
{
8
9
#ifdef __DracoV0_

Ja, es genügt, ein leeres Macro zu definieren, damit #ifdef 
funktioniert.

Weitere Alternative:
1
#define __DracoVersion_ 1
2
3
//...
4
5
void SetGearPosition(uint8_t Gear)
6
{
7
8
#if __DracoVersion_ == 1


Abschließend: Macros mit zwei vorangestellten Unterstrichen sind 
verboten, die gehören ausschließlich dem Compiler. Das solltest Du Dir 
daher besser abgewöhnen.

von Draco (Gast)


Lesenswert?

Rufus Τ. F. schrieb:
> Abschließend: Macros mit zwei vorangestellten Unterstrichen sind
> verboten, die gehören ausschließlich dem Compiler. Das solltest Du Dir
> daher besser abgewöhnen.

Danke, werde ich mir einprägen. Gibt es da ungeschriebene Gesetze wie 
man diese am besten bennent?!

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.