Forum: Compiler & IDEs Macro einer Funktion übergeben


von Thomas U. (morrie)


Lesenswert?

Hallo,
eigentlich dachte ich dass es einfach ist was ich machen will, aber ich 
konnte nichts dazu finden und bei den Macros bin ich dann irgendwann 
ausgestiegen.

Jetzt erst mal was ich machen will: Ich programmiere ein Programm, in 
dem ich sehr viel mit Ein- und Ausgängen arbeite. Der Übersichtlichkeit 
halber möchte ich alle Ein- und Ausgänge in einer Header File 
definieren:

#define Port_Eingang1 PORTA
#define Pin_Eingang1  4
.....

Jetzt benötige ich für jeden der Eingänge mehrere Funktionen, und die 
würde ich gerne so übergeben:

Warte_Auf_Pin_high(Port, PortNr)
Warte_Auf_Pin_low(Port, PortNr)
Warte_Auf_Pin_change(Port, PortNr)

Selbes gibt auch für die Ausgänge:

Setze_Pin_0(Port,PortNr)
Setze_Pin_1(Port,PortNr)
Setze_Pin_change(Port,PortNr)

Im Programm würde ich das ganze so aufrufen:
Warte_Auf_Pin_high(Port_Eingang1, Pin_Eingang1)

So wie ich das ganze verstanden habe ist ja bereits PORTA ein Macro dass 
ich der Funktion dann übergeben müsste. Mir ist es aber nicht gelungen. 
Das kann doch nicht so schwer sein.

Oder gibt es einen einfacheren Weg das ganze zu lösen.

Gruß,

Thomas

von K. D. (deka)


Lesenswert?

Wie stellst du dir das denn vor? #define ist eine Textersetzung . 
Natürlich funktioniert das nicht:

Thomas U. schrieb:
> #define Port_Eingang1 PORTA
> #define Pin_Eingang1  4


> Warte_Auf_Pin_high(Port_Eingang1, Pin_Eingang1)

daraus macht der Präprozessor

Warte_Auf_Pin_high(PORTA, 4)

Die 4 ist ok, aber was für ein Datentyp soll PORTA sein?

Das ist kein C. Das ist kein Programmieren. Kauf dir ein C Handbuch und 
lerne C ...

von Karl H. (kbuchegg)


Lesenswert?

Thomas U. schrieb:

> Jetzt benötige ich für jeden der Eingänge mehrere Funktionen, und die
> würde ich gerne so übergeben:
>
> Warte_Auf_Pin_high(Port, PortNr)
> Warte_Auf_Pin_low(Port, PortNr)
> Warte_Auf_Pin_change(Port, PortNr)

Die ganze Thematik mit Warten ist höchst wahrscheinlich schon der 
falsche Ansatz. Warten ist gaaaaaanz schlecht.

> Setze_Pin_0(Port,PortNr)
> Setze_Pin_1(Port,PortNr)
> Setze_Pin_change(Port,PortNr)
>
> Im Programm würde ich das ganze so aufrufen:
> Warte_Auf_Pin_high(Port_Eingang1, Pin_Eingang1)

An dieser Stelle sind Funktionen keine gute Idee.
Man kann sie machen.
1
void Setze_Pin( volatile uint8_t* port, uint8_t pin )
2
{
3
  *port |= (1 << pin);
4
}
aber eigentlich möchte man das nicht. Denn damit raubt man dem Compiler 
oft jegliche Möglichkeit zu optimieren und anstelle der aufwändigen 
Oder-Operation die Bitoperationen einzusetzen.

Derartige Dinge werden sinnigerweise nicht als Funktionen, sondern 
ihrerseits wieder als Makros ausgeführt
1
#define SET_BIT(p,b)  ((p) |= (1<<(b))

von Karl H. (kbuchegg)


Lesenswert?

K. D. schrieb:

> Warte_Auf_Pin_high(PORTA, 4)
>
> Die 4 ist ok, aber was für ein Datentyp soll PORTA sein?

PORTA ist seinerseit auch wieder ein Makro.
Eine Speicheradresse, die auf einen volatile uint8_t Pointer gecastet 
wird.

von Andreas B. (andreas_b77)


Lesenswert?

Karl Heinz Buchegger schrieb:
> Derartige Dinge werden sinnigerweise nicht als Funktionen, sondern
> ihrerseits wieder als Makros ausgeführt

Also sinnigerweise sollte man da static inline Funktionen in den 
Header schreiben. Das ist im Endergebnis genauso schnell, bietet aber 
die Datentyp-Prüfungen wie jeder andere Funktionsaufruf, ist im 
Allgemeinen besser lesbar als eine Makrodefinition mit all den 
notwendigen Klammerungen und hat vor allem keine unvorhergesehenen 
Nebeneffekte.

von Thomas U. (morrie)


Lesenswert?

Dass warten mit dem Mikrocontroller nicht gut ist, weiß ich. In meinem 
Fall ist es aber so, dass ich auf beliebige Änderungen an den Eingängen 
reagiere und dann dazu Ausgänge schalte. In der Zwischenzeit macht der 
Conroller nichts.

Danke für die Tips, ich werde das ganze heute Abend mal testen.

Gruß,

Thomas

von Rosa-Kleidchen (Gast)


Lesenswert?

Ja, und vergiss nicht, ein C-Buch zu lesen, das hier immer wieder 
Schlaukoeppe einwerfen.
Rosa

von Andreas S. (Firma: Schweigstill IT) (schweigstill) Benutzerseite


Lesenswert?

Thomas U. schrieb:
> In meinem
> Fall ist es aber so, dass ich auf beliebige Änderungen an den Eingängen
> reagiere und dann dazu Ausgänge schalte. In der Zwischenzeit macht der
> Conroller nichts.

Doch, bei den von Dir gewünschten Funktionen 
(Warte_Auf_Pin_[high|low|change])
wartet der Prozessor auf Änderungen genau eines Pins. Dies lässt sich 
zwar kombinieren zu
1
if (Warte_Auf_Pin_high(Port_Eingang1, Pin_Eingang1) || Warte_Auf_Pin_high(Port_Eingang2, Pin_Eingang5))
2
{
3
   machwas();
4
}

aber der Ablauf ist ein ganz anderer als von Dir vielleicht intuitiv 
angenommen.

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.