Hallo, ich versuche zu überprüfen, ob alle gennanten 9 Pins an einem AVR auf High sind. Leider ist wohl etwas an meiner Syntax falsch, ich bekomme nur nicht raus was es ist. Könnt ihr mir evtl. weiterhelfen? if (((PINC & (1<<PINC4)) && (PINC & (1<<PINC5)) && (PINC & (1<<PINC6)) && (PINC & (1<<PINC7)) && ((PIND & (1<<PIND4)) && ((PIND & (1<<PIND5)) && ((PIND & (1<<PIND6)) && ((PIND & (1<<PIND7)) && ((PINA & (1<<PINA4))) {Anweisung;}
Passt soweit. Was passiert denn? Sind die Pins WIRKLICH alle HIGH?
Ah habs es hinbekommen. Irgendwie bin ich mit den Klammern durcheinandergekommen. Dem Compiler fehlte da was :-(
Hi, vielleicht zum debuggen die Ports separieren und einzeln die PINx werte zur Fehlersuche binaer/hex ausgeben. Dann bieten sich zur beseren Lesbarkeit auch noch Masken an. //hufnala
@Johannes (Gast) >Ah habs es hinbekommen. Irgendwie bin ich mit den Klammern >durcheinandergekommen. Dem Compiler fehlte da was :-( Das hätte man ja wohl sagen können und die Fehlermeldung hier posten! Siehe Netiquette!!
Wenn man das vernünftig (und lesbar) formatiert sieht man recht schnell, wo es hakt ...
1 | if ( ((PINC & (1<<PINC4)) && (PINC & (1<<PINC5)) && (PINC & (1<<PINC6)) && |
2 | (PINC & (1<<PINC7)) && ((PIND & (1<<PIND4)) && ((PIND & (1<<PIND5)) && |
3 | ((PIND & (1<<PIND6)) && ((PIND & (1<<PIND7)) && ((PINA & (1<<PINA4)) ) |
4 | |
5 | {Anweisung;} |
Wenn man das ganze so schreibt:
1 | if ( (PINC & ((1<<PINC4)|(1<<PINC5)|(1<<PINC6)|(1<<PINC7)) ) && |
2 | (PIND & ((1<<PIND4)|(1<<PIND5)|(1<<PIND6)|(1<<PIND7)) ) && |
3 | (PINA & ((1<<PINA4)) |
4 | ) { |
5 | Anweisung; |
6 | }
|
dann ist klarer, was man eigentlich vor hat. Zudem sind PINx als volatile deklariert, d.h. der Compiler müßte jede Benutzung mit einem Zugriff umsetzen. Die Varante mit Maske, siehe hier, nur einmal je PINx. Ich nehme mal an, daß Feinheiten im Einlese-Timing hier nicht interessant sind, da ja die exakte Reihenfolge der "Vergleiche" eh nicht bestimmbar ist.
:
Bearbeitet durch User
Carl D. schrieb: > da ja die exakte Reihenfolge der "Vergleiche" eh nicht bestimmbar ist. Doch, die Reihenfolge ist gegeben, da && und || in C einen Sequence Point darstellen. Hier
1 | if((a == b) && (c == d)) {} |
wird der Vergleich a == b vor c == d ausgeführt und wenn der erste Vergleich falsch ist, der zweite nicht ausgeführt. Das kann man z.B. für folgendes Verwenden:
1 | if((x != NULL) && (*x == 123)) {} |
So ist sichergestellt, dass, falls x gleich NULL ist, der Zeiger nicht dereferenziert wird. Edit: Ansonsten gebe ich dir zu 100% Recht, es ist übersichtlicher und man läuft nicht in die Gefahr, dass der Port zwischen den einzenlen Vergleichen den Zustand wechselt. Je nach Anwendung ist das aber auch egal.
:
Bearbeitet durch User
be s. schrieb: > Das kann man z.B. für folgendes Verwenden: >
1 | if((x != NULL) && (*x == 123)) {} |
> So ist sichergestellt, dass, falls x gleich NULL ist, der Zeiger nicht > dereferenziert wird. Das stimmt! Die "Einzelbit-Abfrage" sollte wegen den volatilen PINs auch zu deutlich mehr Code führen. Im konkreten Fall 9 PIN Zugriffe statt 3 bei "gruppiert". War aber bisher zu faul den GCC anzuwerfen, um das genauer zu untersuchen.
Carl D. schrieb: > Wenn man das ganze so schreibt: >
1 | > if ( (PINC & ((1<<PINC4)|(1<<PINC5)|(1<<PINC6)|(1<<PINC7)) ) && |
2 | > (PIND & ((1<<PIND4)|(1<<PIND5)|(1<<PIND6)|(1<<PIND7)) ) && |
3 | > (PINA & ((1<<PINA4)) |
4 | > ) { |
5 | > Anweisung; |
6 | > } |
das wird so für den gewünschten Zweck nicht funktionieren, denn das Ergebnis der UND-Verknüpfung zwichen PINx und Maske ist immer dann ungleich Null wenn eines der Bits in der Maske HIGH ist. Es müsste dann:
1 | (PINC & ((1<<PINC4)|(1<<PINC5)|(1<<PINC6)|(1<<PINC7)))==((1<<PINC4)|(1<<PINC5)|(1<<PINC6)|(1<<PINC7)) |
so aussehen Sascha
Stimmt auch wieder. Dann aber am besten so:
1 | #define MASK_A ((1<<PINC4))
|
2 | #define MASK_C ((1<<PINC4)|(1<<PINC5)|(1<<PINC6)|(1<<PINC7))
|
3 | #define MASK_D ((1<<PIND4)|(1<<PIND5)|(1<<PIND6)|(1<<PIND7))
|
4 | |
5 | if( ((PINA & MASK_A) == MASK_A) && |
6 | ((PINC & MASK_C) == MASK_C) && |
7 | ((PIND & MASK_D) == MASK_D) ) |
8 | {
|
9 | // ...
|
10 | }
|
Damit sind bei Bedarf nur die Defines anzupassen. Und wer will und entsprechende Compilerunterstützung hat, darf sie auch als
1 | static const uint8_t MASK_x = ... |
schreiben.
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.