Präprozessor-Makro >>> Textersatz

OP #4507397
Lesenswert?
• ▲
▼
Hallo.
Stolpere gerade über die Textübergabe innerhalb der Präprozessor-Makros.

#define PORT_AKKU (PORTB,PB4)  // Globale Vorgabe
...
#define BATT_ON (AUSGANG_SET_HIGH (PORT_AKKU))  // statt (PORTB,PB4)
#define BATT_OFF (AUSGANG_SET_LOW (PORT_AKKU))  // statt (PORTB,PB4)
...

Compiler meckert!
Ist es nicht möglich, mehr als 1 Wert gleichzeitig zu übergeben?
#4507407
Lesenswert?
• ▲
▼
@__Son´s Bersi__ (bersison)

>Stolpere gerade über die Textübergabe innerhalb der Präprozessor-Makros.

Nimm Funktionen mit gescheiten Parameter. Deine Aufgabe braucht mit an 
Sicherheit grenzender Wahrscheinlichkeit KEINE hyperschnellen 
Inline-Makrofunktionen.
OP #4507487
Lesenswert?
• ▲
▼
Peter M. schrieb:
> Und wo ist AUSGANG_SET_HIGH definiert?

Im Kopf definiert;

#define AUSGANG_SET_HIGH(port,mask) ((port) |= (1<<mask))
#define AUSGANG_SET_LOW(port,mask) ((port) &= ~(1<<mask))

Einzelne Parameter/Konstanten wie PI= 3.1415 werden problemlos ersetzt. 
Bei 2 Parametern "PORTB" und "PB4" klappt´s nicht. Finde auch nichts in 
Fachliteratur.


Falk B. schrieb:
> Nimm Funktionen mit gescheiten Parameter. Deine Aufgabe braucht mit an
> Sicherheit grenzender Wahrscheinlichkeit KEINE hyperschnellen
> Inline-Makrofunktionen.

--1--
Mir geht es darum, einen Startblock zu schaffen, in dem alle relevanten 
Parameter, übersichtlich zusammengefasst werden.
--2--
Nutze Makro gerne um dauerwiederkehrende Funktionen ab zu legen.
Warum sollte das falsch sein?
#4507539
Lesenswert?
• ▲
▼
__Son´s B. schrieb:
> Ist es nicht möglich, mehr als 1 Wert gleichzeitig zu übergeben?

Doch, über ein Zwischenmakro.
Nur in der ersten Instanz wird die Argumentenzahl geprüft.
1
struct bits {
2
  uint8_t b0:1, b1:1, b2:1, b3:1, b4:1, b5:1, b6:1, b7:1;
3
} __attribute__((__packed__));
4
#define SBIT_(port,pin) ((*(volatile struct bits*)&port).b##pin)
5
#define SBIT(x,y)       SBIT_(x,y)
6

7
#define  PORT_A0    SBIT( PORTA, 0 )
8
// code:
9
  if( PORT_A0 == 1 )
10
    PORT_A0 = 0;
11
  else
12
    PORT_A0 = 1;
Gast #4507804
Lesenswert?
• ▲
▼
Andere Variante:
1
#define writeBit(port,bit,value) { if ((value)>0) (port) |= (1<<bit); else (port) &= ~(1<<bit); } 
2

3
#define readBit(port,bit) (((port) >> (bit)) & 1)
4

5
if ( readBit(PINA,4) )
6
{
7
    writeBit(PORTB,6,1);
8
}
9
else
10
{
11
    writeBit(PORTB,6,0);
12
}

Wird vom Compiler ebenfalls perfekt optimiert. Diese Makros 
funktionieren auch mit Registern und Integer Variablen.

Aber sprechende Makros wie "LED_ON" und "LED_OFF" finde ich hilfreicher.
Gast #4507880
Lesenswert?
• ▲
▼
Ich denke es sind die Klammern in
1
#define PORT_AKKU (PORTB,PB4)  // Globale Vorgabe

Denn das ergibt ein
1
AUSGANG_SET_HIGH ((PORTB,PB4))

Der Präprozessor macht an dieser Stelle stumpf eine Textersetzung.
#4507906
Lesenswert?
• ▲
▼
__Son´s B. schrieb:
> #define BATT_ON (AUSGANG_SET_HIGH (PORT_AKKU))  // statt (PORTB,PB4)
> #define BATT_OFF (AUSGANG_SET_LOW (PORT_AKKU))  // statt (PORTB,PB4)
> ...
>
> Compiler meckert!
> Ist es nicht möglich, mehr als 1 Wert gleichzeitig zu übergeben?

Ist ja auch logisch. Das Leerzeichen in "(AUSGANG_SET_HIGH (PORT_AKKU))" 
wird nicht als Leerzeichen erkannt sondern als Delimiter, also Trenner 
von Argumenten. ;)
OP #4534915
Lesenswert?
• ▲
▼
Hallo - komme jetzt erst zum Weitermachen...

Habe immer noch das Problem, dass ich es nicht schaffe Macros zu 
verschachteln.

Ich würde gerne aus;
#define AUSGANG_SET_HIGH(port,mask) ((port) |= (1<<mask))
#define BATT_ON (AUSGANG_SET_HIGH(PORTA,PA4))
(Funktioniert einwandfrei!)

solche Parametrierung machen;
#define AUSGANG_SET_HIGH(port,mask) ((port) |= (1<<mask))
#define PORT_BATT_OUT(PORTA,PA4)
#define BATT_ON (AUSGANG_SET_HIGH(PORT_BATT_OUT))
Compiler meckert.

Obwohl nach meine Verständnis folgender Ersatz raus kommen sollte;
#define BATT_ON (AUSGANG_SET_HIGH((PORTA,PA4)))

Syntaxfehler?
Gast #4534932
Lesenswert?
• ▲
▼
> #define PORT_BATT_OUT(PORTA,PA4)

Das ist ein Syntaxfehler. Du definierst hier ein Makro mit zwei 
Parametern, aber dahinter steht nicht, durch welchen Text PORT_BATT_OUT 
sersetzt werden soll.

Versuche es mal mit

#define PORT_BATT_OUT (PORTA,PA4)

Also mit Leerzeichen vor der geöffneten Klammer

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren