Ich habe den Funktionscode shiftOut() in wiring_shift.c und ich habe nicht ganz verstanden, was in der digitalWrite-Funktion vor sich geht. Ich sehe, dass !!(val & (1 << i)) den Bitwert von val übernimmt aber wie genau funktioniert es?
Die gesamte Funktion ist unten aufgeführt.
void shiftOut(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder, uint8_t val) { uint8_t i; for (i = 0; i < 8; i++) { if (bitOrder == LSBFIRST) digitalWrite(dataPin, !!(val & (1 << i))); else digitalWrite(dataPin, !!(val & (1 << (7 - i)))); digitalWrite(clockPin, HIGH); digitalWrite(clockPin, LOW); } }
Kommentare
-
!!(val & (1 << i))ist der komplexeste Teil dieses Codes. Wenn Sie dies verstehen , was ist dann der Teil, den Sie nichtverstehe? - @ edgar-bonet Eigentlich war das die Frage. Ich kann sehen, dass es irgendwie den Bitwert berechnet, aber ich habe ' nicht verstanden, wie es tut dies.
- Sie verstehen das Verhalten der shiftOut-Funktion? Ich meine, Sie verstehen, dass es ' ll
shift outeinen Wert (in binärer Form) und gibt einen Takt dazu.
Antwort
Ich gehe davon aus, dass bitOrder == LSBFIRST.
-
iist die Bitnummer, dh der „Index“ des nächsten zu schreibenden Bits -
1ist00000001in binär -
<<ist der Linksverschiebungsoperator. Es gibt sein erstes Argument zurück, das um so viele Positionen nach links verschoben ist, wie durch das zweite Argument angezeigt. -
1<<iist binär00000001umi-Positionen nach links verschoben, dh so etwas wie0...010...0, wobei sich die einzelne 1 in der i-ten Position befindet und von rechts (ganz rechts) zählt Position 0 sein) -
&ist der „bitweise und Operator“, wobeiany_bit & 0Null undany_bit & 1istany_bit -
val & (1 << i)ist0...0(i-th bit of val)0...0in binär, wobei sich das i-te Bit von val an der i-ten Position des Ergebnisses befindet. -
!!ist eine doppelte Negation: es konvertiert Null in Null und jeder Wert ungleich Null in Eins. -
!!(val & (1 << i))ist entweder 0 oder 1 und genau das i-te Bit von val
Kommentare
- Lassen Sie mich zusammenfassen, was ich verstehe. Nehmen wir an,
val = '10010111';for i=2!!(val & (1 << i))=!!('10010111' & '00000100')=!!('00000100')=1Wenn i = 3 ist!!(val & (1 << i))=!!('10010111' & '00001000')=!!('00000000')=0 - Das ist richtig!
- Und das bedeutet, wenn ich shiftOut 16-Bit- oder längere Daten gebe, Es werden niedrigstwertige 8 Bits gesendet und der Rest ignoriert.
-
shiftOut()nimmtuint8_tDaten. Wenn Sie es mit einem 16-Bit-Argument aufrufen, entfernt der Compiler implizit die 8 höchstwertigen Bits vor dem eigentlichen Aufruf vonshiftOut(). - @SteveMcDonald: Ja, die Ausgabe wäre ohne die doppelte Negation dieselbe, weil
digitalWrite()beliebige Nicht- interpretiert Nullwert (nicht nur 1) mit der BedeutungHIGH. Anscheinend wollte sich der Autor vonshiftOut()nicht auf dieses Verhalten verlassen, sondern stattdessendigitalWrite()mit 0 (dhLOW) oder 1 (HIGH).