8-bit shift register 74HC595, Comment ça marche ?
Do not index
Do not index
Hide CTA
Hide CTA
Video preview

Objectifs

Cette vidéo est la première de deux parties.  Je commence d’abord par expliquer les fondements du calcul binaire, ou du moins comment lire et interpréter ces nombres, et on poursuit par une mise en pratique avec le 8-bit shift register de la catégorie des PICs : le 74HC595

Pourquoi utiliser le binaire ?

Je pense que si vous voulez évoluer de manière sereine dans la programmation informatique et l’électronique, avoir les strictes bases de lecture du binaire peux être un atout non négligeable. De plus nous allons un peu plus loin que la simple lecture car nous découvrons par la même occasion l’opérateur binaire de décalage.
N’ayez d’inquiétude, il ne vous suffira que de quelque minutes pour démystifier ces nombres et je vous prouve par le système décimal que vous connaissez déjà, qu’en fait, comprendre l’un, c’est finalement tous les comprendre.

Description du 8-bit shift register 74HC595

Le 8-bit shift register peux devenir un vrai « game changer » dans vos montages électroniques car il permet, tout en utilisant que 3 pins sur votre Arduino, de démultiplier le nombre de sorties logiques digitales. Dans la vidéo présenté dans cet article, vous est montré comment on gère 8-bit à partir des 3 pins originaux, et dans la vidéo qui suivra nous irons plus loin pour voir comment il devient possible de sérialiser l’usage des 74HC595.
Autre avantage de ce composant un peu ignoré surtout lorsque l’on débute c’est le côté conversion Série vers Parallèles. Après tout la première ligne décrivant les options de ce composant dans la fiche technique c’est 8-Bit Serial-In, Parallel-Out Shift. Cela indique que vous allez envoyer des bits un à un à votre PIC, il va les stocker, mais lors du relâchement, ce sont les 8 ports qui se mettent à jour instantanément.  Chose qu’actuellement, si vous réfléchissez bien, n’arrive tout simplement jamais sur vos ordinateurs ou sur votre Arduino. Parfois cette parallélisation peu avoir des enjeux cruciaux.
notion image

Protocole de transmission de données d’un 8-bit shift register

La communication entre l’Arduino et le 74HC595 se fait via 2 fils ce qui permet de ne pas avoir à gérer les timings comme nous l’avions fait lors du contrôle du DHT11 dans le précédent article. Dans ce protocole, un fil envoie un signal carré constant qui sert de tempo pour le transfert de données. Le 74HC595 fonctionne sur le protocole dit « rising-edge » c’est-à-dire qu’à chaque fois que l’horloge passe d’un état bas à un état haut, le composant jette un œil sur son fil data et regarde l’état de celui-ci pour en retenir un bit dans son registre. En parallèle il porte son attention sur le port qui lui sert de gâchette car lorsque ce port sera mis a l’état haut, il mettra à jour la data qu’il a reçu de son registre de stockage au registre des sorties digitales.
notion image

Les ports respectifs du 8-bit shift register 74HC595

notion image

GND :

Vers la masse du circuit

VCC :

Tension d’alimentation pour le 74HC595 que l’on raccordera au 5V de l’Arduino

DS :

C’est par ce port que nous fournissons la donnée bit par bit

OE :

Ce port à un rôle très particulier : activer ou non le composant. Si on lui met une tension alors toutes les sorties s’éteignent et il devient inutilisable. Dans le cas contraire, il fonctionne normalement. Dans nos démonstrations on laissera ce port tranquille mais c’est toujours bon de savoir que ça existe.

STCP :

Gâchette de l’appareil, c’est le port qui nous sert à faire basculer la donnée en attente d’être mise à jour, à la donnée que l’on voit exprimées sur notre circuit. Si nous n’utilisons pas cette gâchette, c’est bien simple, il ne se passera rien. Pour s’en servir, on le passe à LOW juste avant d’envoyer de la data, et on le passe à HIGH pour activer la transition des registres juste après.

SHCP :

C’est par ce port que nous fournissons le signal d’horloge. Ce composant à besoin d’une horloge de référence pour comprendre et interpréter la donnée. Cela veux dire que pour que le registre de décalage, décale les bits un à un dans le registre, il attendra que l’horloge soit à un état haut, et transmettra la donnée à chaque fois que l’horloge passe d’un état bas à un état haut, appelé “rising edge” ou bord montant.

MR :

Un peu dans la même veine que OE, ce port permet de complètement réinitialiser le composant et de mettre toute sa mémoire et registre en cours à 0. Pour s’en servir, la logique sera de tout le temps y appliquer une tension et à la seconde où on passe le port à LOW, cela effectue la réinitialisation. Encore une fois, c’est un usage dont on n’a pas vraiment besoin avec l’Arduino et sert à des usages plus analogique de ce composant dira t’on.

Q7S :

Ce port là est très utile si vous souhaitez faire une chaine de shift register et les contrôler comme un seul très grand composant. L’idée ici c’est de donner la même horloge et la même gâchette à tout les 74HC595 de votre circuit et vous raccordez le port Q7S au port de donné du prochain shift register sur le circuit. Pour en savoir plus je vous montre comment on exploite ce concept dans la seconde vidéo liée à ce chapitre. Il n’y a aucune limite à part celle de l’alimentation, mais vous comprenez surement maintenant l’importance que peut avoir le shift register dans sa capacité à étendre les capacités de votre Arduino.

Q0 à Q7 :

On finit par les ports utiles dans toute cette histoire. Ces 8 ports sont ceux qui nous servirons à être effectivement utilisé comme des ports digitaux supplémentaires sur l’Arduino.

Démonstration et montage électronique

