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
.
-
i
est le numéro du bit, cest-à-dire l «index» du prochain bit à écrire -
1
est00000001
en 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<<i
est binaire00000001
décalé vers la gauche dei
positions, 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 & 0
est zéro etany_bit & 1
estany_bit
-
val & (1 << i)
est0...0(i-th bit of val)0...0
en 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')
=1
Si 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 out
une valeur (sous forme binaire) .Et donnera une impulsion dhorloge avec elle.