Ik was shiftOut() functiecode aan het onderzoeken in wiring_shift.c en ik begreep niet helemaal wat er in de digitalWrite-functie gebeurt. Ik zie dat !!(val & (1 << i)) de bitwaarde overneemt van val maar hoe werkt het precies? 
De hele functie staat hieronder.
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); } } Reacties
Antwoord
 Ik “neem aan bitOrder == LSBFIRST. 
-  iis het bitnummer, dwz de “index” van het volgende te schrijven bit
-  1is00000001in binair formaat
-  <<is de operator voor verschuiven naar links. Het geeft het eerste argument terug dat evenveel posities naar links is verschoven als aangegeven door het tweede argument.
-  1<<iis binair00000001naar links verschoven metiposities, dat wil zeggen zoiets als0...010...0, waarbij de enkele 1 op de i-de positie staat, geteld vanaf de rechterkant zijnde positie 0)
-  &is de “bitsgewijze en operator”, waarbijany_bit & 0nul is enany_bit & 1isany_bit
-  val & (1 << i)is0...0(i-th bit of val)0...0in binair, waarbij het i-de bit van val zich in de i-de positie van het resultaat bevindt
-  !!is een dubbele negatie: het converteert nul naar nul en elke niet-nulwaarde naar één
-  !!(val & (1 << i))is 0 of 1, en is precies het i-de bit van val
Reacties
-  laat me samenvatten wat ik begrijp. Laten we aannemen dat val = '10010111';for i=2!!(val & (1 << i))=!!('10010111' & '00000100')=!!('00000100')=1If i is = 3!!(val & (1 << i))=!!('10010111' & '00001000')=!!('00000000')=0
- Dit is correct!
- En dit betekent dat als ik 16bit of meer gegevens geef om uit te schakelen, het zal de minst significante 8 bits verzenden en de rest negeren.
-  shiftOut()neemtuint8_tgegevens. Als je het aanroept met een 16-bits argument, zal de compiler impliciet de 8 meest significante bits verwijderen voor de daadwerkelijke aanroep vanshiftOut().
-  @SteveMcDonald: Ja, de uitvoer zou hetzelfde zijn zonder de dubbele ontkenning,  omdat  digitalWrite()interpreteert elke niet- nulwaarde (niet alleen 1) als betekenisHIGH. Blijkbaar wilde de auteur vanshiftOut()niet vertrouwen op dit gedrag, en wilde in plaats daarvan altijddigitalWrite()aanroepen met een 0 (dwzLOW) of 1 (HIGH).
!!(val & (1 << i))is het meest complexe deel van deze code. Als je dit begrijpt , wat is dan het deel dat je niet begrepen?shift outeen waarde (in binaire vorm) en geeft daarbij een klokpuls.