Forum: Compiler & IDEs nested #if makro


von nest (Gast)


Lesenswert?

wie macht man sowas hier richtig?
1
#define LED_SET_ON(PRT,PIN,INV)\
2
  #if(INV == 0)\
3
    PORT##PRT |= (1<<PIN)\
4
  #else\
5
    PORT##PRT &=~(1<<PIN)
6
7
#define LED_SET_OFF(PRT,PIN,INV)\
8
  #if(INV == 1)\
9
    PORT##PRT |= (1<<PIN)\
10
  #else\
11
    PORT##PRT &=~(1<<PIN)

Im code bzw. in weiteren makros will ich es so nutzen:
1
LED_SET_ON(D,5,1);  // PD5 low  -> LED an
2
LED_SET_ON(D,6,0);  // PD6 high -> LED an
3
(...)
4
LED_SET_OFF(D,5,1); // PD5 high -> LED aus
5
LED_SET_OFF(D,6,0); // PD6 low  -> LED aus

Die LED-Markos sind noch falsch definiert, sodass der Compiler einen 
Fehler wirft:
1
myfile.c:203:31: error: '#' is not followed by a macro parameter
daher werden die Markos auch im code als Funktionen mit Parametern 
interpretiert:
1
LED_SET_OFF(D,5,1)
1
myfile.c:223:16: error: 'D' undeclared (first use in this function)

von nest (Gast)


Lesenswert?

Stromlauf, falls man es sich nicht schon aus dem Code-Beispiel herleiten 
kann:
1
uC
2
 ........
3
 .      .    LED1
4
 .  PD5 o-----|<|--R---Vcc
5
 .      .
6
 .      .
7
 .      .    LED2
8
 .  PD6 o-----|>|--R---GND
9
 .      .
10
 ........

von nest (Gast)


Lesenswert?

ok ... hab es doch selbst gefunden:
1
#define LED_SET_ON( PRT,PIN,INV) ((INV)==0)?(PORT##PRT|=(1<<PIN)):(PORT##PRT&=~(1<<PIN))
2
#define LED_SET_OFF(PRT,PIN,INV) ((INV)!=0)?(PORT##PRT|=(1<<PIN)):(PORT##PRT&=~(1<<PIN))

von Micha (nichtgast)


Lesenswert?

Warum brauchst du zwei Makros, die eigentlich das gleiche tun?

von Rolf M. (rmagnus)


Lesenswert?

Wenn man meint, das zu brauchen, könnte man auch einfach schreiben:
1
#define LED_SET_OFF(PRT,PIN,INV) LED_SET_ON(PRT, PIN, !(INV))

von Peter D. (peda)


Lesenswert?


von (prx) A. K. (prx)


Lesenswert?

nest schrieb:
> wie macht man sowas hier richtig?

#if Statements sind so nicht anwendbar. Sie wirken zum Zeitpunkt der 
Makrodefinition, nicht bei der Verwendung des Makros.

von Eric B. (beric)


Lesenswert?

1
#define DEFINE_LED(NAME,PRT,PIN,INV)   \
2
  inline void Led_##NAME_Off() {       \
3
    if(INV) PORT##PRT |= (1<<##PIN);   \
4
    else    PORT##PRT &= (1<<##PIN); } \
5
  inline void Led_##NAME_On()  {       \
6
    if(INV) PORT##PRT &= (1<<##PIN);   \
7
    else    PORT##PRT |= (1<<##PIN); }
8
9
DEFINE_LED(Warning,D,5,true)
10
DEFINE_LED(Power,  D,6,false)
11
12
...
13
Led_Warning_Off();
14
Led_Power_On();
Und dann hoffen, dass der Compiler alles schön inline-t ;-)

Hat wenigstens den Vorteil dass
* ich mich nur an einer Stelle drum kümmern muss ob eine LED mit 
Negativ-Logik angesprochen werden soll
* ich mich nicht Port und Pin merken muss im Code, sondern eine 
sinnvolle Name benutzen kann,
* und nicht definierte LEDs zur Compile-time schon gefunden werden.

: Bearbeitet durch User
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.