Fabrication industrielle
Internet des objets industriel | Matériaux industriels | Entretien et réparation d'équipement | Programmation industrielle |
home  MfgRobots >> Fabrication industrielle >  >> Industrial programming >> VHDL

Contrôleur VHDL double afficheur 7 segments pour Pmod SSD – Intégration FPGA simplifiée

Dans cet article, je présente un module VHDL capable d'afficher un nombre à deux chiffres sur le Pmod SSD : afficheur sept segments de Digilent. L'afficheur double 7 segments est compatible avec l'interface Pmod, ce qui signifie que vous pouvez l'utiliser sans aucune soudure. Il s'insère dans le connecteur Pmod, standard sur de nombreuses cartes de développement FPGA.

Pour tester l'implémentation VHDL, j'utilise la Lattice iCEstick, une carte de développement FPGA low-cost avec un connecteur Pmod. En plus de l'iCEstick, vous avez besoin d'un câble séparateur Pmod 2×6 broches vers Double 6 broches pour convertir du connecteur Pmod parallèle de l'iCEstick vers la version en série de la fiche qu'attend l'afficheur 7 segments. Enfin, je recommande un câble d'extension USB type-A car brancher l'iCEstick directement sur le port USB de l'ordinateur est peu pratique.

Fonctionnement des afficheurs 7 segments

Il existe de nombreux afficheurs 7 segments différents sur le marché. Le nombre de chiffres varie entre eux, tout comme l'interface physique et le brochage. Une solution générique couvrant tous les afficheurs 7 segments possibles ne serait probablement pas très conviviale. Cependant, vous pouvez utiliser le code présenté dans cet article comme base et l'adapter à vos besoins.

L'image ci-dessus provient de la fiche technique du module Pmod Digilent. Elle montre comment l'afficheur 7 segments se connecte aux broches Pmod. Ces broches sont directement accessibles au FPGA sur l'iCEstick.

Sept des broches contrôlent chacune un segment de l'afficheur. En appliquant une valeur logique haute sur une telle broche, le segment correspondant s'allume sur l'afficheur. Mais il y a deux chiffres sur cet afficheur, et nous ne pouvons en contrôler qu'un à la fois. La broche P4/C sur le connecteur J2 sélectionne l'un ou l'autre chiffre. Quand la tension logique sur cette broche est '0', le chiffre de droite s'allume ; si c'est '1', le chiffre de gauche est activé.

Le point décimal « DP » n'est pas connecté et ne peut pas être accédé.

L'entité

Le code ci-dessous montre l'entité de notre module VHDL seg7. L'entité a un port générique avec une constante nommée clk_cnt_bits. Elle définit la longueur d'un compteur interne qui contrôle le taux de rafraîchissement de l'afficheur, la fréquence d'alternance entre les chiffres de gauche et de droite.

La fréquence exacte n'est pas critique. Choisissez une longueur de compteur dans la plage de 50 à quelques centaines de Hertz. La formule qui détermine le taux de rafraîchissement est refresh_hz = 2clk_cnt_bits / clk_hz.

entity seg7 is
  generic (
    -- refresh_hz = (2 ** clk_cnt_bits) / clk_hz
    clk_cnt_bits : integer
  );
  port (
    clk       : in  std_logic;
    rst       : in  std_logic;
    value     : in  integer range 0 to 99;
    segments  : out std_logic_vector(6 downto 0);
    digit_sel : out std_logic
  );
end seg7;

En plus de l'horloge et du reset, l'entité a un signal d'entrée : la valeur à afficher sur l'afficheur 7 segments. Le signal value est de type entier restreint à l'intervalle 0 à 99 car ce sont les seules valeurs numériques qu'il est possible d'afficher avec seulement deux chiffres.

Les signaux de sortie sont les sept segments sous forme de vecteur et le signal de sélection de chiffre pour choisir d'allumer soit le chiffre de gauche, soit celui de droite.

Représentation d'un décimal codé binaire (BCD)

Pour représenter les chiffres affichés, nous utiliserons le format connu sous le nom de décimal codé binaire (BCD). Bien qu'une représentation binaire soit la façon la plus efficace de stocker le nombre décimal, nous rencontrons des problèmes quand nous essayons de le diviser en chiffre de gauche et de droite pour l'affichage. Nous ne pouvons pas distinguer les chiffres décimaux simplement en tranchant le vecteur utilisé pour stocker le nombre.

