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;
Read 5 times, last 27 hours ago