XMega-Bit-Manipulation: Einlesen mehrerer Pins gleichzeitig

Gast #4247813
Lesenswert?
• ▲
▼
Hallo,

ich möchte eigentlich nur prüfen, ob zwei Pins (gleichzeitig) high oder 
low sind, aber ich verstehe diese Bit-Schreibweise einfach nicht 
ausreichend und verzweifle langsam.

Gibt es eine Schreibweise wie diese hier,
1
if (PORTA.IN & (PIN0_bm | PIN1_bm)) {}
mit der ich prüfen kann, ob Pin0 und Pin1 gesetzt sind?

Und um es etwas schwieriger zu machen, gibt es eine solche Schreibweise 
auch, um zu prüfen, ob beide Pins gleichzeitig nicht gesetzt sind?

Ich könnte natürlich auch das IN-Register mit einer Zahl vergleichen, 
aber das finde ich schwer zu lesen und nicht elegant. Zudem müsste ich 
wahrscheinlich viel rum-odern, um die nicht betroffenen Pins zu 
ignorieren, was mein Lesbarkeitsproblem noch intensivieren würde...


Danke

Peder
#4247832
Lesenswert?
• ▲
▼
@ Peder (Gast)

>ich möchte eigentlich nur prüfen, ob zwei Pins (gleichzeitig) high oder
>low sind, aber ich verstehe diese Bit-Schreibweise einfach nicht
>ausreichend und verzweifle langsam.

Siehe Bitmanipulation

>if (PORTA.IN & (PIN0_bm | PIN1_bm)) {}

>mit der ich prüfen kann, ob Pin0 und Pin1 gesetzt sind?

Nein, das prüft, ob Pin0 ODER Pin1 gesetzt sind.

>Und um es etwas schwieriger zu machen, gibt es eine solche Schreibweise
>auch, um zu prüfen, ob beide Pins gleichzeitig nicht gesetzt sind?

!(PORTA.IN & (PIN0_bm | PIN1_bm))

Siehe oben.
Gast #4248006
Lesenswert?
• ▲
▼
Danke für die "Nicht-Und"-Lösung. Die scheint zu funktionieren.

Falk B. schrieb:
> Nein, das prüft, ob Pin0 ODER Pin1 gesetzt sind.

Wahrscheinlich war die Satzkonstruktion hier etwas unglücklich. Ich 
meinte, ob es analog zu meinem Beispiel, das eine Oder-Prüfung vornimmt, 
eine Schreibweise gibt, die eine Und-Prüfung vornimmt.
Zwar funktioniert folgendes:
1
if ((PORTA.IN & 0b00000011) == 0b00000011) {}
Mir gefiele aber eine Schreibweise mit PIN0_bm und PIN1_bm mehr. Gibt es 
da eine?
#4248017
Lesenswert?
• ▲
▼
Peder schrieb:

>
1
if ((PORTA.IN & 0b00000011) == 0b00000011) {}
> Mir gefiele aber eine Schreibweise mit PIN0_bm und PIN1_bm mehr. Gibt es
> da eine?

sicher.

0b00000011 ersetzt du an allen vorkommenden Stellen durch deine 
Schreibweise mit PIN0_bm | PIN1_bm

Wichtig: an ALLEN vorkommenden Stellen.

Es reicht dann eben nicht mehr, wenn nach der Verundung etwas ungleich 0 
rauskommt, sondern es muss eben genau rauskommen, dass PIN0 und Pin1 
gesetzt sind.
1
if ( (PORTA.IN & (PIN0_bm | PIN1_bm)) == (PIN0_bm | PIN1_bm) ) {}

was dich wahrscheinlich ins Boxhorn getrieben hat, das ist die Operator 
Precedence (also die Vorrangregeln für Operatoren wie zb & | oder auch 
==). Wenn man die nicht komplett auswendig kennt (und wer kennt schon 
alle), dann setzt man eben Klammern.

Kann natürlich auch sein, dass dein eigentliches Problem darin besteht, 
dass dir nicht klar ist, was die Binäroperationen eigentlich machen und 
was uns das Ergebnis so einer Binäroperation alles erzählt.

Wenn man einfach nur auswendig gelernt hat, dass ein Pin so abgefragt 
wird
1
    if( PORTA.IN & PinMask )
und sich nie überlegt hat, warum man da eigentlich ein & schreibt, was 
das macht und was das Ergebnis davon ist, bzw. einem nicht klar ist, wie 
ein if funktioniert, dann steht man eben da wie der Ochs vorm Tor.
Gast #4248065
Lesenswert?
• ▲
▼
Das Problem ist wahrscheinlich, dass ich diese Bit-Operationen nur 
einmal alle paar Monate brauche. Und irgendwann kopiert man natürlich 
die Zeile für so einfache Abfragen, so dass man das irgendwann nicht 
mehr kann. Und alles, was sich dann IM Controller abspielt, fragt meiner 
Erfahrung nach immer nur nach einem Wert aus den Registern ab (z.B. 
diverse Status-Register). Ich hatte noch nie den Fall, dass zwei Werte 
aus einem Register gebraucht werden.

Dazu kommt noch, dass ich zwar "mathematisch" nachvollziehen kann, was 
diese Operationen machen, aber in die andere Richtung fällt es mir 
schwer. Sprich, ich kann kompliziertere Ausdrücke nicht so ohne weiteres 
herleiten, verstehe sie aber, wenn ich sie lese.


Habt Dank!

Antwort schreiben

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.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.