subtype digit_type is integer range 0 to 9;
type digits_type is array (1 downto 0) of digit_type;
signal digit  : digit_type;
signal digits : digits_type;

Comme montré dans le code ci-dessus, nous déclarons un sous-type d'entier sur l'intervalle 0 à 9 pour décrire la valeur qui peut être représentée par un chiffre décimal. Ensuite, nous déclarons un nouveau type tableau qui peut contenir deux telles valeurs BCD. Le signal digit contient le nombre actuellement affiché soit sur le côté gauche, soit sur le côté droit de l'afficheur. D'autre part, le signal digits contient les caractères décimaux individuels pour les deux chiffres, tels qu'ils apparaîtront à une personne regardant l'écran.

Conversion décimal vers BCD

L'entrée de ce module, value, est un entier sur l'intervalle 0 à 99, une représentation binaire du nombre. Nous devons convertir cet entier unique en deux entiers sur l'intervalle 0 à 9, les BCD.

L'algorithme standard pour cela est le Double Dabble, aussi connu sous le nom d'algorithme shift-and-add-3. Bien que ce soit bien de l'utiliser, j'opterai pour une solution plus courte dans notre cas car nous n'avons que deux chiffres à séparer.

digits(1) <= value / 10;
digits(0) <= value - ((value / 10) * 10);

En utilisant la division entière comme montré dans le code ci-dessus, nous pouvons isoler le chiffre décimal le plus significatif et l'assigner au signal digits(1). Pour récupérer le chiffre le moins significatif, nous pouvons soustraire le chiffre le plus significatif du signal value, ne nous laissant que le nombre à assigner au signal digits(0).

Comptage des cycles d'horloge

Différer le temps dans les FPGA est simplement une question de comptage de cycles d'horloge. La période d'horloge est le seul intervalle de temps prévisible sur lequel vous pouvez compter dans votre code VHDL. Le code ci-dessous montre le signal clk_count, que nous utilisons pour compter les cycles d'horloge. Le générique clk_cnt_bits détermine combien de bits réserver pour ce signal non-signé.

signal clk_cnt : unsigned(clk_cnt_bits - 1 downto 0);

Le taux de rafraîchissement exact de l'afficheur est de moindre importance, c'est pourquoi j'ai opté pour un type non-signé ici. Cela nous permet d'utiliser le comportement d'auto-emballage (wraparound) du signal non-signé. Tout ce que nous avons à faire est d'incrémenter le compteur à chaque front montant de l'horloge. Le code ci-dessous montre le processus synchrone avec reset qui s'en charge.

COUNT_PROC : process(clk)
begin
  if rising_edge(clk) then
    if rst = '1' then
      clk_cnt <= (others => '0');
    else
      clk_cnt <= clk_cnt + 1;
    end if;
  end if;
end process;

Alternance entre les chiffres

Maintenant que nous avons le compteur libre qui fonctionne, nous pouvons utiliser le bit de poids fort (MSB) du signal de compteur non-signé pour basculer entre les deux chiffres. Le MSB alterne entre '0' et '1' avec un cycle de travail de 50 %. La première ligne du code ci-dessous définit le signal digit_sel basé sur la valeur du MSB. La seconde ligne implémente un multiplexeur avec le MSB utilisé comme sélecteur. Il transmettra la valeur du chiffre actif depuis le tableau digits vers le signal digit.

