7 avr. 2016

MAX 7219 pour piloter des afficheurs 7 segments

Ce circuit permet de soulager le programme au niveau du PIC pour gérer des afficheurs.




Pilotage afficheurs 7 segments avec le Max7219



MAX7219 : Présentation


Il est possible de commander des afficheurs 7 segment directement à l'aide d'un PIC mais cela demande l'utilisation de nombreuses E/S et de développer un programme pour gérer les afficheurs.
Ci dessous un schéma possible :

schema affichage 7 segments



Outre le nombre important  E/S utilisées le timing au niveau programme est important pour assurer le multiplexage des segments.
Très vite cela devient une contrainte et laisse peu de temps pour les autres fonctions que doit réaliser le logiciel.

Donc l'utilisation d'un circuit qui s'occupe de gérer les afficheurs est une solution simple, peu onéreuse et demande peu de dépense au niveau écriture logiciel.

Le plus connu est le MAX7219 de chez Maxim, ce circuit on le trouve souvent monté sur une platine avec 8 afficheurs (voir sur Ebay, Amazon ou autres).

Le datasheet de ce composant est disponible ICI.
Certaines figures sont extraites de ce datasheet et sont la propriété de la société Maxim.

Le MAX7219 gère des afficheurs "cathode commune" et s'interface grâce à une liaison série qui d'après Maxim n'est pas compatible à 100% avec la "norme SPI", pour cela il y a le MAX7221.

Nous utiliserons quand même le circuit "SPI" intégré au PIC pour commander ce circuit, cela ne semble pas poser de problème mais attention quand même !.

Pour tester nous utiliserons la carte à base de 18F4525, il est bien sûr possible de choisir un autre PIC et d'adapter le hard et le soft à celui ci.

Le schéma général pour utiliser le circuit est donné par le constructeur :


max7219 utilisation

Pour notre usage : 

DIN = PORTC.5, CS = PORTC.0 et CLK = PORTC.3 ce qui correspond aux pins d'évolues au module SPI du 18F4525 ce qui n'est pas un hasard.

D'abord nous allons regarder le circuit et après nous verrons les différentes possibilités au niveau du programme avec plusieurs choix.

Le Max 7219 c'est :

  • une interface série,
  • la gestion de 8 afficheurs 7 segments ou 64 leds,
  • la possibilité de chaîner plusieurs circuits
En premier un regard sur le diagramme du circuit :

max7219 diagramme interne

La partie la plus intéressante pour nous est la partie basse du diagramme car elle nous donne la structure des données qu'il est nécessaire de fournir au circuit.
On retrouve le format de ces données dans la figure ci dessous :

max7219 data

Attention le synoptique du circuit nous informe que les bits sont envoyés de D15 à D0.

Un "message" est composé d'une adresse et d'une donnée et pour valider la broche "LOAD/CS"  est utilisée :


max7219 message


Maintenant regardons les différents registres qui sont accessibles à l'utilisateur :


max7219 registres

L'adresse 0x00 n'est pas utilisée, les adresses de 0x01 à 0x0F sont affectées à chaque afficheur.

L'adresse 0x09  permet de choisir le mode de décodage suivant le tableau suivant :

max7219 decodage

  • data 0x00 : pas de décodage, utilisée dans le cas d'utilisation de leds indépendantes,
  • data 0x01 : décodage pour l'afficheur 0 et pas de décodage pour les autres,
  • data 0x0F : décodage pour les afficheurs 0 à 3 et pas de décodage pour les autres,
  • data 0xFF : décodage pour tous les afficheurs.
Nous utiliserons dans notre test le décodage de tous les afficheurs soit une séquence : 0x09 et 0xFF.

L'adresse 0x0A permet de définir la luminosité de tous les afficheurs, pas de réglage pour chaque afficheur.
Les valeurs vont de 0x00 à 0x0F pour le maximum, la séquence est de type : 0x0A et 0X0E par exemple.

L'adresse 0x0B permet de définir le nombre d'afficheurs utilisés suivant le tableau :

max7219 nombre afficheurs

Pour nous ce sera la séquence suivante pour 8 afficheurs : 0X0B et 0x07.

L'adresse 0x0C permet de d'arrêter ou de mettre en fonctionnement l'afficheur suivant la valeur de la data, soit 0 pour l'arrêt ou 1 pour le fonctionnement normal.

L'adresse 0x0F permet de déclencher un test des afficheurs suivant la valeur de la data, soit 0 pour un fonctionnement normal ou 1 pour le mode test .

Dans le cas de l'utilisation de plusieurs circuits il faut connecter en parallèle les broches "LOAD/CS" ainsi que les broches "CLK" et de connecter la broche "Dout" du premier circuit à la broche "Din" du deuxième et ainsi de suite.

max7219 cablage

Au niveau logiciel nous utiliserons le module "SPI" du pic ou nous écrirons directement dans les registres adéquats ou nous utiliserons la bibliothèque "SPI" fournie avec XC8, la troisième solution consiste à écrire sa propre bibliothèque série.

Nous commencerons par l'écriture dans les registres du pic.

Les différents registres nécessaires pour utiliser le module "SPI" sont :
  • le registre SSPSTAT : registre d'état et de contrôle,
  • le registre SSPCON1 : registre de contrôle,
  • le registre PIR1 : registres pour la gestion des interruptions si celle ci sont utilisées,
  • le registre SSPBUF : registre pour l'envoi ou la réception des données

SSPSTAT registre pic

SSPCON1 registre pic

