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:
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.