Jeg undersøkte shiftOut() funksjonskode i wiring_shift.c og jeg forstod ikke helt hva som skjer i digitalWrite-funksjonen. Jeg ser !!(val & (1 << i)) tar bitverdien fra val men hvordan fungerer det akkurat?
Hele funksjonen er under.
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 antar bitOrder == LSBFIRST.
-
ier bitnummeret, dvs. «indeksen» til neste bit som skal skrives -
1er00000001i binær -
<<er skiftet til venstre. Den returnerer sitt første argument skiftet til venstre med så mange posisjoner som angitt av det andre argumentet -
1<<ier binært00000001skiftet til venstre aviposisjoner, dvs. noe sånt som0...010...0, der singelen 1 er i den i-posisjonen teller fra høyre (høyre å være posisjon 0) -
&er «bitvis og operator», derany_bit & 0er null ogany_bit & 1erany_bit -
val & (1 << i)er0...0(i-th bit of val)0...0i binær, der i-bit av val er i i-posisjon av resultatet -
!!er en dobbel negasjon: det konverterer null til null og en verdi som ikke er null til en -
!!(val & (1 << i))er enten 0 eller 1, og er nøyaktig den i-biten av val
Kommentarer
- la meg oppsummere det jeg forstår. La oss anta
val = '10010111';for i=2!!(val & (1 << i))=!!('10010111' & '00000100')=!!('00000100')=1Hvis jeg er = 3!!(val & (1 << i))=!!('10010111' & '00001000')=!!('00000000')=0 - Dette er riktig!
- Og dette betyr at hvis jeg gir 16bit eller lengre data å skifte ut, det vil sende minst betydelige 8 biter og ignorere resten.
-
shiftOut()taruint8_tdata. Hvis du kaller det med et 16-bits argument, vil kompilatoren implisitt fjerne de 8 mest betydningsfulle bitene før selve anropet tilshiftOut(). - @ SteveMcDonald: Ja, utdataene ville være de samme uten den dobbelte negasjonen, fordi
digitalWrite()tolker noen ikke- null verdi (ikke bare 1) som betyrHIGH. Tilsynelatende ønsket ikke forfatteren avshiftOut()å stole på denne oppførselen, og ville i stedet alltid ringedigitalWrite()med enten 0 (dvs.LOW) eller 1 (HIGH).
!!(val & (1 << i))er den mest komplekse delen av denne koden. Hvis du gjør forstår dette, hva er den delen du gjør ikke forstår?shift outen verdi (i binær form). Og vil gi en klokkepuls sammen med den.