📄 lcd.vhd
字号:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
entity lcd is
generic ( asciiwidth : positive := 8);
port ( clk : in std_logic;
reset : in std_logic; -- active low
data_valid : in std_logic; -- enables lcd to start new write cycle when high
------interface to LCM----------------------------------------------
lcd_data : out std_logic_vector(asciiwidth-1 downto 0);
lcd_select : out std_logic; -- selects data(0) or instruction(1)
lcd_rw,tt : out std_logic; -- read (1) or write (0) data
lcd_enable : out std_logic; -- must be pulsed at clock frequency
---------------------------------------------------------------------
done : out std_logic); -- set low during write cycle, high if ready for new data
end lcd;
architecture behavioural of lcd is
constant countwidth : positive := 3;
type state_type is (warmup, setfunc, dispoff, clear,clear1, setmode, home, idle, write1,write2,write3,setadd);
signal state : state_type;
signal rw_int, enable_int : std_logic;
signal count : std_logic_vector(countwidth downto 0);
signal count1 :std_logic_vector (5 downto 0);
signal write_mode : std_logic; -- stores whether to enter write cycle after clearing display
signal last_data_valid : std_logic; -- used to track rising edge on valid
begin
tt<='0';
lcd_rw <= rw_int;
lcd_enable <= enable_int;
enable_int <= not clk; -- this is very important! if enable is not pulsed, lcd will not write
state_set: process (clk, reset)
begin
if reset = '0' then
count <= (others => '0');
write_mode <= '1';
state <= warmup;
elsif (clk'event and clk = '1') then
case state is
when warmup =>
lcd_select <= '0';
rw_int <= '0';
done <= '0';
lcd_data <= "00000000"; -- do nothing
if count = "0111" then
count <= (others => '0');
state <= setfunc;
else
count <= count + '1';
state <= warmup;
end if;
when setfunc =>
lcd_data <= "00010000";
if count = "1111" then
state <= dispoff;
else
count <= count + '1';
state <= setfunc;
end if;
when dispoff =>
lcd_data <= "00001000";
count <= (others => '0');
state <= clear;
when clear =>
lcd_data <= "00000001"; -- clear display
if count = "0101" then
state <= setmode;
else
count <= count + '1';
state <= clear;
end if;
when setmode =>
lcd_data <= "00000110";
count <= (others => '0');
state <= home;
when home =>
lcd_data <= "00001100";
if count = "0100" then
if write_mode = '0' then
done <= '1';
state <= idle;
else
done <= '0';
count <= (others => '0');
state <= setadd;
end if;
else
count <= count + '1';
state <= home;
end if;
when setadd=>
lcd_data <= "01000000";
count <= (others => '0');
state <= write1;
when idle =>
if data_valid = '1' and last_data_valid = '0' then
last_data_valid <= '1';
count <= (others => '0');
done <= '0';
write_mode <= '1';
state <= clear;
else
if data_valid = '0' then
last_data_valid <= '0';
end if;
lcd_data <= (others => '0');
done <= '1';
state <= idle;
end if;
when write1 =>
if count1="111111" then
state <= clear1;
else
CASE count1 IS
WHEN "000000" =>
lcd_data <= "00000000"; -- 'H'
WHEN "000001" =>
lcd_data <= "00000000"; -- 'e'
WHEN "000010" =>
lcd_data <= "00000000"; -- 'l'
WHEN "000011" =>
lcd_data <= "00000000"; -- 'l'
WHEN "000100" =>
lcd_data <= "00000001"; -- 'o'
WHEN "000101" =>
lcd_data <= "00000011"; -- 'W'
WHEN "000110" =>
lcd_data <= "00000011"; -- 'u'
WHEN "000111" =>
lcd_data <= "00100000"; -- 'k'
------------------------------------------------
WHEN "001000" =>
lcd_data <= "00000100"; -- 'e'
WHEN "001001" =>
lcd_data <= "00000100"; -- 'M'
WHEN "001010" =>
lcd_data <= "00001110"; -- 'o'
WHEN "001011" =>
lcd_data <= "00011111"; -- 'r'
WHEN "001100" =>
lcd_data <= "00011111"; -- 'n'
WHEN "001101" =>
lcd_data <= "00011111"; -- 'i'
WHEN "001110" =>
lcd_data <= "00001010"; -- 'n'
WHEN "001111" =>
lcd_data <= "00100000"; -- 'g'
--------------------------------------------
WHEN "010000" =>
lcd_data <= "00000000"; -- 'H'
WHEN "010001" =>
lcd_data <= "00000000"; -- 'e'
WHEN "010010" =>
lcd_data <= "00000000"; -- 'l'
WHEN "010011" =>
lcd_data <= "00000000"; -- 'l'
WHEN "010100" =>
lcd_data <= "00010000"; -- 'o'
WHEN "010101" =>
lcd_data <= "00011000"; -- 'W'
WHEN "010110" =>
lcd_data <= "00011000"; -- 'u'
WHEN "010111" =>
lcd_data <= "00100000"; -- 'k'
------------------------------------------
WHEN "011000" =>
lcd_data <= "00000000"; -- 'e'
WHEN "011001" =>
lcd_data <= "00000000"; -- 'M'
WHEN "011010" =>
lcd_data <= "00000000"; -- 'o'
WHEN "011011" =>
lcd_data <= "00010111"; -- 'r'
WHEN "011100" =>
lcd_data <= "00010000"; -- 'n'
WHEN "011101" =>
lcd_data <= "00010111"; -- 'i'
WHEN "011110" =>
lcd_data <= "00010111"; -- 'n'
WHEN "011111" =>
lcd_data <= "00100000"; -- 'g'
--------------------------------------------
WHEN "100000" =>
lcd_data <= "00000111"; -- 'H'
WHEN "100001" =>
lcd_data <= "00001010"; -- 'e'
WHEN "100010" =>
lcd_data <= "00010101"; -- 'l'
WHEN "100011" =>
lcd_data <= "00000011"; -- 'l'
WHEN "100100" =>
lcd_data <= "00011100"; -- 'o'
WHEN "100101" =>
lcd_data <= "00011111"; -- 'W'
WHEN "100110" =>
lcd_data <= "00011111"; -- 'u'
WHEN "100111" =>
lcd_data <= "00100000"; -- 'k'
-------------------------------------------
WHEN "101000" =>
lcd_data <= "00011111"; -- 'e'
WHEN "101001" =>
lcd_data <= "00011111"; -- 'M'
WHEN "101010" =>
lcd_data <= "00001110"; -- 'o'
WHEN "101011" =>
lcd_data <= "00011111"; -- 'r'
WHEN "101100" =>
lcd_data <= "00001110"; -- 'n'
WHEN "101101" =>
lcd_data <= "00011111"; -- 'i'
WHEN "101110" =>
lcd_data <= "00011111"; -- 'n'
WHEN "101111" =>
lcd_data <= "00100000"; -- 'g'
----------------------------------------
WHEN "110000" =>
lcd_data <= "00011100"; -- 'H'
WHEN "110001" =>
lcd_data <= "00001010"; -- 'e'
WHEN "110010" =>
lcd_data <= "00010101"; -- 'l'
WHEN "110011" =>
lcd_data <= "00011111"; -- 'l'
WHEN "110100" =>
lcd_data <= "00000111"; -- 'o'
WHEN "110101" =>
lcd_data <= "00011111"; -- 'W'
WHEN "110110" =>
lcd_data <= "00011111"; -- 'u'
WHEN "110111" =>
lcd_data <= "00100000"; -- 'k'
WHEN "111000" =>
lcd_data <= "00000000"; -- 'e'
WHEN "111001" =>
lcd_data <= "00000000"; -- 'M'
WHEN "111010" =>
lcd_data <= "00000000"; -- 'o'
WHEN "111011" =>
lcd_data <= "00011101"; -- 'r'
WHEN "111100" =>
lcd_data <= "00000001"; -- 'n'
WHEN "111101" =>
lcd_data <= "00011101"; -- 'i'
WHEN "111110" =>
lcd_data <= "00011101"; -- 'n'
WHEN "111111" =>
lcd_data <= "00100000"; -- 'g'
when others => null;
end case;
lcd_select <= '1';
count1 <= count1 + '1';
state <= write1;
end if;
when clear1 =>
lcd_data <= "10000000";
count <= (others => '0');
lcd_select <= '0';
state <= write2;
-------------------------------------------------------
when write2 =>
CASE count IS
WHEN "0000" =>
lcd_data <= "01000001"; -- 'H'
WHEN "0001" =>
lcd_data <= "11111110"; -- 'e'
WHEN "0010" =>
lcd_data <= "11111110"; -- 'l'
WHEN "0011" =>
lcd_data <= "11111110"; -- 'l'
WHEN "0100" =>
lcd_data <= "11111110"; -- 'o'
WHEN "0101" =>
lcd_data <= "11111110"; -- 'W'
WHEN "0110" =>
lcd_data <= "00000111"; -- 'u'
WHEN "0111" =>
lcd_data <= "00001000"; -- 'k'
WHEN "1000" =>
lcd_data <= "00001001"; -- 'e'
WHEN "1001" =>
lcd_data <= "11111110"; -- 'e'
WHEN "1010" =>
lcd_data <= "11111110"; -- 'l'
WHEN "1011" =>
lcd_data <= "11111110"; -- 'l'
WHEN "1100" =>
lcd_data <= "11111110"; -- 'o'
WHEN "1101" =>
lcd_data <= "11111110"; -- 'W'
WHEN "1110" =>
lcd_data <= "11111110"; -- 'u'
WHEN "1111" =>
lcd_data <= "11111110"; -- 'k'
WHEN others =>
null; -- 'e'
END CASE;
lcd_select <= '1';
count <= count + '1';
state <= write2;
when others => null;
end case;
end if;
end process;
end behavioural;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -