Hvordan fungerer shiftOut-funktionen internt? (forklaring på kildekoden)

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

  • !!(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?
  • @ edgar-bonet Faktisk var dette spørgsmålet. Jeg kan se det på en eller anden måde beregner bitværdien, men jeg forstod ikke ' hvordan det gør dette.
  • Forstår du adfærden af shiftOut-funktionen? Jeg mener, du forstår, at den ' ll shift out en værdi (i binær form). Og giver en urpuls sammen med den.

Svar

Jeg antager bitOrder == LSBFIRST.

  • i er bitnummeret, dvs. “indekset” for den næste bit, der skal skrives
  • 1 er 00000001 i 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<<i er binært 00000001 skiftet til venstre med i positioner, dvs. noget som 0...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”, hvor any_bit & 0 er nul og any_bit & 1 er any_bit
  • val & (1 << i) er 0...0(i-th bit of val)0...0 i 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') = 1 Hvis 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() tager uint8_t data. Hvis du kalder det med et 16-bit argument, fjerner compileren implicit de 8 mest betydningsfulde bits før det aktuelle opkald til shiftOut().
  • @ SteveMcDonald: Ja, output ville være det samme uden den dobbelte negation, fordi digitalWrite() fortolker enhver ikke- nul værdi (ikke kun 1) som betydning HIGH. Tilsyneladende ønskede forfatteren af shiftOut() ikke at stole på denne adfærd og ville i stedet altid kalde digitalWrite() med enten 0 (dvs. LOW) eller 1 (HIGH).

Skriv et svar

Din e-mailadresse vil ikke blive publiceret. Krævede felter er markeret med *