Wie funktioniert die shiftOut-Funktion intern? (Erklärung zum Quellcode)

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 nicht verstehe?
  • @ 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 out einen Wert (in binärer Form) und gibt einen Takt dazu.

Antwort

Ich gehe davon aus, dass bitOrder == LSBFIRST.

  • i ist die Bitnummer, dh der „Index“ des nächsten zu schreibenden Bits
  • 1 ist 00000001 in 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<<i ist binär 00000001 um i -Positionen nach links verschoben, dh so etwas wie 0...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“, wobei any_bit & 0 Null und any_bit & 1 ist any_bit
  • val & (1 << i) ist 0...0(i-th bit of val)0...0 in 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') = 1 Wenn 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() nimmt uint8_t Daten. Wenn Sie es mit einem 16-Bit-Argument aufrufen, entfernt der Compiler implizit die 8 höchstwertigen Bits vor dem eigentlichen Aufruf von shiftOut().
  • @SteveMcDonald: Ja, die Ausgabe wäre ohne die doppelte Negation dieselbe, weil digitalWrite() beliebige Nicht- interpretiert Nullwert (nicht nur 1) mit der Bedeutung HIGH. Anscheinend wollte sich der Autor von shiftOut() nicht auf dieses Verhalten verlassen, sondern stattdessen digitalWrite() mit 0 (dh LOW) oder 1 (HIGH).

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.