Forum: Mikrocontroller und Digitale Elektronik Präprozessor-Makro >>> Textersatz


von __Son´s B. (bersison)


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?

von Peter M. (Gast)


Lesenswert?

__Son´s B. schrieb:
> AUSGANG_SET_HIGH (PORT_AKKU)

Überlege doch einmal, was der Präprozessor daraus macht?

Und wo ist AUSGANG_SET_HIGH definiert?

Setze einmal den Compilerschalter, dass er nur den Präprozessor 
ausführt.
Dann schaue Dir das Ergebnis an......

von Falk B. (falk)


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.

von __Son´s B. (bersison)


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?

von Peter D. (peda)


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;

von __Son´s B. (bersison)


Lesenswert?

Vielen Dank für deine Info!

von Stefan F. (Gast)


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.

von fop (Gast)


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.

von M. K. (sylaina)


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. ;)

von __Son´s B. (bersison)


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?

von Stefan F. (Gast)


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

von __Son´s B. (bersison)


Lesenswert?

Stefan U. schrieb:
> #define PORT_BATT_OUT (PORTA,PA4)
>
> Also mit Leerzeichen vor der geöffneten Klammer

Compiler meckert genau so.

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.