Je commence directement par le disclaimer qui va bien : NON le 74HC595 n’est PAS fait pour contrôler des LEDs. À vrai dire, les LEDs c’est le mal absolu, ces trucs tout mimi qui brillent consomment un courant monstre. On va prendre une moyenne de 20 mAh pour une LED standard avec sa résistance de base, si on prend 8 LED allumées simultanément ça nous donne 160 mAh. Et normalement notre 8-bit shift register 74HC595 ne tolère qu’un maximum d’une 50taine de milliampère. Sans parler de l’Arduino qui douille sa mère à lâcher autant de courant. Bref tout ça pour dire que pour cette fois, on va faire une exception afin de simplement démontrer les principes de fonctionnement du composant avec des LEDs mais nous utiliserons les précautions qui s’imposent. À la place des habituelles 220 Ohm que vous placez sur vos LEDs, cette fois prenez-moi des 1 KOhm et signez la pétition de protection des Arduino sauvages maltraitées par leurs utilisateurs.  Grâce à cette mesure vous devriez seulement tirer quelque 3-4 mAh par LED.

Code source pour le 74HC595

C’est maintenant le moment de vérité, voyons voir si vous avez réussi à rassembler toute votre dextérité pour le montage et testons le tout avec un premier code source. Dans celui-ci, on affiche les nombres de 0 à 255 en binaire. Ce sont donc toutes les possibilités que nous permet ce composant.
#define PIN_DS_DATA 4
#define PIN_STCP_LATCH 5
#define PIN_SHCP_CLOCK 6

void setup() {
  //On définie les 3 ports en mode OUTPUT
  pinMode(PIN_STCP_LATCH, OUTPUT);
  pinMode(PIN_SHCP_CLOCK, OUTPUT);
  pinMode(PIN_DS_DATA, OUTPUT);
}

void loop() {
  //On execute une boucle de 255 tours pour visiter 
  //les 255 nombres qui peuvent être représentés dans un octet. 
  for (byte number = 0; number < 256; number++) {
    //On s'assure que la gachette est a l'etat LOW
    digitalWrite(PIN_STCP_LATCH, LOW);
    
    //On utlise la fonction shiftOut de la librairie 
    //arduino pour lui soumettre la valeur à transmettre au registre
    shiftOut(PIN_DS_DATA, PIN_SHCP_CLOCK, LSBFIRST, number);
    
    //On inverse l'etat de la gachette pour mettre à jour le registre
    digitalWrite(PIN_STCP_LATCH, HIGH);
    
    //Un delais d'une demi seconde avant le prochain tour de boucle
    delay(500);
  }
}
Dans les deux prochains codes sources qui ne se différencies que par un seul terme lors de l’appel de la fonction ShiftOut de la librairie Arduino, au lieu d’afficher toutes les combinaisons possibles qu’un octet peut avoir je vous montre le très utile décalage binaire nous permettant d’allumer successivement en boucle chaque LED de manière individuelles.
Lorsque MSBFIRST est utilisé cela indique que c’est le bit de poids fort qui sera envoyé en premier (Most Significant Bit First) et l’inverse LSBFIRST donne la priorité au bit de poids faible (Least Significant Bit First).
#define PIN_DS_DATA 4
#define PIN_STCP_LATCH 5
#define PIN_SHCP_CLOCK 6

byte led = 0;

void setup() {
  //On définie les 3 ports en mode OUTPUT
  pinMode(PIN_STCP_LATCH, OUTPUT);
  pinMode(PIN_SHCP_CLOCK, OUTPUT);
  pinMode(PIN_DS_DATA, OUTPUT);
}

void loop() {
  //On execute une boucle de 8 tours pour visiter les 8 LEDs 
  for (byte i = 0; i < 8; i++) {
    //On affecte la variable led de la valeur 1 decallée au prorata de i
    led = 1 << i;
    
    //On s'assure que la gachette est a l'etat LOW
    digitalWrite(PIN_STCP_LATCH, LOW);
    
    //On utlise la fonction shiftOut de la librairie 
    //arduino pour lui soumettre la valeur a transmettre au registre
    shiftOut(PIN_DS_DATA, PIN_SHCP_CLOCK, LSBFIRST, led);
    
    //On inverse l'etat de la gachette pour mettre a jour le registre
    digitalWrite(PIN_STCP_LATCH, HIGH);
    
    //Un delais d'une demi seconde avant le prochain tour de boucle
    delay(500);
  }
}
#define PIN_DS_DATA 4
#define PIN_STCP_LATCH 5
#define PIN_SHCP_CLOCK 6

byte led = 0;

void setup() {
  //On définie les 3 ports en mode OUTPUT
  pinMode(PIN_STCP_LATCH, OUTPUT);
  pinMode(PIN_SHCP_CLOCK, OUTPUT);
  pinMode(PIN_DS_DATA, OUTPUT);
}

void loop() {
  //On execute une boucle de 8 tours pour visiter les 8 LEDs 
  for (byte i = 0; i < 8; i++) {
    //On affecte la variable led de la valeur 1 decallée au prorata de i
    led = 1 << i;
    
    //On s'assure que la gachette est a l'etat LOW
    digitalWrite(PIN_STCP_LATCH, LOW);
    
    //On utlise la fonction shiftOut de la librairie 
    //arduino pour lui soumettre la valeur a transmettre au registre
    shiftOut(PIN_DS_DATA, PIN_SHCP_CLOCK, MSBFIRST, led);
    
    //On inverse l'etat de la gachette pour mettre a jour le registre
    digitalWrite(PIN_STCP_LATCH, HIGH);
    
    //Un delais d'une demi seconde avant le prochain tour de boucle
    delay(500);
  }
}
 
Cyril

Written by

Cyril

Hobbyiste en électronique, programmation et IA