Ich habe den shiftOut()
Funktionscode in untersucht wiring_shift.c
und nicht ganz verstanden, was in der digitalWrite-Funktion vor sich geht. Ich sehe, !!(val & (1 << i))
nimmt den Bitwert von, val
aber wie genau funktioniert es?
Die ganze Funktion ist unten.
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);
}
}
c++
arduino-ide
core-libraries
wizofwor
quelle
quelle
!!(val & (1 << i))
ist der komplexeste Teil dieses Codes. Wenn Sie dies verstehen, welchen Teil verstehen Sie dann nicht ?shift out
ein Wert sein wird (in binärer Form). Und wird einen Takt dazu geben.Antworten:
Ich werde annehmen
bitOrder == LSBFIRST
.i
ist die Bitnummer, dh der „Index“ des nächsten zu schreibenden Bits1
ist00000001
binär<<
ist der Shift-Left-Operator. Das erste Argument wird um so viele Positionen nach links verschoben, wie im zweiten Argument angegeben1<<i
ist binär00000001
umi
Positionen nach links verschoben , dh so etwas wie0...010...0
, wobei sich die einzelne 1 in der i-ten Position befindet und von rechts zählt (ganz rechts ist Position 0)&
ist der "bitweise und Operator", wobeiany_bit & 0
Null ist undany_bit & 1
istany_bit
val & (1 << i)
ist0...0(i-th bit of val)0...0
binär, wobei sich das i-te Bit von val an der i-ten Position des Ergebnisses befindet!!
ist eine doppelte Negation: Sie wandelt Null in Null und jeden Wert ungleich Null in Eins um!!(val & (1 << i))
ist entweder 0 oder 1 und ist genau das i-te Bit von valquelle
val = '10010111'
;for i=2
!!(val & (1 << i))
=!!('10010111' & '00000100')
=!!('00000100')
=1
Wenn i = 3!!(val & (1 << i))
=!!('10010111' & '00001000')
=!!('00000000')
=0
shiftOut()
nimmtuint8_t
Daten. Wenn Sie es mit einem 16-Bit-Argument aufrufen, entfernt der Compiler implizit die 8 höchstwertigen Bits vor dem eigentlichen Aufruf vonshiftOut()
.digitalWrite()
interpretiert wird . Anscheinend wollte sich der Autor von nicht auf dieses Verhalten verlassen und wollte stattdessen immer entweder mit 0 (dh ) oder 1 ( ) anrufen .HIGH
shiftOut()
digitalWrite()
LOW
HIGH