Je vous propose un tutoriel sur le fonctionnement des afficheurs 7 segments "Digit" avec MikroC.
Les pré-requis :
- Le Modulo : %.
- La fonction : switch.
- Fonction avec paramètres d'entrée et de sortie.
Configuration :
- PIC18F46K22
- IDE : MikroC Pro for PIC Version 6.6.3
- Compilateur : Mikro prog suite fo PIC V 2.32
- Plaque Easy PIC V7
Un afficheur 7 segments appelé également "digit" est un composant permettant l'affichage de chiffres et de lettres en combinant et en allumant ces différents segments.
Chaque segment ( qui sont des leds) doit être connecté à une broche de notre PIC. Suivant l'afficheur 7 segments utilisé, anode ou cathode commune il faudra un "état haut" ou un "état bas" pour allumer celui-ci.
Le Schéma :
Voici le schéma de la partie "DIGIT" de la carte EasyPic7. Chaque segments des digits est relié au PORTD de 0 à 7 . "0" correspondant au segment "a" et 7 à "dp" pour "décimal point".
Les transistors sont reliés au PORT A ( de RA0 à RA3) et active ou non les digits correspondants, le premier Digit(à droite) est branché sur RA0.
Nous allons voir comment se servir d'un seul digit pour commencer !!!
Le but :
Nous allons créer un compteur, comptant de 0 à 9. Il devra afficher sa valeur sur un DIGIT( RA0). Aucune précision n'est souhaité et une pause servira de temporisation.
Une fonction permettra de convertir le chiffre de notre compteur, en une valeur définissant les segments à allumés.
par exemple pour affichés "1" : il faudra affiché les deux segments verticaux à droite .
ces deux segments correspondent aux segments "b" et "c". Ce qui fais 0b00000110 = 0x06
Programme pour un seul "digit" :
Code : Tout sélectionner
/*##################################################################################
############################## Variable / Constante #########################
##################################################################################*/
unsigned int compteur, num ; // Déclaration des variables
/*##################################################################################
########################### CONVERTIR LE CHIFFRE #############################
##################################################################################*/
unsigned short conversion(unsigned short num) // Fonction avec paramètres d'entrée et de sortie
{ // suivant le chiffre du compteur on renvoie la valeur pour allumer tel ou tel segments sur le PORTD
// Utilisation de la commande "switch"
switch (num) { // "Switch" compare la valeur contenu dans "num" aux valeurs "case" ci dessous
// Si une valeur est trouvée, "Switch" renvoie la valeur correspondante et sort
// Une seule valeur est prise en compte
case 0 : return 0x3F; // Affiche un "0" avec l'allumage de six segments 3F = 00111111 du PORTD
case 1 : return 0x06; // |
case 2 : return 0x5B; // |
case 3 : return 0x4F; // |
case 4 : return 0x66; // |
case 5 : return 0x6D; // |
case 6 : return 0x7D; // |
case 7 : return 0x07; // |
case 8 : return 0x7F; // |
case 9 : return 0x6F; // Affiche un "9" par l'allumage des segments correspondants
}
}
/*##################################################################################
############################ PROGRAMME PRINCIPAL ##############################
##################################################################################*/
void main() {
ANSELA = 0; // Configure le PORTA en Digital
ANSELD = 0; // Configure le PORTD en Digital
TRISA = 0; // Configure le PORTA en SORTIE
LATA = 0; // affecte 0 aux broches du PORTA
TRISD = 0; // Configure le PORTD en SORTIE
LATD = 0; // affecte 0 aux broches du PORTD
LATA.B0 = 1; // Mise à l'état haut de RA0 pour activer le premier afficheur.
compteur = 0; // Initialise notre compteur à 0.
//########################## BOUCLE INFINIE ##################################
do {
if (compteur >= 10) compteur = 0 ; // Si le compteur est supérieur ou égale a 10 alors on le remet à 0
LATD = conversion(compteur) ; // on affecte la valeur convertie pour affichage sur le PORT D
compteur = compteur++; // On incrémente notre compteur.
delay_ms(1000); // On marque une pause de 1 seconde.
} while(1); // On reboucle
}
Remarques :
Le problème avec les digits c'est qu'ils sont gourmands en connexions, 8 en général, 7 pour les segments et 1 pour le point. Donc si on veut afficher des nombres avec plus de un chiffre, ça devient assez problématique. Pour éviter de monopoliser autant de broches , on va utiliser le multiplexage .
le multiplexage consiste à allumer successivement les afficheurs les uns après les autres, très rapidement . On ne verra pas de clignotement grâce a la persistance rétinienne.
Le déroulement se fera ainsi :
- activation du premier digit -> Affichage d'un chiffre -> désactivation du premier digit
- activation du deuxième digit -> Affichage d'un chiffre -> désactivation du deuxième digit
- activation du troisième digit -> Affichage d'un chiffre -> désactivation du troisième digit
- activation du quatrième digit -> Affichage d'un chiffre -> désactivation du quatrième digit
- et on reboucle.
Programme pour 4 afficheurs 7 segments :
Voici le programme, non optimisé, pour bien vous faire comprendre le principe. Ici un afficheur sera actif toutes 15ms pendant 5 ms. On ne voit aucun clignotement !.
Bien évidemment suivant votre programme principal, d'autres solutions plus optimisées sont largement conseillées. Ici on ne fait que compter et afficher, c'est rarement le cas dans les projets !
Notez la fonction modulo, qui nous sert à extraire les chiffres correspondant aux différentes unités .
Code : Tout sélectionner
/*##################################################################################
############################## Variable / Constante #########################
##################################################################################*/
unsigned int compteur, num,millier, centaine, dizaine, unite; // Déclaration des variables
/*##################################################################################
########################### CONVERTIR LE CHIFFRE #############################
##################################################################################*/
unsigned short conversion(unsigned short num) // Fonction avec parametres d'entrée et de sortie
{ // suivant le chiffre du compteur on renvoie la valeur pour allumer tel ou tel segments sur le PORTD
// Utilisation de la commande "switch"
switch (num) { // "Switch" compare la valeur contenu dans "num" au valeur "case" ci dessous
// Si une valeur est trouvée, "Switch" renvoie la valeur toucorrespondante et sort
// Une seule valeur est prise en compte
case 0 : return 0x3F; // Affiche un "0" avec l'allumage de six segments 3F = 00111111 du PORTD
case 1 : return 0x06; // |
case 2 : return 0x5B; // |
case 3 : return 0x4F; // |
case 4 : return 0x66; // |
case 5 : return 0x6D; // |
case 6 : return 0x7D; // |
case 7 : return 0x07; // |
case 8 : return 0x7F; // |
case 9 : return 0x6F; // Affiche un "9" par l'allumage des segments correspondants
}
}
/*##################################################################################
############################ PROGRAMME PRINCIPAL ##############################
##################################################################################*/
void main() {
ANSELA = 0; // Configure le PORTA en Digital
ANSELD = 0; // Configure le PORTD en Digital
TRISA = 0; // Configure le PORTA en SORTIE
LATA = 0; // affecte 0 aux broches du PORTA
TRISD = 0; // Configure le PORTD en SORTIE
LATD = 0; // affecte 0 aux broches du PORTD
compteur = 0; // Initialise notre compteur à 0.
//########################## BOUCLE INFINIE ##################################
do {
millier = compteur/1000 %10 ; // Calcul de la valeur des milliers . On divise le compteur par 1000 on prend le modulo
LATD = conversion(millier); // On convertit la valeur calculée en segments pour affichage.
LATA = 8; // On active le 4iéme digit ( 0b00001000) en mettant le bit 3 à 1
delay_ms (5); // On marque une pause pour afficher le chiffre
centaine = compteur/100 %10; // calcul de la valeur des centaines . On divise le compteur par 100 on prend le modulo
LATD = conversion(centaine); // On convertit la valeur calculée en segments pour affichage.
LATA = 4; // On active le 3iéme digit ( 0b00000100) en mettant le bit 2 à 1
delay_ms (5); // On marque une pause pour afficher le chiffre
dizaine = compteur/10 %10; // calcul de la valeur des dizaines . On divise le compteur par 10 on prend le modulo
LATD = conversion(dizaine); // On convertit la valeur calculée en segments pour affichage.
LATA = 2; // On active le 2iéme digit ( 0b00000010) en mettant le bit 1 à 1
delay_ms (5); // On marque une pause pour afficher le chiffre
unite = compteur %10; // calcul de la valeur des unités . On prend le modulo
LATD = conversion(unite); // On convertit la valeur calculée en segments pour affichage.
LATA = 1; // On active le 1er digit ( 0b00000001) en mettant le bit 0 à 1
delay_ms (5) ; // On marque une pause pour afficher le chiffre
compteur = compteur++ ; // On incrémente notre compteur
} while(1); // On reboucle
}
Conseils :
- Conseil de Paulfjujo : Sur les PIC 18F, l'affection d'une valeur sur un PORT se fait avec le mot LATx plutôt que PORTx.
- Ici nous utilisons des delay_ms, pour temporiser l'affichage, sinon cela y aurai bien trop vite pour nos yeux et on verrait tous les segments s'allumés en même temps. N'oubliez pas que pendant un delay_ms, votre µC ne peut rien faire.
La bonne méthode serait de passer par un timer afin de libérer notre µC pendant ces pauses. voici un exemple de ce qui pourrait être fait
Vidéo :
http://www.dailymotion.com/video/x37y6p2
Comme d'habitude, pour les experts si vous voyez des erreurs ou avez des astuces , vous pouvez poster à la suite, je mettrais le Tuto à jour .
Pour les moins Experts qui veulent approfondir ou poser des questions , n’hésitez surtout pas et postez aussi à la suite!.