Hallo liebe Leute
Vorab: Ich benutze einen MSP430.
Ich habe eine Frage, und zwar möchte ich zu Beginn meines Programms
mehrere #define-Anweisungen festlegen, um mir Schreibarbeit zu sparen.
#define IN P1IN // Port 1 Eingang
#define TASTER 0x20 // P1.5
#define GRUEN1 0x01 // P1.0
#define GRUEN2 0x02 // P1.1
#define ROT1 0x40 // P2.6
#define ROT2 0x80 // P2.7
#define GRUEN_1 ((P2OUT &= ~(ROT1 + ROT2)) && (P1OUT &= ~GRUEN2) &&
(P1OUT |= GRUEN1))
#define ROT_1 ((P1OUT &= ~(GRUEN1 + GRUEN2)) && (P2OUT &= ~ROT2) &&
(P2OUT |= ROT2))
#define GRUEN_2 ((P2OUT &= ~(ROT1 + ROT2)) && (P1OUT &= ~GRUEN1) &&
(P1OUT |= GRUEN2))
#define ROT_2 ((P1OUT &= ~(GRUEN1 + GRUEN2)) && (P2OUT &= ~ROT1) &&
(P2OUT |= ROT1))
Wenn ich jetzt irgendwo im Text "GRUEN_1" eingebe, dann soll nur die
eine LED an P1.0 leuchten und die anderen an P1.2, P2.6 und P2.7 eben
nicht.
Mein Problem liegt in der Verknüpfung der einzelnen Ausdrücke. Gebe ich,
wie hier jetzt das "&&" ein, so funktioniert es garnicht. Wenn ich die
"&&"s durch "&" oder durch "+" ersetze, dann funktioniert es, aber es
kommen Warnungen mit 'undefined behaviour...'.
Wie ist die syntaktische Verknüpfung der einzelnen Ausdrücke? KAnn mir
da jemand helfen?
Danke schonmal!
> um mir Schreibarbeit zu sparen.
Dann schreibe Dir am besten kleine Funktionen, die Jeder und vor allem
auch Du selbst verstehen kann. Dann kannst Du auch ausschließen, dass
die anderen Pins der Ports 1+2 korrekt behandelt werden.
Korrektur:
... ausschließen, dass sie nicht korrekt behandelt werden.
Die anderen Pins sollten ja unverändert in ihrem Zustand und ihrer
Funktion bleiben.
Harald schrieb:> #define GRUEN_1 ((P2OUT &= ~(ROT1 + ROT2)) && (P1OUT &= ~GRUEN2) &&> (P1OUT |= GRUEN1))
Funktionen sind zwar übersichtlicher, aber wenn schon, dann:
1
#define GRUEN_1() do{ P2OUT &= ~(ROT1 + ROT2); \
2
P1OUT &= ~GRUEN2; \
3
P1OUT |= GRUEN1; }while(0)
Diese sinnlos wirkende do{...}while(0) Konstruktion statt einfachem
{...} vermeidet Probleme, die sonst bei funktionsartiger Verwendung mit
einem abschliessenden ; entstehen können, denn bei
if (...) GRUEN_1(); else ...
liefert
if (...) {...}; else ...
einen Syntaxfehler,
if (...) do{...}while(0); else ...
jedoch nicht.
Ja, das habe ich bis jetzt auch gemacht, jedoch muss ich dann an jeder
Stelle die entsprechenden LEDs einzeln an und ausschalten. Das ist halt
jedesmal mehr Text. Ein #define wäre da handlicher.
A. K. schrieb:> Funktionen sind zwar übersichtlicher, aber wenn schon, dann:> #define GRUEN_1() do{ P2OUT &= ~(ROT1 + ROT2); \> P1OUT &= ~GRUEN2; \> P1OUT |= GRUEN1; }while(0)
Hey, super, das funktioniert gut! Danke, Kannst du mir noch verraten,
was das "\" zwischen den einzelnen Anweisungen bewirkt?
Danke!
Harald schrieb:> Hey, super, das funktioniert gut! Danke, Kannst du mir noch verraten,> was das "\" zwischen den einzelnen Anweisungen bewirkt?
Präprozessoranweisungen sind normalerweise nur eine Zeile lang. So
lassen sie sich verlängern.
Man könnte auch den Teil der Sprache nutzen, der dafür gedacht ist,
logische und syntaktische Verknüpfungen auszudrücken und Schreibarbeit
zu sparen, nämlich C-Funktionen statt den Präprozessor.
Eine LED-"API" a la set_leds(GREEN1_ONLY, ON) ist für jeden
verständlich, sie funktioniert immer fehlerfrei ohne while(0)-Gebastel
und ist effizient genug für Geblinke und Tastendrücke (und alles andere
wahrscheinlich auch).
EDIT: Karl heinz war schneller.
Thorsten M... schrieb:> Man könnte auch den Teil der Sprache nutzen, der dafür gedacht ist,> logische und syntaktische Verknüpfungen auszudrücken und Schreibarbeit> zu sparen, nämlich C-Funktionen statt den Präprozessor.>> Eine LED-"API" a la set_leds(GREEN1_ONLY, ON) ist für jeden> verständlich, sie funktioniert immer fehlerfrei ohne while(0)-Gebastel> und ist effizient genug für Geblinke und Tastendrücke (und alles andere> wahrscheinlich auch).
Ich finde:
Für eine einzelne LED ist ein Makro noch ok (obwohl man auch da
debattieren kann).
Aber spätestens dann, wenn mehrere Statements in einem Makro verpackt
werden sollen, fährt man mit einer Funktion immer besser.
Diese Makro Lösungen, mit dem do ... while( 0 ) Hack stammen im Grunde
alle noch aus einer Zeit, als inlinen mit einem Compiler Glückssache
war. Und ja, solche Makro-Lösungen fallen einem des öfteren schon auch
mal nach längerer Zeit auf den Schädel. Denn irgendwelche Nebenwirkungen
gibt es meistens.
>Und ja, solche Makro-Lösungen fallen einem des öfteren schon auch>mal nach längerer Zeit auf den Schädel.
Wie wahr, wie wahr!
Auch ich bin schreibfaul, aber wichtiger ist es, dass man ein Programm
schnell lesen und begreifen kann. Meister des Faches schreiben ein
Programm in eine einzige Zeile. Nur wozu soll das gut sein?
Was A.K. vorgeschlagen hat, ist ja letzlich der Rumpf einer Funktion.
Moderne Compiler optimieren derart, dass sie kleine oder einmalige
Funktionen inline einfügen, ohne das man irgendwie tricksen müßte.
Harald schrieb:>#define SET_GREEN (P1OUT |= (0x01)) // P1.0 high>#define RESET_GREEN (P1OUT &= ~(0x01)) // P1.0 low> Ja, das habe ich bis jetzt auch gemacht, jedoch muss ich dann an jeder> Stelle die entsprechenden LEDs einzeln an und ausschalten. Das ist halt> jedesmal mehr Text. Ein #define wäre da handlicher.
Ist doch auch kein Problem: