Forum: Compiler & IDEs nested #if makro


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
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

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]
  • [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.