Hogyan működik a shiftOut funkció belsőleg? (magyarázat a forráskódra)

shiftOut() függvénykódot vizsgáltam a wiring_shift.c és nem igazán értettem, mi történik a digitalWrite funkcióban. Úgy látom, hogy !!(val & (1 << i)) a val bitértéket veszi át de hogyan működik pontosan?

A teljes függvény lent van.

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); } } 

Megjegyzések

  • !!(val & (1 << i)) ennek a kódnak a legösszetettebb része. Ha ezt érted megérted, akkor mi az a rész, amit csinálsz nem értem?
  • @ edgar-bonet Valójában ez volt a kérdés. Látom, hogy valahogy kiszámítja a bit értékét, de nem értettem ' ezt teszi.
  • Érted a shiftOut függvény viselkedését? Úgy értem, hogy megérted, hogy ' ll shift out egy érték (bináris formában). És egy impulzust ad vele együtt.

Válasz

Feltételezem, hogy bitOrder == LSBFIRST.

  • i a bitszám, vagyis a következő írandó bit „indexe”
  • 1 00000001 binárisan
  • << a balra tolás operátora. Az első argumentumot annyi pozícióval balra tolva adja vissza, amennyit a második argumentum jelez.
  • 1<<i bináris 00000001 i pozíciók által balra tolva, azaz valami olyasmi, mint 0...010...0, ahol az 1-es az i-edik pozícióban van, jobbról számítva (a jobb szélső 0-os pozíció)
  • & a „bitenként és operátor”, ahol any_bit & 0 nulla és any_bit & 1 any_bit
  • val & (1 << i) is 0...0(i-th bit of val)0...0 bináris formában, ahol a val i-edik bitje az eredmény i-edik helyzetében van
  • !! kettős tagadás: ez konvertálja a nullát nullává, és az esetleges nem nulla értékeket eggyé
  • !!(val & (1 << i)) akár 0, akár 1, és pontosan a val

Megjegyzések

  • hadd foglaljam össze, mit értek. Tegyük fel, hogy val = '10010111'; for i=2 !!(val & (1 << i)) = !!('10010111' & '00000100') = !!('00000100') = 1 Ha i = 3 !!(val & (1 << i)) = !!('10010111' & '00001000') = !!('00000000') = 0
  • Ez így van!
  • És ez azt jelenti, hogy 16 bites vagy hosszabb adatot adok a shiftOut-nak, legkevesebb 8 bitet küld, a többit pedig figyelmen kívül hagyja.
  • shiftOut() uint8_t adatokat vesz fel. Ha 16 bites argumentummal hívja meg, a fordító implicit módon eltávolítja a 8 legjelentősebb bitet előtt a tényleges hívás shiftOut().
  • @SteveMcDonald: Igen, a kimenet ugyanaz lenne a kettős tagadás nélkül, mert digitalWrite() minden értelmez nulla érték (nem csak 1) jelentése HIGH. Nyilvánvaló, hogy a shiftOut() szerzője nem akart erre a viselkedésre hagyatkozni, ehelyett mindig a (z) digitalWrite() -t 0-val (azaz LOW) vagy 1 (HIGH).

Vélemény, hozzászólás?

Az email címet nem tesszük közzé. A kötelező mezőket * karakterrel jelöltük