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.
-
ion bittinumero, ts. seuraavan kirjoitettavan bitin ”indeksi” -
1on00000001binaarissa -
<<on siirtymä vasemmalle. Se palauttaa ensimmäisen argumenttinsa siirretty vasemmalle niin monta paikkaa kuin toinen argumentti osoittaa. -
1<<ion binaarinen00000001siirtynyt 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 & 0on nolla jaany_bit & 1onany_bit -
val & (1 << i)on0...0(i-th bit of val)0...0binaarisessa 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')=1Jos 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 outarvo (binäärimuodossa). Ja antaa kellopulssin sen mukana.