Tasterabfrage - Frage zum Pinzustand?

OP #3377245
Lesenswert?

Hallo,

ich habe eine Frage zur Zeile:
1
if (!(PIND & (1<<PD2)))

Ich lese damit einen Taster am Pin D2 ein. Soweit so gut, aber wie 
funktioniert es genau? Kann mir jemand diese Zeile genau erklären?

Mit
1
DDRD &= (1<<PD2);

setze ich das Bit D2 zuvor auf Eingang.

Mein Taster ist mit einem Pull-Up Widerstand auf High geschaltet.
Ist der Taster offen, habe ich ein High am PD2.
Ist der Taster geschlossen, habe ich ein Low am PD2
Gast #3377266
Lesenswert?

m. g. schrieb:
> if (!(PIND & (1<<PD2)))

Mit PIND liest du den Zustand vom ganzen PortD ein.
Mit (1 << PD2) stellst du eine Maske für Bit2 bereit (0b00000100)
Mit (PIND & (1<<PD2)) maskierst du aus dem PortD-Zustand das Taster-Bit
Mit !... invertierst du das Ergebnis (aus "gleich 0" wird "ungleich 0")
Mit if (...) steuerst du deinen Programmablauf

Und in deinem C-Buch oder Tutorial steht ist das nicht unter dem Thema 
Bitmanipulationen beschrieben?
#3377276
Lesenswert?

m. g. schrieb:
> Hallo,
>
> ich habe eine Frage zur Zeile:
>
>
1
> if (!(PIND & (1<<PD2)))
2
>
>
> Ich lese damit einen Taster am Pin D2 ein. Soweit so gut, aber wie
> funktioniert es genau? Kann mir jemand diese Zeile genau erklären?

Ein ganz normaler binäres Und.

Es hat die Logik-tabelle
1
   A   B    Ergebnis
2
   0   0      0
3
   1   0      0
4
   0   1      0
5
   1   1      1

Das Ergebnis ist also nur dann eine 1, wenn sowohl A als auch B den Wert 
1 haben.

So weit so gut. Das gilt bei 1 Bit.
Jetzt hast du aber vom Port nicht 1 Bit, du kriegst vom Port 8 Stück 
davon.

Diese binäre Und-Operation wird auf alle 8 Bits gleichzeitig angewendet
1
   vom Port     01010011    (das ist die Komponente 'A', 8 mal)
2
   die Maske    00011000    (das ist die Komponente 'B', ebenfalls 8 mal)

und jetzt wendest du die Und-Operation auf alle 8 Spalten getrennt an. 
Jede Spalte für sich
1
   vom Port     01010011    (das ist die Komponente 'A', 8 mal)
2
   die Maske    00011000    (das ist die Komponente 'B', ebenfalls 8 mal)
3
                --------
4
                ||||||||
5
                vvvvvvvv
6

7
                00010000

Das ist interessant. Denn da ist nur eine einzige 1 übrig geblieben. 
Tatsächlich ist es so, wenn man sich die Logik Tabelle mal genau 
ansieht, dann ist das Ergebnis auf jeden Fall dort 0, wo in B eine 0 
auftaucht.
Genau das wird hier ausgenutzt. Wenn ich mal genau diese Spalten im 
Ergebnis markiere, dann steht da
1
   vom Port     01010011    (das ist die Komponente 'A', 8 mal)
2
   die Maske    00011000    (das ist die Komponente 'B', ebenfalls 8 mal)
3
                --------
4
                ||||||||
5
                vvvvvvvv
6

7
                zzz10zzz

d.h. alle mit z markierten Stellen sind im Ergebnis auf jeden Fall 0, 
egal, welcher Wert in der Komponente A war. Bei den beiden übrig 
gebliebenen Spalten, die nicht z sind, hängt es von A ab, ob da jetzt 
eine 1 oder eine 0 auftaucht.

Was du also gemacht hast, ist mit den 1 Bits in der Maske ein "Sieb" 
aufzuspannen, welches dir nur ganz bestimmte Bits aus dem Original 
durchlässt und alles andere gezielt auf 0 setzt.

In deinem Fall, 1<<PD2, lässt das Sieb nur eine einzige Spalte durch. 
Nämlich die an Bitposition 2.
1
      01010011
2
      00000100
3
     ----------
4
      zzzzz0zz

das ergebnis ist deswegen 0, weil im Original auch ein 0 Bit an dieser 
Position war.
bedenkt man jetzt, dass z ja eigentlich als 0 zu lesen ist, dann steht 
da
1
      01010011
2
      00000100
3
     ----------
4
      00000000

und das ist über alle Bits gesehen eine glatte dezimale 0

Wäre das Bit auf 1 gewesen
1
      01010111
2
      00000100
3
     ----------
4
      00000100

dann kommt da etwas ungleich 0 heraus. Welche Zahl das genau ist, ist an 
dieser Stelle nicht wirklich wichtig. Wichtig ist, dass es nicht 0 ist.

Denn jetzt kommt eine C-Eigenart ins Spiel:
1
   if( Ausdruck )

das if interessiert sich nicht für den konkreten Zahlenwert. Für das if 
stellt sich nur die Frage: Ist der angegebene Ausdruck 0 oder ist er 
nicht 0.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren