Afficheurs 7 segments - 4 x 7 segmenst et 74HC595
Table des matières
TL;DR
Utiliser un afficheur 4 x 7 segments (et un^Wdeux 74HC595).
Afficheur 1 x 7 segments
Ce genre d'afficheur cumule 2 inconvénients: il mobilise 8 broches (1 par segment + 1 pour le point décimal) et ne permet d'afficher qu'un seul chiffre. Même si une blue pill est bien fournie, je trouve que c'est un prix lourd à payer.
Afficheur 4 x 7 segments
Il faut cette fois-ci 12 broches: toujours 8 par chiffre et 4 autres pour sélectionner le chiffre. Pour afficher '1984' il faut:
- sélectionner le chiffre des unités
- afficher 4 un "certain" temps
- sélectionner le chiffre des dizaines
- afficher 8 un "certain" temps
- sélectionner le chiffre des centaines
- afficher 9 un "certain" temps
- sélectionner le chiffre des milliers
- afficher 1 un "certain" temps
- recommencer
Pour sélectionner un chiffre on passe sa broche à l'état bas dans le cas d'un afficheur à cathode commune ou à l'état haut pour un afficheur à anode commune. Principal inconvénient de ce type d'afficheur: il faut afficher les chiffres en permanence sous peine de provoquer un clignotement assez désagréable. Cela implique donc une boucle:
while (1) { display(number); }
74HC595
Ce petit circuit intégré permet de piloter 8 sorties depuis 3 entrées. On trouve assez facilement des exemples d'utilisation de ce registre à décalage qui est le compagnon idéal d'un afficheur 7 segments: on pilote les segments de l'afficheur à l'aide des sorties du 74HC595.
Ma représentation d'un 74HC595:
enum IC_74HC595_PINS {
IC_74HC595_SER, // 14 DS
IC_74HC595_RCLK, // 12 ST_CP
IC_74HC595_SRCLK, // 11 SH_CP
IC_74HC595_PINS_SIZE
};
typedef struct {
GPIO_TypeDef *gpio;
uint8_t pins[IC_74HC595_PINS_SIZE];
} IC_74HC595_TypeDef;
Je m'impose une contrainte: les broches doivent faire partie du même GPIO. Le code suivant contrôle les sorties d'un 74HC595:
1 void
2 ic_74hc595_send(IC_74HC595_TypeDef *ic_74hc595, uint8_t byte) {
3 ic_74hc595->gpio->BRR = (1 << ic_74hc595->pins[IC_74HC595_RCLK]); // pin low
4 for (uint8_t i = 0; i < 8; i++) {
5 ic_74hc595->gpio->BRR = (1 << ic_74hc595->pins[IC_74HC595_SRCLK]); // pin low
6 if ((byte >> i) & 0x01)
7 ic_74hc595->gpio->BSRR = (1 << ic_74hc595->pins[IC_74HC595_SER]); // 1: pin high
8 else
9 ic_74hc595->gpio->BRR = (1 << ic_74hc595->pins[IC_74HC595_SER]); // 0: pin low
10 ic_74hc595->gpio->BSRR = (1 << ic_74hc595->pins[IC_74HC595_SRCLK]); // pin high
11 }
12 ic_74hc595->gpio->BSRR = (1 << ic_74hc595->pins[IC_74HC595_RCLK]); // pin high
13 }
Afficheur 4 x 7 segments et 74HC595
En utilisant un deuxième 74HC595, je n'utilise que 6 broches de la blue pill: 3 pour contrôler les segments, 3 pour sélectionner un chiffre. On distingue sur cette salade de câble (2070x1456 px, 501Ko):
- mini "breadboard" blanche: l'afficheur 4 x 7 segments, les résistances pour sélectionner un chiffre et la mini salade de fil gris/orange/rouge pour contrôler les segments
- mini "breadboard" verte: 74HC595 pour sélectionner un chiffre
- mini "breadboard" orange: 74HC595 pour contrôler les segments
- blue pill avec 6 broches occupées: GPIOA 0-2 et GPIOA 5-7. Le circuit est alimenté en 3.3V (bas de l'image)
- ST-LINK v2 branché sur un hub usb 3.0 auto-alimenté (je ne pourrai plus me passer de ses interrupteurs, vraiment très pratique)
Le code
Le code complet: https://gitlab.com/dsx/blue-pill/-/tree/master/stm32f103c8t6/05_4x7_segments_74hc595
A suivre
L'ADC de la blue bill est sur 12 bits, sa valeur maximale est de 4095 et tient sur 4 chiffres ... Coïncidence ? Je ne crois pas.