Seven Segment Display Using Spartan 3E
Dans la meme série de tutoriels que j'ai fait au but de la découverte de technologie FPGA et en particulier la carte Spartan 3E, Aujourd'hui je vais vous montrer comment on fait pour relier un afficheur 7 segments, je vais vous expliquer les étapes de programmation que j'ai fait en passant par un test pratique démonstratif.
Commençons tout d'abord par définir l'afficheur 7 segment.
L'afficheur 7 segment comme on la connu au petit test simple avec Arduino ou avec PIC en faite ;
Les afficheurs 7 segments sont un type d'afficheur très présent sur les calculatrices et les montres à affichage numérique : les caractères (des chiffres, bien que quelques lettres soient utilisées pour l'affichage hexadécimal) s'écrivent en allumant ou en éteignant des segments, au nombre de sept. Quand les 7 segments sont allumés, on obtient le chiffre 8.
Dans un afficheur 7 segments, les segments sont généralement désignés par les lettres allant de A à G. Dans le cas où l'afficheur comporte un point, servant de séparateur décimal, celui-ci est désigné DP (de l'anglais decimal point); certains parlent dans ce cas d'un afficheur « 8 segments ».
Dans le cas d'afficheurs à DEL, deux cas de figures sont présents :
- Afficheur à anode commune : toutes les anodes sont reliées et connectées au potentiel haut.
- Afficheur à cathode commune : toutes les cathodes sont reliées et connectées au potentiel bas.
- La commande du segment se fait par son anode mise au potentiel haut.
Alors a propos de câblage de l'afficheur 7 segment, rien est plus simple que ça on a que relier chaque segment avec une sortie de notre carte FPGA,
Passons maintenant au programmation;
La première phase de programme implique la génération du signal horloge lent, Pour ma carte Spartan 3E le clock standard est de valeur 50 Mhz donc j'ai besoin absolument de créer un clock plus lent que ça,
L'idée c'est de générer un signal de 27 bits initialisé en des zéros, ce dernier il va a chaque front montant de notre clock standard s’incrémenter, du coup après je pourrai prendre le comportement de bit numéro 25 comme étant un clock lent ou un signal d'horloge lent adaptable au travail de reste de projet sous le nom Slow_clk
signal clk_divider : std_logic_vector(27 downto 0) := x"0000000";
clk_division : process (clk, clk_divider)
begin
if (clk = '1' and clk'event) then
clk_divider <= clk_divider + 1;
end if;
slow_clk <= clk_divider(25);
end process;
La deuxieme phase du programme c'est de réaliser un compteur modulo 10 et faire l'implenter sur 4 leds que j'ai choisis.
J'ai expliqué le fonctionnement de ce dernier pas à pas ici Led 4 bit Counter
Et la dernière phase de programme c'est de manipuler l'afficheur 7 segment suivant les états de mon compteur donc :
PS: L'afficheur que j'ai utilisé est anode commune si vous vouler utiliser cathode commune vous avez que changer les uns par des zéros et vis vers ça,
seg : process (temp_count)
begin
if slow_clk'event and slow_clk ='1' then
if temp_count = "0000" then display <= "1111110";
elsif temp_count = "0001" then display <= "0110000";
elsif temp_count = "0010" then display <= "1101101";
elsif temp_count = "0011" then display <= "1111001";
elsif temp_count = "0100" then display <= "0110011";
elsif temp_count = "0101" then display <= "1011011";
elsif temp_count = "0110" then display <= "1011111";
elsif temp_count = "0111" then display <= "1110010";
elsif temp_count = "1000" then display <= "1111111";
elsif temp_count = "1001" then display <= "1111011";
end if ;
end if ;
end process;
Au niveau du programme j'ai choisis implémenter deux switcheurs (Reset et Pause) asynchrones :
counting : process(reset, pause, slow_clk, temp_count)
begin
if reset = '1' then
temp_count <= "0000"; -- Asynchronous reset.
elsif pause = '1' then
temp_count <= temp_count; -- Asynchronous count pause.
else
if slow_clk'event and slow_clk ='1' then -- Counting state
if temp_count < 9 then
temp_count <= temp_count + 1; -- Counter increase
else
temp_count <= "0000"; -- Rollover to zero
end if;
end if;
end if;
count_out <= temp_count; -- Output
end process;
Voici le programme finale du projet :
-- Company: There is no company -- Engineer: Aymen Lachkhem -- -- Create Date: 02:27:11 03/24/2016 -- Design Name: -- Module Name: counter - Behavioral -- Project Name: -- Target Devices: -- Tool versions: -- Description: -- -- Dependencies: -- -- Revision: -- Revision 0.01 - File Created -- Additional Comments: -- ---------------------------------------------------------------------------------- library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; entity counter is port ( clk : in std_logic; reset : in std_logic; pause : in std_logic; max : out std_logic; min : out std_logic; display : out std_logic_vector(6 downto 0); count_out : out std_logic_vector(3 downto 0)); end counter; architecture Behavioral of counter is signal temp_count : std_logic_vector(3 downto 0) := x"0"; signal slow_clk : std_logic; signal clk_divider : std_logic_vector(27 downto 0) := x"0000000"; begin clk_division : process (clk, clk_divider) begin if (clk = '1' and clk'event) then clk_divider <= clk_divider + 1; end if; slow_clk <= clk_divider(25); end process; counting : process(reset, pause, slow_clk, temp_count) begin if reset = '1' then temp_count <= "0000"; -- Asynchronous reset. elsif pause = '1' then temp_count <= temp_count; -- Asynchronous count pause. else if slow_clk'event and slow_clk ='1' then -- Counting state if temp_count < 9 then temp_count <= temp_count + 1; -- Counter increase else temp_count <= "0000"; -- Rollover to zero end if; end if; end if; count_out <= temp_count; -- Output end process; seg : process (temp_count) begin if slow_clk'event and slow_clk ='1' then if temp_count = "0000" then display <= "1111110"; -- 0 in 7 segment elsif temp_count = "0001" then display <= "0110000"; -- 1 elsif temp_count = "0010" then display <= "1101101";--2 elsif temp_count = "0011" then display <= "1111001"; elsif temp_count = "0100" then display <= "0110011"; elsif temp_count = "0101" then display <= "1011011"; elsif temp_count = "0110" then display <= "1011111"; elsif temp_count = "0111" then display <= "1110010"; elsif temp_count = "1000" then display <= "1111111"; elsif temp_count = "1001" then display <= "1111011"; -- 9 end if ; end if ; end process; max_min : process (temp_count,slow_clk) begin if slow_clk'event and slow_clk ='1' then if temp_count = "1001" then max <= '1'; -- 1001 in counter is exactly 9 in 7 segment displaying else max <= '0'; if temp_count = "0000" then min <= '1'; -- 0 else min <= '0'; end if ;end if ; end if ; end process; end Behavioral; -- End module.
// 7 Segment Interfacing
Pour les configurations physiques de mon programme avec la carte Spartan 3E j'ai choisis ces entrées sorties:
NET "clk" LOC = "C9" ;NET "count_out<0>" LOC = "F12" ; # LED<0>NET "count_out<1>" LOC = "E12" ; # LED<1>NET "count_out<2>" LOC = "E11" ; # LED<2>NET "count_out<3>" LOC = "F11" ; # LED<3>NET "reset" LOC = "L13" ; # resetNET "pause" LOC = "L14" ; # LED<3>NET "display<0>" LOC = " B4";NET "display<1>" LOC = " A4";NET "display<2>" LOC = " D5";NET "display<3>" LOC = " C5";NET "display<4>" LOC = " A6";NET "display<5>" LOC = " B6";NET "display<6>" LOC = " E7";NET "min" LOC = "D7";NET "max" LOC ="C7";
Le reste c'est d’implémenter le programme pour avoir ceci :
Aucun commentaire:
Enregistrer un commentaire