-------------------------------------------------------------------------------- -- Company: -- Engineer: -- -- Create Date: 23:03:55 03/31/07 -- Design Name: -- Module Name: lcd - Behavioral -- Project Name: -- Target Device: -- 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; ---- Uncomment the following library declaration if instantiating ---- any Xilinx primitives in this code. --library UNISIM; --use UNISIM.VComponents.all; entity lcd is port( clk : in std_logic; --50MHz hertzreg : in std_logic_vector(25 downto 0);--enthält die auszugebende Zahl(8 Stellen) segment_enable : out std_logic_vector(3 downto 0);--enable der 7-Seg Anzeige btn_push : in std_logic; --entprelltes Tastersignal pixels : out std_logic_vector(6 downto 0) --Segmente ); end lcd; architecture Behavioral of lcd is type subtractor_type is array (0 to 7) of integer; constant subtractor_array : subtractor_type := (10000000,1000000,100000,10000,1000,100,10,1);--Array für Subtraktoren signal clk_divider : std_logic_vector(15 downto 0); signal kilohz : std_logic; --1KHz signal two_hz_counter : std_logic_vector(8 downto 0); signal two_hz : std_logic; --2Hz signal segment_shiftreg : std_logic_vector(69 downto 0);--Hier stehen 8 Zahlen + "Hz" 7-Segment codiert drin signal temp_hertzreg : std_logic_vector(25 downto 0):= (others => '0');--Temp-Reg zum Rechnen signal subtractor : integer := 10000000; --Subtraktor um einzelne Stellen von der Zahl abzuziehen signal stelle : integer range 0 to 7 := 0; --aktuelle Stelle in der Zahl signal wert_counter : std_logic_vector(3 downto 0):= (others => '0');--Zählt, wieviel mal der Subtraktor abgezogen werden konnte, ohne dass Zahl < 0 wird signal btn1, btn2 : std_logic; --zum Eintakten signal btn_change : std_logic; signal btn_rst : std_logic; signal btn_enable,dummy : std_logic; signal bcd_hertzreg : std_logic_vector(31 downto 0):= (others => '0');--Zahl in BCD-Kodierung signal mux : std_logic_vector(1 downto 0) := "00"; --Multiplex-Zähler signal digit_counter : integer range 1 to 8 := 8;--Stellen-Zähler für MUX signal conv_to_seg_ena : std_logic; --enable zum Konvertieren von BCD in 7-Segment signal digit_buffer : std_logic_vector(6 downto 0); signal shift_control : std_logic; signal shift_control_cnt : std_logic_vector(1 downto 0); begin process(clk) -- 1KHz Takt erzeugen begin if rising_edge(clk) then if clk_divider = "1100001101010000" then --50000 clk_divider <= (others => '0'); kilohz <= '1'; else kilohz <= '0'; clk_divider <= clk_divider +1; end if; end if; end process; process(clk) --2Hz Takt erzeugen begin if rising_edge(clk) then if kilohz = '1' then if two_hz_counter = "111110100" then --500 two_hz_counter <= (others => '0'); two_hz <= '1'; else two_hz_counter <= two_hz_counter +1; two_hz <= '0'; end if; end if; end if; end process; subtractor <= subtractor_array(stelle);--brechnet den Subtraktor. Muss ungetaktet sein, da sonst zu langsam process(clk) begin if rising_edge(clk) then btn1 <= btn_push; btn2 <= btn1; dummy <= btn_change; --Verzögerung für btn_enable, da sonst Werte draufgehen if btn1 = '1' and btn2 = '0' then btn_change <= '1'; else btn_change <= '0'; end if; if dummy = '1' then btn_enable <= '1'; end if; if btn_rst = '1' then btn_enable <= '0'; end if; end if; end process; process(clk) --Konvertierung von binär in 4-Bit BCD begin if rising_edge(clk) then btn_rst <= '0'; if btn_change = '1' then temp_hertzreg <= hertzreg;--Auszugebenden Wert übernehmen wert_counter <= "0000"; end if; if btn_enable = '1' then if temp_hertzreg /= "00000000000000000000000000" then if temp_hertzreg - subtractor > temp_hertzreg then--wenn Zahl - Subtraktor kleiner 0 wird... bcd_hertzreg(31-stelle*4 downto (31-stelle*4)-3) <= wert_counter; wert_counter <= "0000"; stelle <= stelle +1; else temp_hertzreg <= temp_hertzreg - subtractor; wert_counter <= wert_counter +1; end if; else btn_rst <= '1'; stelle <= 0; bcd_hertzreg(3 downto 0) <= wert_counter; end if; end if; end if; end process; --Segmentbelegung --************************************| -- | -- Seg(0) = Mitte | -- Seg(1) = oben links | -- Seg(2) = unten links | -- Seg(3) = unten Mitte | -- Seg(4) = unten rechts | -- Seg(5) = oben rechts | -- Seg(6) = oben Mitte | -- | -- | -- 6 | -- __ | -- 1|__|5 Mitte = 0 | -- 2|__|4 | -- 3 | --************************************| process(clk)--Anzeige multiplexen begin if rising_edge(clk) then if kilohz = '1' then mux <= mux + "01"; end if; case mux(1 downto 0) is when "00" => pixels <= segment_shiftreg(48 downto 42) ; segment_enable <= "1110" ; when "01" => pixels <= segment_shiftreg(55 downto 49) ; segment_enable <= "1101" ; when "10" => pixels <= segment_shiftreg(62 downto 56) ; segment_enable <= "1011" ; when others => pixels <= segment_shiftreg(69 downto 63) ; segment_enable <= "0111" ; end case ; end if; end process; process(clk) begin if rising_edge(clk) then if btn_rst = '1' then --Enable Signal für BCD to 7-Seg Konvertierung steuern conv_to_seg_ena <= '1'; end if; if digit_counter = 0 then conv_to_seg_ena <= '0'; digit_counter <= 8; segment_shiftreg(13 downto 0) <= "00010010010010";--..."Hz" anfügen end if; if conv_to_seg_ena = '1' then --wenn enable aktiv... digit_counter <= digit_counter -1; case bcd_hertzreg(4*digit_counter -1 downto 4*digit_counter -4) is--Hier tritt der Fehler auf...soll bcd_hertzreg mit 4-Bit-Schritten durchlaufen... when "0000" => segment_shiftreg(7*digit_counter -1 downto 7*digit_counter -7) <= "0000001";--...BCD in 7-Seg umrechnen und in segment_shiftreg an die richtige Stelle schreiben when "0001" => segment_shiftreg(7*digit_counter -1 downto 7*digit_counter -7) <= "1001111"; when "0010" => segment_shiftreg(7*digit_counter -1 downto 7*digit_counter -7) <= "0010010"; when "0011" => segment_shiftreg(7*digit_counter -1 downto 7*digit_counter -7) <= "0000110"; when "0100" => segment_shiftreg(7*digit_counter -1 downto 7*digit_counter -7) <= "1001100"; when "0101" => segment_shiftreg(7*digit_counter -1 downto 7*digit_counter -7) <= "0100100"; when "0110" => segment_shiftreg(7*digit_counter -1 downto 7*digit_counter -7) <= "0100000"; when "0111" => segment_shiftreg(7*digit_counter -1 downto 7*digit_counter -7) <= "0001111"; when "1000" => segment_shiftreg(7*digit_counter -1 downto 7*digit_counter -7) <= "0000000"; when others => segment_shiftreg(7*digit_counter -1 downto 7*digit_counter -7) <= "0000100"; end case; else if two_hz = '1' then shift_control <= '1'; end if; if shift_control = '1' then shift_control_cnt <= shift_control_cnt +"01"; if shift_control_cnt = "11" then shift_control <= '0'; shift_control_cnt <= "00"; end if; digit_buffer <= segment_shiftreg(69 downto 63); --erste Stelle sichern segment_shiftreg(69 downto 7) <= segment_shiftreg(62 downto 0); --Stellen um 1 nach links schieben segment_shiftreg(6 downto 0) <= digit_buffer; --erste Stelle hinten wieder anfügen end if; end if; end if; end process; end Behavioral;