Tutkin shiftOut()
-toimintokoodia wiring_shift.c
ja en tiennyt oikein, mitä digitalWrite-toiminnossa tapahtuu. Näen, että !!(val & (1 << i))
ottaa bittiarvon kohteesta val
mutta miten se toimii?
Koko toiminto on alla.
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); } }
Kommentit
vastaus
Oletan, että bitOrder == LSBFIRST
.
-
i
on bittinumero, ts. seuraavan kirjoitettavan bitin ”indeksi” -
1
on00000001
binaarissa -
<<
on siirtymä vasemmalle. Se palauttaa ensimmäisen argumenttinsa siirretty vasemmalle niin monta paikkaa kuin toinen argumentti osoittaa. -
1<<i
on binaarinen00000001
siirtynyt vasemmallei
-asennoilla, ts.0...010...0
-työkalulla, jossa yksittäinen 1 on i: nnessä sijainnissa laskettaessa oikealta (oikeanpuoleisin sijainti 0) -
&
on ”bitti ja operaattori”, jossaany_bit & 0
on nolla jaany_bit & 1
onany_bit
-
val & (1 << i)
on0...0(i-th bit of val)0...0
binaarisessa muodossa, jossa val-arvon i-bitti on tuloksen i-nnessä asemassa -
!!
on kaksinkertainen negaatio: se muuntaa nollan nollaksi ja kaikki nollasta poikkeavat arvot yhdeksi -
!!(val & (1 << i))
on joko 0 tai 1 ja on täsmälleen i: nnen bitin val
Kommentit
- anna minun tehdä yhteenveto ymmärrämästäni. Oletetaan, että
val = '10010111'
;for i=2
!!(val & (1 << i))
=!!('10010111' & '00000100')
=!!('00000100')
=1
Jos i on = 3!!(val & (1 << i))
=!!('10010111' & '00001000')
=!!('00000000')
=0
- Tämä on oikein!
- Ja tämä tarkoittaa, että annan 16 bittiä tai pidempää dataa shiftOut, se lähettää vähintään 8 merkitsevää bittiä ja ohittaa loput.
-
shiftOut()
vieuint8_t
-dataa. Jos kutsut sitä 16-bittisellä argumentilla, kääntäjä poistaa implisiittisesti 8 merkittävintä bittiä ennen varsinaista kutsuashiftOut()
. - @SteveMcDonald: Kyllä, lähtö olisi sama ilman kaksoisnegatiota, koska
digitalWrite()
tulkitsee mitä tahansa muuta kuin nolla-arvo (ei vain 1) merkitykselläHIGH
. Ilmeisesti julkaisunshiftOut()
kirjoittaja ei halunnut luottaa tähän käyttäytymiseen ja halusi sen sijaan aina kutsuadigitalWrite()
jommallakummalla 0 (eliLOW
) tai 1 (HIGH
).
!!(val & (1 << i))
on tämän koodin monimutkaisin osa. Jos ymmärrät tämän, niin mikä on tekemäsi osa ei ymmärrän?shift out
arvo (binäärimuodossa). Ja antaa kellopulssin sen mukana.