Jexaminais shiftOut() le code de fonction dans wiring_shift.c et je nai pas très bien compris ce qui se passe dans la fonction digitalWrite. Je vois que !!(val & (1 << i)) prend la valeur du bit de val mais comment ça marche exactement?
Toute la fonction est ci-dessous.
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); } }
Commentaires
Réponse
Je « suppose que bitOrder == LSBFIRST.
-
iest le numéro du bit, cest-à-dire l «index» du prochain bit à écrire -
1est00000001en binaire -
<<est lopérateur de décalage vers la gauche. Il renvoie son premier argument décalé vers la gauche dautant de positions quindiqué par le deuxième argument -
1<<iest binaire00000001décalé vers la gauche deipositions, cest-à-dire quelque chose comme0...010...0, où le 1 unique est à la i-ième position à partir de la droite étant la position 0) -
&est le « bitwise and operator », oùany_bit & 0est zéro etany_bit & 1estany_bit -
val & (1 << i)est0...0(i-th bit of val)0...0en binaire, où le i-ème bit de val est à la i-ème position du résultat -
!!est une double négation: il convertit zéro en zéro et toute valeur différente de zéro en un -
!!(val & (1 << i))vaut 0 ou 1 et correspond exactement au i-ième bit de val
Commentaires
- permettez-moi de résumer ce que je comprends. Supposons que
val = '10010111';for i=2!!(val & (1 << i))=!!('10010111' & '00000100')=!!('00000100')=1Si i est = 3!!(val & (1 << i))=!!('10010111' & '00001000')=!!('00000000')=0 - Cest correct!
- Et cela signifie que si je donne des données de 16 bits ou plus à shiftOut, il enverra les 8 bits les moins significatifs et ignorera le reste.
-
shiftOut()prend des donnéesuint8_t. Si vous lappelez avec un argument 16 bits, le compilateur supprimera implicitement les 8 bits les plus significatifs avant lappel réel àshiftOut(). - @SteveMcDonald: Oui, la sortie serait la même sans la double négation, car
digitalWrite()interprète tout non- valeur zéro (pas seulement 1) comme signifiantHIGH. Apparemment, lauteur deshiftOut()ne voulait pas se fier à ce comportement, et a plutôt voulu toujours appelerdigitalWrite()avec soit 0 (cest-à-direLOW) ou 1 (HIGH).
!!(val & (1 << i))est la partie la plus complexe de ce code. Si vous comprenez ceci, alors quelle est la partie que vous ne faites pas compris?shift outune valeur (sous forme binaire) .Et donnera une impulsion dhorloge avec elle.