Forum: Mikrocontroller und Digitale Elektronik geschachtelte if Abfrage auf AVR Pins


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Johannes (Gast)


Bewertung
0 lesenswert
nicht lesenswert
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;}

von Falk B. (falk)


Bewertung
0 lesenswert
nicht lesenswert
Passt soweit. Was passiert denn? Sind die Pins WIRKLICH alle HIGH?

von Johannes (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Ah habs es hinbekommen. Irgendwie bin ich mit den Klammern 
durcheinandergekommen. Dem Compiler fehlte da was :-(

von hufnala (Gast)


Bewertung
0 lesenswert
nicht lesenswert
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

von Falk B. (falk)


Bewertung
0 lesenswert
nicht lesenswert
@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!!

von Dieter F. (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Wenn man das vernünftig (und lesbar) formatiert sieht man recht schnell, 
wo es hakt ...

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;}


von Carl D. (jcw2)


Bewertung
0 lesenswert
nicht lesenswert
Wenn man das ganze so schreibt:
if ( (PINC & ((1<<PINC4)|(1<<PINC5)|(1<<PINC6)|(1<<PINC7)) ) &&
     (PIND & ((1<<PIND4)|(1<<PIND5)|(1<<PIND6)|(1<<PIND7)) ) && 
     (PINA & ((1<<PINA4))    
   ) {
       Anweisung;
     } 
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
von B. S. (bestucki)


Bewertung
0 lesenswert
nicht lesenswert
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
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:
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
von Carl D. (jcw2)


Bewertung
0 lesenswert
nicht lesenswert
be s. schrieb:
> Das kann man z.B. für folgendes Verwenden:
>
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.

von Sascha W. (sascha-w)


Bewertung
0 lesenswert
nicht lesenswert
Carl D. schrieb:
> Wenn man das ganze so schreibt:
>
> if ( (PINC & ((1<<PINC4)|(1<<PINC5)|(1<<PINC6)|(1<<PINC7)) ) &&
>      (PIND & ((1<<PIND4)|(1<<PIND5)|(1<<PIND6)|(1<<PIND7)) ) &&
>      (PINA & ((1<<PINA4))
>    ) {
>        Anweisung;
>      } 
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:
(PINC & ((1<<PINC4)|(1<<PINC5)|(1<<PINC6)|(1<<PINC7)))==((1<<PINC4)|(1<<PINC5)|(1<<PINC6)|(1<<PINC7))
so aussehen

Sascha

von Carl D. (jcw2)


Bewertung
0 lesenswert
nicht lesenswert
Stimmt auch wieder.
Dann aber am besten so:
#define MASK_A       ((1<<PINC4))
#define MASK_C       ((1<<PINC4)|(1<<PINC5)|(1<<PINC6)|(1<<PINC7))
#define MASK_D       ((1<<PIND4)|(1<<PIND5)|(1<<PIND6)|(1<<PIND7))

if( ((PINA & MASK_A) == MASK_A) &&
    ((PINC & MASK_C) == MASK_C) &&
    ((PIND & MASK_D) == MASK_D) )
{
   // ...
}
Damit sind bei Bedarf nur die Defines anzupassen. Und wer will und 
entsprechende Compilerunterstützung hat, darf sie auch als
static const uint8_t MASK_x = ...
schreiben.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.