digit_sel <= clk_cnt(clk_cnt'high);
digit     <= digits(0) when clk_cnt(clk_cnt'high) = '0' else digits(1);

Encodeur BCD vers 7 segments

L'étape finale du module seg7 est de traduire le BCD stocké dans le signal digit en représentation visuelle sur l'afficheur 7 segments. Le code ci-dessous montre un processus qui y parvient en utilisant une instruction case.

La position dans le vecteur de chaque littéral de bit correspond à un segment sur l'afficheur. L'index 0 équivaut au segment A, l'index 1 au B, et ainsi de suite jusqu'à l'index 6, qui contrôle le segment G. Les correspondances des segments aux index de vecteur sont dérivées de la fiche technique de l'afficheur 7 segments Digilent.

ENCODER_PROC : process(digit)
begin
  case digit is
    when 0 => segments <= "0111111";
    when 1 => segments <= "0000110";
    when 2 => segments <= "1011011";
    when 3 => segments <= "1001111";
    when 4 => segments <= "1100110";
    when 5 => segments <= "1101101";
    when 6 => segments <= "1111101";
    when 7 => segments <= "0000111";
    when 8 => segments <= "1111111";
    when 9 => segments <= "1101111";
  end case;
end process;

La sortie

Le module VHDL seg7 affichera sur l'afficheur ce que vous assignez au signal d'entrée value. Dans le testbench, nous incrémentons le signal value une fois par seconde. Ensuite, nous simulons un peu plus de 100 secondes pour observer le point de rebouclage du compteur value.

La forme d'onde ci-dessus provient de ModelSim. Elle montre la première partie de la simulation, où la valeur a compté de 0 à 15. On voit que les nombres dans le tableau digits comptent aussi. Les unités (0) comptent à chaque fois que le signal value change, tandis que les dizaines (1) s'incrémentent tous les dix nombres.

Vous pouvez télécharger le projet ModelSim, incluant le testbench, en utilisant le formulaire ci-dessous.

Si vous implémentez le module seg7 comme module principal sur le FPGA, l'afficheuraffichera très probablement un « 00 » stable. C'est parce que '0' est la valeur par défaut la plus courante donnée aux signaux non initialisés dans les FPGA. Quand le signal value est mis à tous les zéros, l'afficheur affichera juste cela.

Pour faire défiler tous les nombres d'entrée possibles, j'ai créé un module VHDL wrapper qui incrémente le signal value dix fois par seconde. J'ai ensuite instancié le module seg7 dans le wrapper avant d'implémenter le design sur la Lattice iCEstick. La vidéo GIF en boucle ci-dessous montre à quoi ressemble le design implémenté sur l'afficheur 7 segments.

Achat du Pmod SSD : Afficheur 7 segments

L'afficheur 7 segments utilisé dans cet article vient de Digilent. Vous pouvez acheter le module Pmod sur la boutique en ligne Digilent, ou chez l'un des nombreux revendeurs. Dans la liste ci-dessous, j'ai mis des liens vers la page produit de l'afficheur dans quelques boutiques d'électronique en ligne qui le proposent.

Notez que si vous voulez utiliser l'afficheur 7 segments Digilent avec la Lattice iCEstick, ou toute autre carte de développement FPGA qui a un connecteur Pmod 6×2 broches, vous avez aussi besoin d'un câble séparateur. Le câble est disponible chez Digilent, Digi-Key, Mouser et RS Electronics.

De plus, tous les composants sont disponibles auprès de divers vendeurs sur Amazon et eBay.

Cours VHDL utilisant l'afficheur 7 segments Digilent

J'ai lancé un nouveau cours VHDL et FPGA pour débutants absolus. Dans ce cours, j'utilise l'afficheur 7 segments de Digilent et la carte de développement FPGA Lattice iCEstick pour enseigner le VHDL. Cliquez sur le lien ci-dessous pour en savoir plus sur le cours !

FPGA et VHDL Fast-Track : Hands-On pour Débutants Absolus

Vous connaissez la programmation mais êtes nouveau en VHDL ?
Vous avez besoin d'une courte introduction à ce sujet peu familier ?
Votre emploi du temps est chargé sans temps pour étudier ?

Comprenez les bases du développement FPGA en VHDL en quelques soirées ! Ce cours est pour les professionnels IT et étudiants qui ont besoin d'un survol rapide du sujet. Avec ce cours et la carte de développement Lattice iCEstick low-cost, vous développerez du vrai matériel en quelques heures.

Cliquez ici pour en savoir plus et vous inscrire :
FPGA et VHDL Fast-Track : Hands-On pour Débutants Absolus

VHDL

  1. Intégration des bibliothèques IP Quartus Prime dans VUnit : Guide étape par étape
  2. Quiz VHDL Basics - Partie 4 : Vérifiez votre compréhension
  3. Maîtriser les boucles While en VHDL : contrôle d'itération dynamique
  4. Améliorer la vérification matérielle avec un testbench interactif basé sur Tcl
  5. Maîtriser Xilinx Vivado : Analyseur de logique intégré (ILA) et Entrée/Sortie virtuelle (VIO) pour le débogage
  6. Variables VHDL expliquées : exemples pratiques et règles pour un design fiable
  7. Concevoir un contrôleur de servo RC basé sur FPGA avec PWM précis
  8. Maîtriser std_logic_vector : Création de vecteurs de signaux en VHDL
  9. Maîtriser les types Signé vs Non-signé en VHDL : insights pratiques