Sunday, March 27, 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 : 




No comments:

Post a Comment