Forum: Mikrocontroller und Digitale Elektronik Präprozessordirektiven


von Thomas Frosch (Gast)


Lesenswert?

Hi,

ich möchte mittels Präprozessordirektiven Ausgänge schalten und mir die 
Schreibarbeit wesentlich vereinfachen. Im Moment benutze ich diese 
defines.
1
#define CLEAR_LED       (PORTD &= ~_BV(PD4))
2
#define SET_LED       (PORTD |=  _BV(PD4))
3
#define TOGGLE_LED       (PORTD ^=  _BV(PD4))
4
#define Z_LED         (PORTD &   _BV(PD4))
5
#define OUT_LED        (DDRD  |=  _BV(PD4))

Nun möchte ich z.B. sowas machen
1
#define AUSGANG1 PORTD,PD7
2
#define TOGGLE(x,y) (#x ^= _BV(#y))
3
4
int main(void)
5
{
6
    DDRD  |=  _BV(PD7);
7
    TOGGLE(AUSGANG1);
8
}

Das geht jedoch leider nicht. Noch schöner wäre natürlich wenn ich die 
defines wie oben so .... verwenden könnte (????xxxx???? soll dabei ein 
Platzhalter für die Anweisung sein die ich gerne wissen möchte, falls 
das überhaupt möglich ist!)
1
#define AUSGANG1   ????xxxx????
2
#define AUSGANG2   ????xxxx????
3
#define AUSGANG3   ????xxxx????
4
5
#define TOGGLE(x)  ????xxxx????
6
#define OUT(x)     ????xxxx????
7
#define SET(x)     ????xxxx????
8
...
9
10
int main(void)
11
{
12
    OUT(AUSGANG1);
13
    OUT(AUSGANG2);
14
15
    TOGGLE(AUSGANG1);
16
    SET(AUSGANG3);
17
}

Das heißt bei Ausgang müsste irgendwie sowas wie PD7 angegeben werden, 
und die funktionen weiter unten müssten das D und die 7 extrahieren und 
dementsprechend in die defines ganz oben einsetzen!

Ist das irgendwie möglich???

von Ratgeber Technik (Gast)


Lesenswert?

hier mal was als Ansatz:

#define CLRBIT(PORT,NR)      (PORT &= ~(1<<NR))
#define SETBIT(PORT,NR)      (PORT |=  (1<<NR))

#define LED_GRUEN_AUS()    SETBIT(PORTA,PA3)
#define LED_GRUEN_EIN()    CLRBIT(PORTA,PA3)

von Thomas Frosch (Gast)


Lesenswert?

Hmm ok...

Mir geht es eigentlich darum nur noch in einer Zeile den Ausgang zu 
definieren. Also zum Beispiel #define AUSGANG1 PD7 und in 5 weiteren 
Zeilen die dann für alle anderen Ausgänge gelten die Funktionen zu 
AUSGANG1 zu definieren.

#define CLEAR
#define SET
#define TOGGLE
#define Z
#define OUT


_________________

Mir geht es darum die redundanzen die in

#define CLEAR_LED       (PORTD &= ~_BV(PD4))
#define SET_LED       (PORTD |=  _BV(PD4))
#define TOGGLE_LED       (PORTD ^=  _BV(PD4))
#define Z_LED         (PORTD &   _BV(PD4))
#define OUT_LED        (DDRD  |=  _BV(PD4))

sind herauszunehmen. Also 4xPORTD 5xPD4 und 1x DDRD (die Ausgänge 
unterscheiden sich immer nur in der Zahl hier 4 und dem Buchstaben hier 
D)

Im moment muss ich für jeden Ausgang diese 5 Zeilen einfügen. Ich möchte 
aber für jeden weiteren Ausgang immer nur eine Zeile hinzufügen.

von (prx) A. K. (prx)


Lesenswert?

Strings zerlegen geht mit dem C Präprozessor nicht. Da müsste man schon 
auf andere ausweichen, wie etwa den M4.

Was aber geht:
1
#define GLUE(a, b) a##b
2
#define PORT(x)    GLUE(PORT, x)
3
#define PIN(x)     GLUE(PIN, x)
4
#define DDR(x)     GLUE(DDR, x)
und dann
1
#define LCD_LP_PORT  D
2
#define LCD_LP_PIN  (1<<PD6)
3
4
DDR(LCD_LP_PORT) |= LCD_LP_PIN;

von chris (Gast)


Lesenswert?

doch, das geht, du brauchst aber eine Ebene mehr.

z.B
#define TOGGLE_(x,y) ((x)^=1<<(y))
#define TOGGLE(x)  TOGGLE_(x)

Mit
#define LED_RED  PortA,3

wird dann TOGGLE(LED_RED) zu
TOGGLE_(PortA,3) was dann richtigerweise zu ((PortA)^=1<<(3)) gemacht 
wird.

von (prx) A. K. (prx)


Lesenswert?

Das wird aber erst dann wirklich sinnvoll, wenn du mit
  #define LED_RED A,3
arbeiten und den Präfix PIN/PORT/DDR über die skizzierte GLUE() Methode 
anfügen kannst. Sonst braucht jedes Register eine Extrawurst.

von Thomas Frosch (Gast)


Lesenswert?

Das sieht doch schonmal sehr gut aus. Die zweite Ebene ist zwar zuerst 
etwas seltsam aber macht dann schon irgendwie Sinn.

Gibt es nun noch irgendwie die Möglichkeit es mit dem PIN und DDR 
hinzubekommen?

Ansonsten erweitere ich mein define einfach mit mehr parametern und die 
jeweilige funktion pickt sich eben die benötigte raus so wie
#define AUSGANG1 PORTA,PINA,DDRA,2

Aber schonmal vielen vielen Dank, dass wird mir in Zukunft viel Zeit 
sparen!!

von chris (Gast)


Lesenswert?

Ja, geht auch problemlos, nur da braucht es auch weitere Stufen, für
jede ## eine. 4-5 Stufen sind nicht so ungewöhnlich.

von Thomas Frosch (Gast)


Lesenswert?

Super!!! Vielen Dank. Habe es nun so gelöst:
1
#define PORT_(x)      PORT ##x
2
#define  DDR_(x)       DDR ##x
3
#define  PIN_(x)       PIN ##x
4
5
#define TOGGLE_(x,y)    ((PORT_(x)) ^=  (1<<(y)))
6
#define CLEAR_(x,y)     ((PORT_(x)) &= ~(1<<(y)))
7
#define SET_(x,y)      ((PORT_(x)) |=  (1<<(y)))    
8
#define Z_(x,y)       ((PORT_(x)) &   (1<<(y)))    
9
#define OUT_(x,y)      (( DDR_(x)) |=  (1<<(y)))    
10
#define IN_(x,y)      ((PORT_(x)) |=  (1<<(y)))
11
#define P_(x,y)        (( PIN_(x)) &   (1<<(y)))
12
13
#define TOGGLE(x)       TOGGLE_(x)
14
#define CLEAR(x)       CLEAR_(x)
15
#define SET(x)         SET_(x)
16
#define Z(x)         Z_(x)
17
#define OUT(x)         OUT_(x)
18
#define IN(x)         IN_(x)
19
#define P(x)         P_(x)
20
21
#define LED         B,0
22
#define IR_LED        B,1
23
#define IR_REC        D,2

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.