Shift Register 74HC595

Vous venez de déballer votre Raspberry Pi et vous vous posez des questions ? C'est ici que ça se passe !

Modérateur : Francois

Répondre
RogerTheGold
Messages : 2
Enregistré le : lun. 13 juil. 2015 21:45

Shift Register 74HC595

Message par RogerTheGold » lun. 13 juil. 2015 22:46

Bonsoir à tous !

Voilà, ça fait quelques mois que j'ai ma Raspberry Pi B+ sous Raspbian. J'avais commandé un pack de composants chez Sunfounder pour bien démarrer et pouvoir m'amuser un peu, pack qui contenais notamment 2 registres 74HC595, mais je n'arrive pas à dompter la bête.

J'essaie simplement d'allumer 8 leds grâce à 1 seul registre pour le moment, dans l'ordre que je le veux (en vérité peu m'importe l'ordre, le principe étant de savoir contrôler les leds indépendamment).
Après pas mal de recherche et d'essais, aucun n'ont abouti. Le meilleur résultat que j'ai su obtenir (et encore, c'est en reprenant le code et le schéma qui étaient présent dans le pack acheté, donc aucun mérite lol) est un clignotement de groupes de leds alors qu'elles sont censées clignoter chacune tour à tour.

Etant débutant, je ne sais pas si j'ai fait une erreur dans le montage, ou si le code n'est pas celui promis dans les vidéos de démonstration.

J'ai donc refait un schéma reprenant mon montage :
Image

Et voici le code en C correspondant :

Code : Tout sélectionner

#include <wiringpi.h>
#include <stdio.h>
  
#define   SDI   0   //serial data input
#define   RCLK  1   //memory clock input(STCP)
#define   SRCLK 2   //shift register clock input(SHCP)
  
unsigned char LED[8] = {0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};
  
  
void pulse(int pin)
{
    digitalWrite(pin, 0);
    digitalWrite(pin, 1);
}
  
void SIPO(unsigned char byte)
{
    int i;
  
    for(i=0;i<8;i++){
        digitalWrite(SDI, ((byte & (0x80 >> i)) > 0));
        pulse(SRCLK);
    }
}
  
void init(void)
{
    pinMode(SDI, OUTPUT); //make P0 output
    pinMode(RCLK, OUTPUT); //make P0 output
    pinMode(SRCLK, OUTPUT); //make P0 output
  
    digitalWrite(SDI, 0);
    digitalWrite(RCLK, 0);
    digitalWrite(SRCLK, 0);
}
  
int main(void)
{
    int i;
  
    if(wiringPiSetup() == -1){ //when initialize wiring failed,print messageto screen
        printf("setup wiringPi failed !");
        return 1;
    }
  
    init();
  
    while(1){
        for(i=0;i<8;i++){
            SIPO(LED[i]);
            pulse(RCLK);
            delay(150);
            //printf("i = %d\n",i);
        }
        delay(500);
  
        for(i=0;i<3;i++){
            SIPO(0xff);
            pulse(RCLK);
            delay(100);
            SIPO(0x00);
            pulse(RCLK);
            delay(100);
        }
        delay(500);
//      digitalWrite(RCLK,0);
  
        for(i=0;i<8;i++){
            SIPO(LED[8-i-1]);
            pulse(RCLK);
            delay(150);
        }
        delay(500);
  
        for(i=0;i<3;i++){
            SIPO(0xff);
            pulse(RCLK);
            delay(100);
            SIPO(0x00);
            pulse(RCLK);
            delay(100);
        }
        delay(500);
    }
  
    return 0;
}
Je dois vous avouer que je ne comprend pas vraiment le code à 100% et c'est aussi pourquoi je viens vous voir..

Merci pour vos futures réponses !

guillaume9344
Raspinaute
Messages : 629
Enregistré le : mar. 6 janv. 2015 19:44
Localisation : finistere

Re: Shift Register 74HC595

Message par guillaume9344 » mar. 14 juil. 2015 13:51

Bonjour,
en premier , lorsque l'on utilise un circuit intégré (de la porte logique au gros microcontrôleur 64 bits) il faut étudier la doc du composant .
je la met ici pour tout le monde :
http://www.nxp.com/documents/data_sheet/74HC_HCT595.pdf

Pour le fonctionnement du circuit: il sert a "convertir" une suite de bits sur un fil en bits sous forme parallèles.

l' entrée ce fait sur la pin DS, au premier front montant du signal shcp , le niveau présent sur DS est stockée dans la première "case"de stockage (8 en-tout).
Au second front sur shcp toutes les cases sont décalées: la valeur de la case 1 est copiée dans la case 2, la case 2 est stocké dans la case 3.............et DS est copié dans la case 1.
Voir fig8 page 6 de la doc .
On voit qu'il y a eu juste un niveau 1 lors du premier front de shcp , puis que des 0, et que par la suite ce niveau 1 est transféré de case à chaque front de shcp.

Les niveau des cases sont présentés au sorties à chaque front montant du signal STCP. Cela implique deux mode de fonctionnement :
-on actionne le fronts sur stcp à caque front sur shcp
-on actionne le front sur stcp que lorsque toute les cases sont remplies
Pour seulement allumer des led , les deux fonctionnements sont transparents.

Un petit exemple:
on veut afficher le nombre 0xA5(en hexa) 0b10100101 (en binaire)

on commence par faire une impulsion vers 0 sur la pin MR , se qui a pour effet de rester toutes les cases à 0 (0000000)
on envoi le premier bit sur DS ,ici 1
on applique un front montant sur shcp , cela charge 1 dans la case 1.(1000000)

on applique le bit 2 sur DS , ici 0
on applique un front montant sur shcp, cela decale toute les cases ( 0100000) et charge ds dans la case 1(0100000)

on applique le bit 3 sur DS ici 1
on applique un front montant sue shcp , cela decale toute les cases ( 0010000) et charge ds dans la case 1(1010000)
.....
....
....
....
on applique le bit 8 sur DS ici 1
on applique un front montant sue shcp , cela decale toute les cases ( 00100101) et charge ds dans la case 1(10100101).

à ce moment les sorties sont toujours dans un état indéterminé.
on applique un front montant sur stcp , cela envoi la valeur des cases sur les sorties et les verrouilles en attentant le prochain front sur stcp.
rpi b+ ,osmc, motioneyes
rpi 2 raspbian , server minecraft 24h/24 , utilisation gpio
orange pi pc debian ,utilisation gpio, motion cam

guillaume9344
Raspinaute
Messages : 629
Enregistré le : mar. 6 janv. 2015 19:44
Localisation : finistere

Re: Shift Register 74HC595

Message par guillaume9344 » mar. 14 juil. 2015 14:05

Pour le fonctionnement du code d'exemple:

Code : Tout sélectionner

  #include <wiringpi.h>
    #include <stdio.h>
     
    #define   SDI   0   //serial data input
    #define   RCLK  1   //memory clock input(STCP)
    #define   SRCLK 2   //shift register clock input(SHCP)
inclusion des bibliothèques wiringpi pour la gestion des gpio, et stdio une bibliothèque standard en C .
definition des différentes pin utilisées.

Code : Tout sélectionner

 unsigned char LED[8] = {0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};
declaration d'un tableau de char , en gros les différentes valeurs que l on veut afficher .

Code : Tout sélectionner

 void pulse(int pin)
    {
        digitalWrite(pin, 0);
        digitalWrite(pin, 1);
    }
fonction de création d'un front montant sur une pin

Code : Tout sélectionner

 void SIPO(unsigned char byte)
    {
        int i;
     
        for(i=0;i<8;i++){
            digitalWrite(SDI, ((byte & (0x80 >> i)) > 0));
            pulse(SRCLK);
        }
    }
fonction qui envoi 8bits sur SDI et envoi en front montant sur srclk(shcp), donc ici on charge les 8 cases .

Code : Tout sélectionner

 void init(void)
    {
        pinMode(SDI, OUTPUT); //make P0 output
        pinMode(RCLK, OUTPUT); //make P0 output
        pinMode(SRCLK, OUTPUT); //make P0 output
     
        digitalWrite(SDI, 0);
        digitalWrite(RCLK, 0);
        digitalWrite(SRCLK, 0);
    }

fonction qui initialise les pin en sortie et applique un niveau 0.

Code : Tout sélectionner

int main(void)
    {
        int i;
     
        if(wiringPiSetup() == -1){ //when initialize wiring failed,print messageto screen
            printf("setup wiringPi failed !");
            return 1;
        }
     
        init();
     
        while(1){
            for(i=0;i<8;i++){
                SIPO(LED[i]);
                pulse(RCLK);
                delay(150);
                //printf("i = %d\n",i);
            }
            delay(500);
début de la fonction MAIN , avec appel de la fonction d'initialisation des pin ,puis une boucle sans fin qui affiche les valeurs contenues dans le tableau LED.
le reste du code n'est jamais exécuté car la première boucle est un while(1) qui ne se fini jamais.

J 'espéré avoir été claire.

@+
rpi b+ ,osmc, motioneyes
rpi 2 raspbian , server minecraft 24h/24 , utilisation gpio
orange pi pc debian ,utilisation gpio, motion cam

RogerTheGold
Messages : 2
Enregistré le : lun. 13 juil. 2015 21:45

Re: Shift Register 74HC595

Message par RogerTheGold » mer. 15 juil. 2015 14:04

Bonjour,

Je pense avoir compris le fonctionnement du registre (il va me falloir un peu de pratique pour bien assimiler et ne pas me tromper avec les pins à activer).
Niveau code, idem. Le plus flou n'est plus ! Maintenant que je sais à quoi sert la fonction SIPO, le reste doit couler de source xD En revanche, si je ne m'abuse, toute la boucle while est bel et bien exécutée ^^

D'ou ma question : est-ce bien normal que les leds clignotent groupées chez moi, et clignotent une à une dans la vidéo de démonstration (reprenant le même code, et le même schéma..) ?

guillaume9344
Raspinaute
Messages : 629
Enregistré le : mar. 6 janv. 2015 19:44
Localisation : finistere

Re: Shift Register 74HC595

Message par guillaume9344 » mer. 15 juil. 2015 15:37

Petite erreure de lecture du code, tout le programme est executé, j ai confondue
l acolade de fermeture du premier foravec l acolade de fermegure du while.
donc avec ce code, en premier les led s affiches les une apres les autre ( premiere boucle for)avec un delay de 150miliseconde?
puis seconde boucle for: tout alumé , delay100, tout etteind, delay 100,trois fois de suite.
troiseme boucle , un autre comptage.
quatrieme boucle de nouveau tout ou rien.

Les delay me semble un peut court, vous pouvez augmenter les 100 en 250
ca permetterai de bien detacher chaque affichage.
rpi b+ ,osmc, motioneyes
rpi 2 raspbian , server minecraft 24h/24 , utilisation gpio
orange pi pc debian ,utilisation gpio, motion cam

Répondre

Retourner vers « Débutants »