📄 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;
-- load :in std_logic;
reset : in std_logic; -- active low
data_valid : in std_logic; -- enables lcd to start new write cycle when high
-- data_in: in std_logic_vector(asciiwidth-1 downto 0);
high,low :in std_logic_vector(15 downto 0);
------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 := 4;
type state_type is (warmup, setfunc, dispoff, clear, setmode, home, idle,ini1,ini2,code_address1,code_address2, position,write);
signal state : state_type;
signal rw_int, enable_int : std_logic;
signal count : std_logic_vector(countwidth 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
-- if load='0' then
-- count<=(others=>'0');
-- state<=position;
-- else
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 <= "00110000";----八位数据接口,一行显示,5*7字符;
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;清DDRAM和AC计数器的值;
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 <= ini1;
end if;
else
count <= count + '1';
state <= home;
end if;
------------------------------------
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 ini1=>
lcd_data<="01000000";
lcd_select<='0';
state<=code_address1;
when code_address1=>
case count is
when "00000"=>
lcd_data<="00000111";
when "00001"=>
lcd_data<="00001110";
when "00010"=>
lcd_data<="00011000";
when "00011"=>
lcd_data<="00010000";
when "00100"=>
lcd_data<="00000000";
when "00101"=>
lcd_data<="00000000";
when "00110"=>
lcd_data<="00000000";
when "00111"=>
lcd_data<="00000000";
when "01000"=>
lcd_data<="00011100";
when "01001"=>
lcd_data<="00001110";
when "01010"=>
lcd_data<="00000011";
when "01011"=>
lcd_data<="00000001";
when "01100"=>
lcd_data<="00000000";
when "01101"=>
lcd_data<="00000000";
when "01110"=>
lcd_data<="00000000";
when "01111"=>
lcd_data<="00000000";
when others=>
lcd_data<="00000000";
end case;
count<=count+'1';
lcd_select<='1';
if count="01111" then
state<=ini2;
else
state<=code_address1;
end if;
when ini2=>
lcd_data<="01010000";
lcd_select<='0';
state<=code_address2;
when code_address2=>
case count is
when "10000"=>
lcd_data<="00000000";
when "10001"=>
lcd_data<="00000000";
when "10010"=>
lcd_data<="00000000";
when "10011"=>
lcd_data<="00011000";
when "10100"=>
lcd_data<="00001100";
when "10101"=>
lcd_data<="00000111";
when "10110"=>
lcd_data<="00000011";
when "10111"=>
lcd_data<="00000000";
when "11000"=>
lcd_data<="00000000";
when "11001"=>
lcd_data<="00000000";
when "11010"=>
lcd_data<="00000000";
when "11011"=>
lcd_data<="00000001";
when "11100"=>
lcd_data<="00000011";
when "11101"=>
lcd_data<="00001110";
when "11110"=>
lcd_data<="00011100";
when "11111"=>
lcd_data<="00000000";
when others=>
lcd_data<="00000000";
end case;
lcd_select <= '1';
if count="01111" then
state <= position;
count<="00000";
else
state<=code_address2;
count<=count+'1';
end if;
--------------------------------
when position =>
lcd_data<="10000000";
lcd_select<='0';
state<=write;
-- case count is
-- when "00000"=>
-- lcd_data<="10000000";
-- when "00001"=>
-- lcd_data<="10000001";
-- when "00010"=>
-- lcd_data<="10000010";
-- when "00011"=>
-- lcd_data<="10000011";
-- when "00100"=>
-- lcd_data<="10000100";
-- when "00101"=>
-- lcd_data<="10000101";
-- when "00110"=>
-- lcd_data<="10000110";
-- when "00111"=>
-- lcd_data<="10000111";
-- when "01000"=>
-- lcd_data<="10001000";
-- when "01001"=>
-- lcd_data<="10001001";
-- when "01010"=>
-- lcd_data<="10001010";
-- when "01011"=>
-- lcd_data<="10001011";
-- when "01100"=>
-- lcd_data<="10001100";
-- when "01101"=>
-- lcd_data<="10001101";
-- when "01110"=>
-- lcd_data<="10001110";
-- when "01111"=>
-- lcd_data<="10001111";
-- when others=>
-- lcd_data<="10000000";
-- end case;
-- lcd_select<='0';
-- state<=write;
when write =>
CASE count(3 downto 0) IS
when "0000"=>
lcd_data<="000000"&high(0)&low(0);
when "0001"=>
lcd_data<="000000"&high(1)&low(1);
when "0010"=>
lcd_data<="000000"&high(2)&low(2);
when "0011"=>
lcd_data<="000000"&high(3)&low(3);
when "0100"=>
lcd_data<="000000"&high(4)&low(4);
when "0101"=>
lcd_data<="000000"&high(5)&low(5);
when "0110"=>
lcd_data<="000000"&high(6)&low(6);
when "0111"=>
lcd_data<="000000"&high(7)&low(7);
when "1000"=>
lcd_data<="000000"&high(8)&low(8);
when "1001"=>
lcd_data<="000000"&high(9)&low(9);
when "1010"=>
lcd_data<="000000"&high(10)&low(10);
when "1011"=>
lcd_data<="000000"&high(11)&low(11);
when "1100"=>
lcd_data<="000000"&high(12)&low(12);
when "1101"=>
lcd_data<="000000"&high(13)&low(13);
when "1110"=>
lcd_data<="000000"&high(14)&low(14);
when "1111"=>
lcd_data<="000000"&high(15)&low(15);
when others=>
lcd_data<="00000000";
END CASE;
lcd_select <= '1';
count <= count + '1';
state <= write;
-- if(count="01111" ) then
-- count<=(others=>'0');
-- else count <= count + '1';
-- end if;
-- lcd_data <= data_in; ---------向DDRAM写入数据(字符ASCII码)
-- lcd_select <= '1';
-- state<=position;
end case;
-- end if;
end if;
end process;
end behavioural;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -