[VHDL代码]LCD1602驱动
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity LCD1602 is
Port ( Clk : in std_logic; --状态机时钟信号,同时也是液晶时钟信号,其周期应该满足液晶数据的建立时间Sec_low,Sec_high,Min_low,Min_high,Hour_low,Hour_high: in std_logic_vector(3 downto 0);
LCD_RS : out std_logic; --寄存器选择信号
LCD_RW : out std_logic; --液晶读写信号
LCD_EN : out std_logic; --液晶时钟信号
LCD_Data : out std_logic_vector(7 downto 0)); --液晶数据信号
end LCD1602;
architecture Behavioral of LCD1602 is
type STATE_TYPE is
(START,write_C,write_D,WRITE_BYTE_C,WRITE_BYTE_D,wait_3m1,wait_3m2,wait_5m1,wait_5m2,w ait_100m);
type MY_ARRAY1 is array(0 to 4) of std_logic_vector(7 downto 0);
type MY_ARRAY2 is array(0 to 7) of std_logic_vector(7 downto 0);--长度为14的8位/字数组
constant c_d: MY_ARRAY1:=(x"38",x"0c",x"06",x"01",x"84");
signal d_d: MY_ARRAY2:=(x"20",x"20",x"3A",x"20",x"20",x"3A",x"20",x"20");
signal STATE: STATE_TYPE:=START;
signal w_c_flag : integer range 0 to 2:=0;
signal w_d_flag : integer range 0 to 2:=0;
signal write_c_cnt : integer range 0 to 5:=0;
signal write_d_cnt : integer range 0 to 8:=0;
signal cnt : integer range 0 to 10000:=0;
signal count : integer range 0 to 10000:=0;
begin
LCD_RW <= '0' ; --写数据
d_d(0)<="0000"&Hour_high+x"30";
d_d(1)<="0000"&Hour_low+x"30";
d_d(3)<="0000"&Min_high+x"30";
d_d(4)<="0000"&Min_low+x"30";
d_d(6)<="0000"&Sec_high+x"30";
d_d(7)<="0000"&Sec_low+x"30";
process(Clk,STATE) --液晶驱动控制器begin
if rising_edge(Clk) then
case STATE is
when START=>
LCD_EN<='0';
w_c_flag<=0;
w_d_flag<=0;
write_c_cnt<=0;
write_d_cnt<=0;
STATE<=WRITE_C;
when WRITE_C=>
case write_c_cnt is
when 0 to 4=>
STATE<=WRITE_BYTE_C;
when 5=>
write_c_cnt<=4;
STATE<=WRITE_D;
end case;
when WRITE_BYTE_C=>
if(w_c_flag=0) then
LCD_RS<='0';
LCD_Data<=c_d(write_c_cnt);
w_c_flag<=1;
STATE<=wait_3m1;
elsif(w_c_flag=1) then
LCD_EN<='1';
w_c_flag<=2;
STATE<=wait_5m1;
elsif(w_c_flag=2) then
LCD_EN<='0';
w_c_flag<=0;
write_c_cnt<=write_c_cnt+1;
STATE<=WRITE_C;
end if;
when WRITE_D=>
case write_d_cnt is
when 0 to 7=>
STATE<=WRITE_BYTE_D;
when 8=>
write_d_cnt<=0;
STATE<=wait_100m;
end case;
when WRITE_BYTE_D=>
if(w_d_flag=0) then
LCD_RS<='1';
LCD_Data<=d_d(write_d_cnt); w_d_flag<=1;
STATE<=wait_3m2;
elsif(w_d_flag=1) then
LCD_EN<='1';
w_d_flag<=2;
STATE<=wait_5m2;
elsif(w_d_flag=2) then
LCD_EN<='0';
w_d_flag<=0;
write_d_cnt<=write_d_cnt+1; STATE<=WRITE_D;
end if;
when wait_3m1=>
if (cnt>=3) then
STATE<=WRITE_BYTE_C; cnt<=0;
else
cnt<=cnt+1;
STATE<=wait_3m1;
end if;
when wait_5m1=>
if (cnt>=5) then
STATE<=WRITE_BYTE_C; cnt<=0;
else
cnt<=cnt+1;
STATE<=wait_5m1;
end if;
when wait_3m2=>
if (cnt>=3) then
STATE<=WRITE_BYTE_D; cnt<=0;
else
cnt<=cnt+1;
STATE<=wait_3m2;
end if;
when wait_5m2=>
if (cnt>=5) then
STATE<=WRITE_BYTE_D; cnt<=0;
else
cnt<=cnt+1;
STATE<=wait_5m2;
end if;
when wait_100m=>
if (cnt>=100) then
STATE<=START;
cnt<=0;
else
cnt<=cnt+1;
STATE<=wait_100m;
end if;
end case;
end if;
end process;
end Behavioral;。