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
Válasz
Feltételezem, hogy bitOrder == LSBFIRST.
-
ia bitszám, vagyis a következő írandó bit „indexe” -
100000001biná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<<ibináris00000001ipozíciók által balra tolva, azaz valami olyasmi, mint0...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”, aholany_bit & 0nulla ésany_bit & 1any_bit -
val & (1 << i)is0...0(i-th bit of val)0...0biná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 li i-edik bitje >
Megjegyzések
- hadd foglaljam össze, mit értek. Tegyük fel, hogy
val = '10010111';for i=2!!(val & (1 << i))=!!('10010111' & '00000100')=!!('00000100')=1Ha 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_tadatokat 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ásshiftOut(). - @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éseHIGH. Nyilvánvaló, hogy ashiftOut()szerzője nem akart erre a viselkedésre hagyatkozni, ehelyett mindig a (z)digitalWrite()-t 0-val (azazLOW) vagy 1 (HIGH).
!!(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?shift outegy érték (bináris formában). És egy impulzust ad vele együtt.