Jak funguje funkce shiftOut interně? (vysvětlení ke zdrojovému kódu)

Zkoumal jsem shiftOut() funkční kód v wiring_shift.c a úplně jsem nepochopil, co se děje ve funkci digitalWrite. Vidím, že !!(val & (1 << i)) bere bitovou hodnotu z val ale jak přesně to funguje?

Celá funkce je níže.

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

Komentáře

  • !!(val & (1 << i)) je nejsložitější částí tohoto kódu. Pokud tomu rozumíte , pak jaká je vaše část, ne rozumět?
  • @ edgar-bonet Vlastně to byla otázka. Vidím, že nějak vypočítá bitovou hodnotu, ale nerozuměl jsem ' jak udělá to.
  • Chápeš chování funkce shiftOut? Chápu, že ' ll shift out hodnota (v binární formě). A spolu s ní dá hodinový puls.

Odpověď

Předpokládám bitOrder == LSBFIRST.

  • i je číslo bitu, tj. „index“ dalšího bitu, který se má zapsat
  • 1 je 00000001 v binární podobě
  • << je operátor posunu vlevo. Vrátí svůj první argument posunutý doleva o tolik pozic, kolik naznačuje druhý argument
  • 1<<i je binární 00000001 posunuto doleva o i pozice, tj. něco jako 0...010...0, kde je singl 1 v i-té pozici počítající zprava (úplně vpravo) pozice 0)
  • & je „bitový a operátor“, kde any_bit & 0 je nula a any_bit & 1 je any_bit
  • val & (1 << i) je 0...0(i-th bit of val)0...0 v binární podobě, kde i-tý bit val je v i-té pozici výsledku
  • !! je dvojitá negace: it převede nulu na nulu a jakoukoli nenulovou hodnotu na jednu
  • !!(val & (1 << i)) je buď 0 nebo 1 a je přesně i-tým bitem val

Komentáře

  • dovolte mi shrnout, čemu rozumím. Předpokládejme val = '10010111'; for i=2 !!(val & (1 << i)) = !!('10010111' & '00000100') = !!('00000100') = 1 Pokud je i = 3 !!(val & (1 << i)) = !!('10010111' & '00001000') = !!('00000000') = 0
  • To je správné!
  • A to znamená, že pokud na shiftOut dám 16bitová nebo delší data, pošle nejméně významných 8 bitů a zbytek bude ignorovat.
  • shiftOut() vezme uint8_t data. Pokud jej zavoláte 16bitovým argumentem, kompilátor implicitně odstraní 8 nejvýznamnějších bitů před skutečným voláním shiftOut().
  • @SteveMcDonald: Ano, výstup by byl stejný bez dvojí negace, protože digitalWrite() interpretuje jakékoli jiné než nulová hodnota (nejen 1) znamená HIGH. Autor shiftOut() se zjevně nechtěl spoléhat na toto chování a místo toho chtěl vždy volat digitalWrite() buď s 0 (tj. LOW) nebo 1 (HIGH).

Napsat komentář

Vaše e-mailová adresa nebude zveřejněna. Vyžadované informace jsou označeny *