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.
Ich verwende gerne Ausdrücke in der Form:
1 | #define SET_GREEN (P1OUT |= (0x01)) // P1.0 high
|
2 | #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.
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.
Funktionen sind trotzdem besser! Vor allem für einen Neuling!
Mich würde auch interessieren, welcher Code für jeden 'Aufruf' erzeugt wird. Kannst Du mal den passenden Ausschnitt aus der *.lst Datei zeigen?
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:
1 | #define GREEN_H (P1OUT |= (0x01))
|
2 | #define GREEN_L (P1OUT &= ~(0x01))
|
3 | #define RED_H (P1OUT |= (0x04))
|
4 | #define RED_L (P1OUT &= ~(0x04))
|
5 | |
6 | #define SET_GREEN {GREEN_H; RED_L;}
|
7 | #define SET_RED {RED_H; GREEN_L;}
|
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.