dimanche 27 mars 2016

Interfacing Spartan 3E with 7 Segment Display !!

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.

Afficher l'image d'origine

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.
La commande du segment se fait par sa cathode mise au potentiel bas.
  • 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;

Et pour le Fun j'ai choisis deux sorties du Spartan 3E et j'ai les relié à des diodes Leds simples de façon la première s'allume au maximum de compteur et l'autre au minimum.

Voici le programme finale du projet :


// 7 Segment Interfacing

-- 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.

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