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
.
-
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áris00000001
i
pozí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 & 0
nulla ésany_bit & 1
any_bit
-
val & (1 << i)
is0...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 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')
=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á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 out
egy érték (bináris formában). És egy impulzust ad vele együtt.