Le bit BF du registre SSPSTAT nous intéresse car il permet de savoir si la transmission (dans notre cas) est terminée et qu'il est possible de charger le registre SSPBUF avec une nouvelle valeur.

Typiquement nous utiliserons cette ligne de programme :   while (!SSPSTATbits.BF) ; 

Le bits SMP permet de choisir le moment d'échantillonnage des données d'entrée (non utilisé pour notre test), les bits  CKE du registre SSPSTAT et CKP du registre SSPCON1 permettent de choisir le mode, ils seront positionnés à 1 pour configurer le module dans le mode 0.

Dans le registre SSPCON1, les bits SSPEM et SSPM3:SSPM0 sont utilisés.
Le bit SSPEM permet d'autoriser le port série et de configurer les pins concernées, nous le mettrons à 1.

Les bits SSPM3:SSPM0 permettent de choisir le mode de fonctionnement (slave ou master), l'horloge utilisée ainsi que sa vitesse.
Pour notre test nous utiliserons le module en mode "master" avec une vitesse d'horloge de Fosc/64.

Dans notre fonction d'initialisation nous écrirons dans : 

SSPSTAR =  0b11000000
SSPCON1 = 0b00100010  

Puis pour écrire nous chargerons SSPBUF avec la donnée à envoyer et nous testerons la fin de l'envoi en testant le flag BF.



L'utilisation de la bibliothèque de XC8 permet de s'affranchir de la connaissance des différents registres, pour notre test nous utiliserons deux fonctions : 
  • OpenSPI(SPI_FOSC_64, MODE_00, SMPEND)
  • WriteSPI(data)   

La première permet de définir la fréquence, le mode de fonctionnement et l'échantillonnage des données d'entrée.
La seconde permet d'écrire la donnée à transmettre.

Voir dans le document "MPLAB_C18_libraries" le paragraphe 2.8 la description des différentes fonctions disponibles. 

La troisième possibilité est de ne pas utilisé le module SPI interne au Pic et d'écrire sa propre fonction "SPI".

Pour cela il faut :
  • configurer les ports utilisés,
  • écrire une fonction qui transmet la donnée sous forme série.
Comme nous utilisons uniquement la transmission de données les pins utilisées, soit CS, clk et dout, seront toutes configurées en sortie.
Cela donne par ex :

#define SPI_CS LATCbits.LATC0
#define SPI_clk LATCbits.LATC3
#define SPI_dout LATCbits.LATC5

TRISCbits.RC0 = 0;
TRISCbits.RC3 = 0;
TRISCbits.RC5 = 0;

La pin CS sera positionnée à 1 au cours de l'initialisation.

La fonction qui permet de transmettre sous forme série consiste à faire un test sur le bit concerné, suivant le résultat de ce test la pin "dout" est mise à 0 ou à 1, un petit coup de "clock" pour valider et ensuite à effectuer un décalage de 1. Ceci est à répéter bien évidemment huit fois pour transmettre nos 8 bits.

Il faut envoyer les bits : du plus fort au plus faible (D7 à D0) le test se fera donc sur le bit D7 et le décalage se fera à gauche.

Pour que tout cela fonctionne il faut mettre la pin "CS" à zéro pendant la transmission de la donnée, cette pin sera remise à un après la transmission du dernier bit.

Cela donne :

void ecr_7219_byte(unsigned char data)
{
    unsigned char cmp;
    SPI_dout = 0;
    for (cmp=8;cmp>=1;cmp--)
    {
        if (data & 0x80)                   // test bit D7
            SPI_dout = 1;
        else
            SPI_dout = 0;
        data = data<<1;                // décalage vers la gauche de 1
        __delay_us(1);
        SPI_clk = 1;                       // horloge 
        __delay_us(1);                 
        SPI_clk =0;
    }
}



MLABX et XC8 : Programme de démonstration


Dans le fichier disponible "test_Max7219" nous avons un exemple de fonctionnement pour les trois possibilités au niveau soft.


/*----------------------------------------------------------------------------------------------------------*/
Le coin de Patou "sait" "C"
/*----------------------------------------------------------------------------------------------------------*/


La boucle "FOR"



Elle est souvent utilisée pour exécuter un nombre déterminé (ce n’est pas une obligation) d’instructions incluses dans la boucle.
La syntaxe est :           for (expression 1 ; expression 2 ; expression 3)

avec expression 1 et expression 3 qui sont le plus souvent des affectations et expression 2 une expression de relation.

Par exemple :

for (cmpt = 0 ; cmpt < cmptmax ; cmpt++)
{

 instructions ;

}

Il est possible de la remplacer par une boucle « while » :

cmpt =0 ;
cmptmax = 100 ;
while (cmpt < cmptmax)
{
 instructions ;
 cmpt++ ;
}


Un autre exemple d’une boucle « for » dont on ne sait pas à l’avance le nombre d’itérations :

for (cmpt = 0 ; tab[cmpt] == ‘ ‘ ; cmpt++)
{

 instructions ;

}

Dans ce cas la boucle se termine au premier espace trouvé dans le tableau (attention il n'y a pas de limite, ceci n'est qu'un exemple).


Le choix est souvent une affaire d’habitude ou de goût,

A éviter :

  • Ne pas indiquer les expressions 1 à 3 comme ci dessous :
for ( ; ; )

  une belle boucle sans fin, un « break » ou un « return » peuvent nous sauver.


  • Modifier à l’intérieure de la boucle « expression 2 », cela est possible mais pas recommandé.







Aucun commentaire:

Enregistrer un commentaire