Ein einfaches Beispiel zur Realisierung einer Ansteuerung von Siebensegment Anzeigen in VHDL. Die einzelnen Segmente werden im Zeitmultiplexverfahren durchgeschaltet.
-- Bjoern Biesenbach 2013 -- bjoern@bjoern-b.de library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.NUMERIC_STD.ALL; entity sevensegment is Port ( clk : in STD_LOGIC; -- jeweils ein 4 bit Eingang fuer jede 7Segment Stelle bcd1 : in STD_LOGIC_VECTOR(3 downto 0); bcd2 : in STD_LOGIC_VECTOR(3 downto 0); bcd3 : in STD_LOGIC_VECTOR(3 downto 0); bcd4 : in STD_LOGIC_VECTOR(3 downto 0); bcd5 : in STD_LOGIC_VECTOR(3 downto 0); bcd6 : in STD_LOGIC_VECTOR(3 downto 0); bcd7 : in STD_LOGIC_VECTOR(3 downto 0); bcd8 : in STD_LOGIC_VECTOR(3 downto 0); -- Pins zu den gemeinsamen Kathoden der Segmente SsegA : out STD_LOGIC; SsegB : out STD_LOGIC; SsegC : out STD_LOGIC; SsegD : out STD_LOGIC; SsegE : out STD_LOGIC; SsegF : out STD_LOGIC; SsegG : out STD_LOGIC; SsegDP : out STD_LOGIC; -- Pins zu den einzelnen Anoden der Segmente (hier 8 Segmente) SsegSEL : out STD_LOGIC_VECTOR (7 downto 0) ); end sevensegment; architecture behavorial of sevensegment is -- Tabelle welche den Zeichen 1 bis F die Muster der Segmentanzeigen zuordnet type SEG_ROM_TYPE is array (0 to 15) of std_logic_vector(6 downto 0); constant SEG_ROM: SEG_ROM_TYPE := ( "0111111", -- 0 "0000110", -- 1 "1011011", -- 2 "1001111", -- 3 "1100110", -- 4 "1101101", -- 5 "1111101", -- 6 "0000111", -- 7 "1111111", -- 8 "1101111", -- 9 "1110111", -- A "1111100", -- b "0111001", -- C "1011110", -- d "1111001", -- E "1110001" --F ); -- Einfache Statemaschine type segment_states is (seg1,seg2,seg3,seg4,seg5,seg6,seg7,seg8); signal seg_state : segment_states := seg1; signal seg_select : STD_LOGIC_VECTOR (7 downto 0) := "00000001"; signal clk_div : STD_LOGIC; -- Counter zum Runterteilen des Systemtakts auf die Multiplexfrequenz signal cnt : integer range 0 to 1024; signal addr: unsigned(3 downto 0); begin -- Prozess zur Teilung des Systemtaktes process begin wait until rising_edge(clk); cnt < = cnt +1; if cnt = 0 then clk_div <= not clk_div; end if; end process; -- Der eigentliche Prozess zum multiplexen process begin wait until rising_edge(clk_div); case seg_select is -- um eins verschoben da seg_select bereits immer eine stelle voraus ist when "10000000" => addr < = unsigned(bcd8); when "00000001" => addr < = unsigned(bcd7); when "00000010" => addr < = unsigned(bcd6); when "00000100" => addr < = unsigned(bcd5); when "00001000" => addr < = unsigned(bcd4); when "00010000" => addr < = unsigned(bcd3); when "00100000" => addr < = unsigned(bcd2); when "01000000" => addr < = unsigned(bcd1); when others => addr < = "1111"; -- kann nie eintreten end case; seg_select <= seg_select(6 downto 0) & seg_select(7); -- rotate left end process; -- aktuelle stelle ausgeben SsegA <= not SEG_ROM(to_integer(addr))(0); SsegB <= not SEG_ROM(to_integer(addr))(1); SsegC <= not SEG_ROM(to_integer(addr))(2); SsegD <= not SEG_ROM(to_integer(addr))(3); SsegE <= not SEG_ROM(to_integer(addr))(4); SsegF <= not SEG_ROM(to_integer(addr))(5); SsegG <= not SEG_ROM(to_integer(addr))(6); SsegSEL <= not seg_select; end behavorial; |
Hier zu sehen ist das mithilfe von Quartus aus dem VHDL Code erstellte Symbol mitsamt Verdrahtung zu den Pins des FPGA. Die „Punkte“ der Siebensegmentanzeigen sind derzeit nicht angeschlossen.