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 Keiner N. (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.