library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.NUMERIC_STD.ALL; entity LCD_Controller is Port ( clk : in STD_LOGIC; rst : in STD_LOGIC; RS : out STD_LOGIC; EN : out STD_LOGIC; D4 : out STD_LOGIC; D5 : out STD_LOGIC; D6 : out STD_LOGIC; D7 : out STD_LOGIC ); end LCD_Controller; architecture Behavioral of LCD_Controller is type state_type is ( InitWait, SendHigh, PulseEN1, Wait1, SendLow, PulseEN2, Wait2, Next, Idle ); signal state : state_type := InitWait; type rom_type is array(0 to 20) of std_logic_vector(7 downto 0); constant ROM : rom_type := ( -- Inicjalizacja LCD x"33", x"33", x"33", x"32", -- Tryb 4-bit x"28", -- 2 linie, 4-bit x"0C", -- Display ON x"01", -- Clear x"06", -- Entry Mode x"80", -- DDRAM addr 0 -- Hello World x"48", x"65", x"6C", x"6C", x"6F", x"20", x"57", x"6F", x"72", x"6C", x"64" ); signal rom_index : integer range 0 to 20 := 0; signal delay_cnt : integer := 0; signal data_byte : std_logic_vector(7 downto 0); -- Rejestry wyjściowe signal rs_reg, en_reg : std_logic := '0'; signal d4_reg, d5_reg, d6_reg, d7_reg : std_logic := '0'; begin RS <= rs_reg; EN <= en_reg; D4 <= d4_reg; D5 <= d5_reg; D6 <= d6_reg; D7 <= d7_reg; process(clk) begin if rising_edge(clk) then if rst = '1' then state <= InitWait; delay_cnt <= 0; rom_index <= 0; en_reg <= '0'; rs_reg <= '0'; else case state is when InitWait => if delay_cnt < 1_500_000 then -- ok. 15 ms delay_cnt <= delay_cnt + 1; else delay_cnt <= 0; data_byte <= ROM(rom_index); state <= SendHigh; end if; when SendHigh => rs_reg <= '0' when rom_index < 9 else '1'; d7_reg <= data_byte(7); d6_reg <= data_byte(6); d5_reg <= data_byte(5); d4_reg <= data_byte(4); en_reg <= '1'; delay_cnt <= 0; state <= PulseEN1; when PulseEN1 => if delay_cnt < 10 then delay_cnt <= delay_cnt + 1; else en_reg <= '0'; delay_cnt <= 0; state <= Wait1; end if; when Wait1 => if delay_cnt < 2000 then delay_cnt <= delay_cnt + 1; else d7_reg <= data_byte(3); d6_reg <= data_byte(2); d5_reg <= data_byte(1); d4_reg <= data_byte(0); en_reg <= '1'; delay_cnt <= 0; state <= PulseEN2; end if; when PulseEN2 => if delay_cnt < 10 then delay_cnt <= delay_cnt + 1; else en_reg <= '0'; delay_cnt <= 0; state <= Wait2; end if; when Wait2 => if delay_cnt < 2000 then delay_cnt <= delay_cnt + 1; else rom_index <= rom_index + 1; if rom_index < 20 then data_byte <= ROM(rom_index + 1); state <= SendHigh; else state <= Idle; end if; end if; when Idle => -- nic nie rób null; when others => state <= Idle; end case; end if; end if; end process; end Behavioral;