Lorsqu’il est nécessaire de communiquer des informations à l’utilisateur, l’ami le plus fidèle des microcontrôleurs est souvent un afficheur LCD, et particulièrement ceux dotés d’un contrôleur HD44780. Ces écrans, dont la taille varie de 8 caractères pour les plus petits, à plus de 4 lignes de 20 caractères pour les plus grands, sont particulièrement aisé à utiliser grâce à leur contrôleur, qui utilise un protocole de communication très simple. Mais je ne m’étendrai pas sur le sujet, celui-ci ayant déjà fait l’objet de l’article suivant.
Cependant, dans certains projets, l’utilisation de ces écrans reviendrait à utiliser un Hummer pour se rendre au travail : ça passe difficilement les virages, ça se gare de justesse, et on fini par se demander si on a réellement besoin de tant pour effectuer ces simples trajets quotidiens. C’est par exemple le cas lorsqu’on souhaite juste afficher une température : là où 2 caractères sont nécessaires, le plus petit afficheur LCD en propose 8. Un peu « overshoot », non ?
Travaillant justement sur un de ces projets qui ne requièrent que l’affichage d’un nombre à 2 chiffres, j’ai mis au point quelques fonctions simples afin de faciliter l’utiliser de ces afficheurs. Ces fonctions sont prévues pour fonctionner avec un afficheur double ( 2 chiffres ) qu’il soit à anode commune, ou cathode commune, mais elles fonctionneront telles quelles avec un afficheur simple ( 1 chiffre ) et ne demanderont que des modifications simples pour fonctionner avec des afficheurs avec plus de chiffres. L’ensemble du code est écrit pour le compilateur XC8 de Microchip, mais devrait fonctionner sans difficultés sur d’autres afficheurs.
Introduction aux afficheurs 7 segments
Mais commençons par le début, en revenant sur le principe de fonctionnement des afficheurs 7 segments : il s’agit ni plus ni moins de 7 leds, reliées ensemble par l’une de leur broche. Si ce sont les cathodes (coté négatif) des leds qui sont reliées ensemble, on parle d’afficheur à cathode commune. L’inverse ( leds reliées par leurs anodes) est bien entendu nommé anode commune :
Il a souvent une led en plus, qui correspond au point décimal. Pour utiliser cet afficheur avec un microcontrôleur PIC, rien de plus simple, la broche « commune » est reliée à la masse dans le cas d’un afficheur à cathode commune, et au +5V du PIC pour un afficheur a anode commune. Les broches restantes sont alors reliées à un port du PIC, chacune à travers une résistance de 1kohms, et c’est parti !
Oui, mais maintenant on souhaiterait utiliser un afficheur à 2 chiffres. On peut bien sur appliquer la même méthode, en utilisant 2 ports du PIC, un pour chaque afficheur. Mais ça commence à faire un sacré nombre de broches, et on risque de ne plus pouvoir faire grand chose d’autre de notre PIC. D’ailleurs, les afficheurs à plusieurs chiffres du commerces ne sont pas conçus comme ça. En fait, les chiffres sont câblés en parallèle, et seule la broche commune à tous les segments d’un même chiffre permet de sélectionner ce chiffre :
Comme il s’agit d’un afficheur tiré d’un appareil qui affichait l’heure, les leds UC et LC correspondent aux doubles points centraux.
Pour allumer une led, faut sélectionner son chiffre (« digit »), puis le segment. Par exemple, pour allumer la led B du digit 2, on relie la broche 8 au +5V, puis la broche 10 à la masse à travers un résistance. Simple non ?
Mais je sens une question pointer : « Avec ce système, comment fais-tu pour allumer la led B du digit 2 ET la led C du digit 1 sans allumer les autres ? « .
La réponse est simple, on ne peut tout simplement pas. C’est une des limites de ce système. Cependant, il permet de piloter 32 leds avec seulement 12 pins, il faut bien qu’il y ait un inconvénient quelque part.
« Mais pourtant, n’importe quel réveil numérique est bien capable d’afficher 4 chiffres différents en même temps ».
En fait, pas exactement en même temps, et c’est là toute l’astuce ! Il n’y a qu’un chiffre d’allumé à la fois, et même un seul segment sur certains appareils. La seule contrainte est d’alterner assez rapidement entre les chiffres pour que ceux-ci semblent fixes pour l’oeil humain, typiquement un clignotement à 50 Hz est quasiment imperceptible. En dessous de 30Hz, les chiffres commencent à scintiller visiblement, et si on ralentit encore, la lecture de l’afficheur devient pénible.
Maintenant que les bases sont posées, rentrons dans le vif du sujet : l’utilisation d’un afficheur double avec un microcontrôleur PIC :
Schéma de câblage
Le schéma varie légèrement en fonction du type (Anode ou Cathode commune) de l’afficheur :
Les différences entre les deux schémas sont : le type des transistors, NPN pour l’afficheur à Cathode commune, et PNP pour celui à Anode commune, et la tension présente sur l’émetteur des transistors (la masse dans un cas, et le +5V dans l’autre).
Pour les résistances, si vous ne souhaitez pas les calculer précisément, une valeur de 1kohms pour toutes les résistances devrait convenir dans la plupart des cas. Pour les transistors, des modèles courant, comme le 2N2222 (NPN) et le 2N2907 (PNP) sont tout indiqués.
Les broches du PIC sont données à titre indicatif, il s’agit de la configuration par défaut pour le code présenté plus loin. Il est tout à fait possible d’utiliser d’autres broches, mais un port complet doit être dédié à l’afficheur (ici le port B).
Le code : ma bibliothèque SevenSeg
Parler de bibliothèque est ici un peu exagéré, puisqu’il n’y a en tout et pour tout que 5 fonctions :
- void sevenSegRefreshDisplay(void) : cette fonction doit être appelée régulièrement, l’idéal étant de l’appeler depuis une interruption générée par le débordement d’un timer. Chaque appel de cette fonction alterne l’affichage entre le chiffre des unité et celui des dizaines. Il faut l’appeler au minimum 60 fois par seconde pour éviter un scintillement trop visible de l’afficheur, l’idéal étant plus de 100 fois par seconde. Les variables sevenSegUnitValue et sevenSegDigitValue indiquent quels segments de chaque digit doit s’allumer, chaque bit correspondant à un segment, dans l’ordre a b c d e f g dp.
- void sevenSegSetRawValue(unsigned char decade, unsigned char unit) : cette fonction permet de modifier directement les variables sevenSegUnitValue et sevenSegDigitValue qui indiquent quels segments de chaque digit doivent d’allumer.
- void sevenSegSetNumber(unsigned char valueToDisplay) : cette fonction permet d’afficher un nombre, compris entre 0 et 99 inclus, passé en paramètre. Tout nombre supérieur à 99 provoque l’affichage des lettres « HI ».
- void sevenSegSetUnitDigit(unsigned char digitValue) : cette fonction permet d’afficher un chiffre sur le digit des unités. Le chiffre affiché correspond à la valeur de la variable digitValue modulo 10.
- void sevenSegSetDecadeDigit(unsigned char digitValue) : cette fonction permet d’afficher un chiffre sur le digit des dizaines. Le chiffre affiché correspond à la valeur de la variable digitValue modulo 10.
Configuration
Toute la configuration se fait est éditant la section SETTINGS du fichier 7segment.h.
Par défaut, les signaux générés correspondent à un afficheur a Cathode commune. Si un afficheur à Anode commune est utilisée, il faut dé-commenter la ligne suivante :
//#define sevenSegCommonAnode
Il est également possible de configurer les I/O utilisées pour l’afficheur, le seul impératif étant l’utilisation d’un port complet pour le pilotage des segments de l’afficheur. Il aurait été possible de pouvoir utiliser 8 broches séparées à cet effet, mais cela demanderait beaucoup de calculs inutiles au PIC.
Utilisation
Ajouter les fichiers 7segment.h et 7segment.c au projet MPLAB, et inclure 7segment.h dans les fichiers où l’on souhaite pouvoir utiliser les fonctions de la bibliothèque.
Le fichier Demo.c inclus le code nécessaire au test de l’affichage, pour un PIC16F628A, mais devrait faire l’affaire pour beaucoup d’autres PICs de la série 16F (commenter la ligne CMCON=0x07; au besoin).
Téléchargement
L’archive contenant les fichier cités précédemment est téléchargeable ICI.
Conclusion
Cette bibliothèque, bien que toute petite, permet de mettre rapidement en place une interface à base d’afficheurs 7 segments, en offrant les fonctions qui me semblent indispensables, notamment l’affichage directe de nombres. Elle ne gère pour l’instant que les afficheurs doubles, mais peut être étendue facilement aux afficheurs triples, quadruples, etc… ,facilement.
Un exemple en vidéo du résultat possible, affichage de la valeur d’une variable incrémentée de 0 à 128 :
Comme d’habitude, n’hésitez pas à me faire part de vos remarques, questions, etc…
4 Commentaires
Passer au formulaire de commentaire
Excellent! Tout simplement excellent!
J’ai pas tout compris, mais c’est l’avantage des bons tutos c’est que l’on a pas à tout comprendre pour pouvoir les suivre.
C’est quand que tu nous fait une présentation à COAGUL que je te voie à l’oeuvre?
Auteur
Merci. =)
Pour COAGUL, je ne fais pas de présentation tout de suite. A moyen terme, je vais essayer de remettre le projet Floppy Orchestra (qui consiste à jouer de la musique avec les lecteurs disquettes) en fonctionnement, avec un arduino, ce que je ne manquerai pas de vous présenter !
bjr pourrai-je avoir le code pour afficher de 0 a 99 sur deux afficheurs 7 segments a l’aide d’un PIC
Auteur
Bonjour,
tout mon code est dispo dans la section « téléchargement » de l’article.