Jeg undersøgte shiftOut() funktionskode i wiring_shift.c og jeg forstod ikke helt, hvad der foregår i digitalWrite-funktionen. Jeg ser !!(val & (1 << i)) tager bitværdien fra val men hvordan fungerer det nøjagtigt?
Hele funktionen er nedenfor.
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); } }
Kommentarer
Svar
Jeg antager bitOrder == LSBFIRST.
-
ier bitnummeret, dvs. “indekset” for den næste bit, der skal skrives -
1er00000001i binært -
<<er skiftet til venstre. Det returnerer sit første argument skiftet til venstre med så mange positioner som angivet af det andet argument -
1<<ier binært00000001skiftet til venstre medipositioner, dvs. noget som0...010...0, hvor single 1 er i den i-position og tæller fra højre (højre at være position 0) -
&er “bitvis og operator”, hvorany_bit & 0er nul ogany_bit & 1erany_bit -
val & (1 << i)er0...0(i-th bit of val)0...0i binær, hvor den i-bit af val er i den i-position af resultatet -
!!er en dobbelt negation: det konverterer nul til nul, og enhver værdi, der ikke er nul, til en -
!!(val & (1 << i))er enten 0 eller 1, og er nøjagtigt den i-bit af val
Kommentarer
- lad mig opsummere, hvad jeg forstår. Lad os antage
val = '10010111';for i=2!!(val & (1 << i))=!!('10010111' & '00000100')=!!('00000100')=1Hvis jeg er = 3!!(val & (1 << i))=!!('10010111' & '00001000')=!!('00000000')=0 - Dette er korrekt!
- Og det betyder, at hvis jeg giver 16bit eller længere data til at skifte ud, det sender mindst signifikante 8 bits og ignorerer resten.
-
shiftOut()tageruint8_tdata. Hvis du kalder det med et 16-bit argument, fjerner compileren implicit de 8 mest betydningsfulde bits før det aktuelle opkald tilshiftOut(). - @ SteveMcDonald: Ja, output ville være det samme uden den dobbelte negation, fordi
digitalWrite()fortolker enhver ikke- nul værdi (ikke kun 1) som betydningHIGH. Tilsyneladende ønskede forfatteren afshiftOut()ikke at stole på denne adfærd og ville i stedet altid kaldedigitalWrite()med enten 0 (dvs.LOW) eller 1 (HIGH).
!!(val & (1 << i))er den mest komplekse del af denne kode. Hvis du gør forstår dette, hvad er den del, du laver ikke forstår?shift outen værdi (i binær form). Og giver en urpuls sammen med den.