---------------------------------------------------------------------------------- -- Company: -- Engineer: Anastazja Sofińska -- -- Create Date: 25.06.2025 07:51:35 -- Design Name: -- Module Name: testownik - 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_unsigned.all; entity testownik is PORT( reset : in STD_LOGIC; Clock100MHz : in STD_LOGIC; LCD_RS : out STD_LOGIC; LCD_E : out STD_LOGIC; DATA_BUS : out STD_LOGIC_VECTOR (3 DOWNTO 0) ); end testownik; architecture Behavioral of testownik is type state_type is ( IDLE, ENABLE1, ENABLE2, INIT1, INIT2, INIT3, INIT4, FUNC_SET, DISPLAY_ON, MODE_SET, WRITE_CHAR, RETURN_BACK, SEND_UPPER, SEND_LOWER, DISPLAY_OFF, DISPLAY_CLEAR, SET_CURSOR_LINE1 ); signal curr_state : state_type := INIT1; signal next_state : state_type := INIT2; signal lcd_data_buf : STD_LOGIC_VECTOR (7 DOWNTO 0) := (others => '0'); signal tick_2ms : STD_LOGIC := '0'; signal tick_cnt : integer range 0 to 250000 := 0; signal char_idx : STD_LOGIC_VECTOR (4 downto 0) := (others => '0'); signal char_data : STD_LOGIC_VECTOR (7 DOWNTO 0); signal char_reg : STD_LOGIC_VECTOR (7 DOWNTO 0) := "10000001"; shared variable line_flag : STD_LOGIC := '0'; signal rst_counter : STD_LOGIC_VECTOR (3 downto 0) := (others => '0'); signal is_ready : boolean := true; begin char_data <= char_reg; -- pomocniczy zegar ~2.5 ms process(Clock100MHz) begin if rising_edge(Clock100MHz) then if reset = '1' then tick_cnt <= 0; tick_2ms <= '0'; else tick_cnt <= tick_cnt + 1; if tick_cnt = 250000 then tick_cnt <= 0; tick_2ms <= not tick_2ms; end if; end if; end if; end process; -- FSM do obsługi LCD process(tick_2ms, reset) begin if reset = '1' then curr_state <= INIT1; lcd_data_buf <= (others => '0'); next_state <= INIT2; LCD_E <= '1'; LCD_RS <= '0'; line_flag := '0'; elsif rising_edge(tick_2ms) then case curr_state is when IDLE => if is_ready then LCD_E <= '1'; curr_state <= next_state; is_ready <= false; else is_ready <= true; end if; when ENABLE1 => LCD_E <= '0'; curr_state <= SEND_LOWER; when ENABLE2 => LCD_E <= '0'; curr_state <= IDLE; when INIT1 => LCD_RS <= '0'; lcd_data_buf <= "00000011"; rst_counter <= rst_counter + 1; if rst_counter = "1001" then next_state <= INIT2; curr_state <= SEND_LOWER; end if; when INIT2 => LCD_RS <= '0'; lcd_data_buf <= "00000011"; rst_counter <= rst_counter + 1; if rst_counter = "1011" then next_state <= INIT3; curr_state <= SEND_LOWER; end if; when INIT3 => LCD_RS <= '0'; lcd_data_buf <= "00000011"; rst_counter <= rst_counter + 1; if rst_counter = "1100" then next_state <= INIT4; curr_state <= SEND_LOWER; end if; when INIT4 => LCD_RS <= '0'; lcd_data_buf <= "00000010"; next_state <= FUNC_SET; curr_state <= SEND_LOWER; when FUNC_SET => LCD_RS <= '0'; lcd_data_buf <= "00101000"; -- 4-bit, 2 linie next_state <= DISPLAY_OFF; curr_state <= SEND_UPPER; when DISPLAY_OFF => LCD_RS <= '0'; lcd_data_buf <= "00001000"; next_state <= DISPLAY_CLEAR; curr_state <= SEND_UPPER; when DISPLAY_CLEAR => LCD_RS <= '0'; lcd_data_buf <= "00000001"; next_state <= DISPLAY_ON; curr_state <= SEND_UPPER; when DISPLAY_ON => LCD_RS <= '0'; lcd_data_buf <= "00001100"; next_state <= MODE_SET; curr_state <= SEND_UPPER; when MODE_SET => LCD_RS <= '0'; lcd_data_buf <= "00000110"; next_state <= SET_CURSOR_LINE1; curr_state <= SEND_UPPER; when SET_CURSOR_LINE1 => LCD_RS <= '0'; lcd_data_buf <= "10000000"; next_state <= WRITE_CHAR; curr_state <= SEND_UPPER; when WRITE_CHAR => if char_idx = "11011" then curr_state <= IDLE; next_state <= IDLE; elsif char_idx = "01100" and line_flag = '0' then LCD_RS <= '0'; lcd_data_buf <= "11000000"; line_flag := '1'; curr_state <= SEND_UPPER; next_state <= WRITE_CHAR; else LCD_RS <= '1'; lcd_data_buf <= char_data; char_idx <= char_idx + 1; curr_state <= SEND_UPPER; next_state <= WRITE_CHAR; end if; when RETURN_BACK => LCD_RS <= '0'; lcd_data_buf <= "10000000"; next_state <= WRITE_CHAR; curr_state <= SEND_UPPER; when SEND_UPPER => LCD_E <= '1'; DATA_BUS <= lcd_data_buf(7 downto 4); curr_state <= ENABLE1; when SEND_LOWER => LCD_E <= '1'; DATA_BUS <= lcd_data_buf(3 downto 0); curr_state <= ENABLE2; when others => curr_state <= next_state; end case; end if; end process; -- Przypisywanie znaków do LCD process(tick_2ms, reset) begin if reset = '1' then char_reg <= (others => '0'); elsif rising_edge(tick_2ms) then if curr_state = WRITE_CHAR then case char_idx is -- Linia 1: "Ile to 2+2? " when "00000" => char_reg <= "01001001"; -- I when "00001" => char_reg <= "01101100"; -- l when "00010" => char_reg <= "01100101"; -- e when "00011" => char_reg <= "00100000"; -- when "00100" => char_reg <= "01110100"; -- t when "00101" => char_reg <= "01101111"; -- o when "00110" => char_reg <= "00100000"; -- when "00111" => char_reg <= "00110010"; -- 2 when "01000" => char_reg <= "00101011"; -- + when "01001" => char_reg <= "00110010"; -- 2 when "01010" => char_reg <= "00111111"; -- ? when "01011" => char_reg <= "00100000"; -- spacja -- Linia 2: "A:2 B:3 C:1 D:4" when "01100" => char_reg <= "01000001"; -- A when "01101" => char_reg <= "00111010"; -- : when "01110" => char_reg <= "00110010"; -- 2 when "01111" => char_reg <= "00100000"; -- when "10000" => char_reg <= "01000010"; -- B when "10001" => char_reg <= "00111010"; -- : when "10010" => char_reg <= "00110011"; -- 3 when "10011" => char_reg <= "00100000"; -- when "10100" => char_reg <= "01000011"; -- C when "10101" => char_reg <= "00111010"; -- : when "10110" => char_reg <= "00110100"; -- 4 when "10111" => char_reg <= "00100000"; -- when others => char_reg <= "00100000"; -- spacja end case; end if; end if; end process; end Behavioral;