Comment fonctionne la fonction shiftOut en interne? (explication sur le code source)

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

  • !!(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?
  • @ edgar-bonet En fait, cétait la question. Je peux voir quil calcule en quelque sorte la valeur du bit, mais je nai ' pas compris comment
  • Vous comprenez le comportement de la fonction shiftOut? Je veux dire, vous comprenez quelle ' ll shift out une valeur (sous forme binaire) .Et donnera une impulsion dhorloge avec elle.

Réponse

Je « suppose que bitOrder == LSBFIRST.

  • i est le numéro du bit, cest-à-dire l «index» du prochain bit à écrire
  • 1 est 00000001 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 binaire 00000001 décalé vers la gauche de i positions, cest-à-dire quelque chose comme 0...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 et any_bit & 1 est any_bit
  • val & (1 << i) est 0...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ées uint8_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 signifiant HIGH. Apparemment, lauteur de shiftOut() ne voulait pas se fier à ce comportement, et a plutôt voulu toujours appeler digitalWrite() avec soit 0 (cest-à-dire LOW) ou 1 (HIGH).

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *