?? lcd_driver.vhd
字號(hào):
--文件名:lcd_driver.vhd
--功 能:驅(qū)動(dòng)LCD顯示,并可以對(duì)顯示的數(shù)據(jù)進(jìn)行設(shè)置
--說(shuō) 明:液晶顯示的數(shù)值
--------------############################################-------------
--------- AB:CD:EF
-- “S4”鍵控制“A”段的數(shù)據(jù)
-- “S6”鍵控制“B”段的數(shù)據(jù)
-- “S7”鍵控制“C”段的數(shù)據(jù)
-- “S8”鍵控制“D”段的數(shù)據(jù)
-- “S9” 鍵控制“E”段的數(shù)據(jù)
-- “S10”鍵控制“F”段的數(shù)據(jù)
--------------############################################-------------
--注 意:在使用液晶的時(shí)候,千萬(wàn)要注意防靜電(手最好不要觸碰液晶表面)
-- 否則液晶很容易被損壞;
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity lcd_driver is
generic(N:integer:=5000;
delay:integer:=10);
Port ( clk : in std_logic; --系統(tǒng)時(shí)鐘輸入
reset : in std_logic; --復(fù)位信號(hào),在下完程序之后需要對(duì)液晶進(jìn)行復(fù)位清零
set1,set2,set3,set4,set5,set6,set7 : in std_logic;
--set1~set6為數(shù)據(jù)的預(yù)置位,set7是復(fù)位清零信號(hào);
lcden : out std_logic; --接LCD使能端
lcdda : out std_logic; --接LCD_da信號(hào)輸入端
lcdrw : out std_logic; --接LCD讀寫(xiě)信號(hào)輸入端
data :inout std_logic_vector(7 downto 0));--接LCD數(shù)據(jù)輸入位
end lcd_driver;
architecture Behavioral of lcd_driver is
type state is (set_dlnf,clear_lcd,set_cursor,set_dcb,set_location,write_data);
signal current_state:state;
type ram is array(0 to 7) of std_logic_vector(7 downto 0);
signal dataram :ram;
signal yz1:std_logic_vector(3 downto 0);
signal yz2:std_logic_vector(3 downto 0);
signal tq1: std_logic_vector(3 downto 0);
signal tq2: std_logic_vector(3 downto 0);
signal jb1: std_logic_vector(3 downto 0);
signal jb2: std_logic_vector(3 downto 0);
signal yz_dout1: std_logic_vector(7 downto 0);
signal yz_dout2: std_logic_vector(7 downto 0);
signal tq_dout1: std_logic_vector(7 downto 0);
signal tq_dout2: std_logic_vector(7 downto 0);
signal jb_dout1: std_logic_vector(7 downto 0);
signal jb_dout2: std_logic_vector(7 downto 0);
signal clk_2hz,clk_500hz: std_logic;
begin
--(液晶)數(shù)據(jù)交換頻率
lcd_clk:process(clk,reset)
variable c: integer range 0 to 10000;
variable clk0: std_logic;
begin
if reset='0' then c:=0; clk0:='0';
elsif clk'event and clk='1' then c:=c+1;
if c=N then clk0:='1';
elsif c=2*N then clk0:='0';c:=0;
end if;
end if;
clk_500hz<=clk0;
end process;
--2赫茲的分頻模塊
set_clk:process(clk,reset)
variable c: integer range 0 to 25000000;
variable clk0: std_logic;
begin
if reset='0' then c:=0;clk0:='0';
elsif clk'event and clk='1' then c:=c+1;
if c=12500000 then clk0:='1';
elsif c=25000000 then clk0:='0';c:=0;
end if;
end if;
clk_2hz<=clk0;
end process;
--按鍵置數(shù)模塊
set:process(clk_2hz,set7)
variable p1,p2,p3,p4,p5,p6:std_logic_vector(3 downto 0);
begin
if set7='0' then yz1<="0000";yz2<="0000";tq1<="0000";tq2<="0000";jb1<="0000";jb2<="0000";
p1:="0000";p2:="0000"; p3:="0000";p4:="0000"; p5:="0000"; p6:="0000";
elsif clk_2hz'event and clk_2hz='1' then
if set1='0' then if p1="1001" then p1:="0000";
else p1:=p1+1;
end if;
end if;
if set2='0' then if p2="1001" then p2:="0000";
else p2:=p2+1;
end if;
end if;
if set3='0' then if p3="1001" then p3:="0000";
else p3:=p3+1;
end if;
end if;
if set4='0' then if p4="1001" then p4:="0000";
else p4:=p4+1;
end if;
end if;
if set5='0' then if p5="1001" then p5:="0000";
else p5:=p5+1;
end if;
end if;
if set6='0' then if p6="1001" then p6:="0000";
else p6:=p6+1;
end if;
end if;
end if;
yz1<=p1;yz2<=p2;tq1<=p3;tq2<=p4;jb1<=p5;jb2<=p6;
end process;
--數(shù)據(jù)譯碼
lcd_decoder_yz1: process(clk)
begin
if clk'event and clk='1' then
case yz1 is
when "0000"=>yz_dout1<="00110000";
when "0001"=>yz_dout1<="00110001";
when "0010"=>yz_dout1<="00110010";
when "0011"=>yz_dout1<="00110011";
when "0100"=>yz_dout1<="00110100";
when "0101"=>yz_dout1<="00110101";
when "0110"=>yz_dout1<="00110110";
when "0111"=>yz_dout1<="00110111";
when "1000"=>yz_dout1<="00111000";
when "1001"=>yz_dout1<="00111001";
when "1010"=>yz_dout1<="01000001";
when "1011"=>yz_dout1<="01000010";
when "1100"=>yz_dout1<="01000011";
when "1101"=>yz_dout1<="01000100";
when "1110"=>yz_dout1<="01000101";
when "1111"=>yz_dout1<="01000110";
when others=>yz_dout1<="00111111";
end case;
end if;
end process;
lcd_decoder_yz2:process(clk)
begin
if clk'event and clk='1' then
case yz2 is
when "0000"=>yz_dout2<="00110000";
when "0001"=>yz_dout2<="00110001";
when "0010"=>yz_dout2<="00110010";
when "0011"=>yz_dout2<="00110011";
when "0100"=>yz_dout2<="00110100";
when "0101"=>yz_dout2<="00110101";
when "0110"=>yz_dout2<="00110110";
when "0111"=>yz_dout2<="00110111";
when "1000"=>yz_dout2<="00111000";
when "1001"=>yz_dout2<="00111001";
when "1010"=>yz_dout2<="01000001";
when "1011"=>yz_dout2<="01000010";
when "1100"=>yz_dout2<="01000011";
when "1101"=>yz_dout2<="01000100";
when "1110"=>yz_dout2<="01000101";
when "1111"=>yz_dout2<="01000110";
when others=>yz_dout2<="00111111";
end case;
end if;
end process;
lcd_decoder_tq1:process(clk)
begin
if clk'event and clk='1' then
case tq1 is
when "0000"=>tq_dout1<="00110000";
when "0001"=>tq_dout1<="00110001";
when "0010"=>tq_dout1<="00110010";
when "0011"=>tq_dout1<="00110011";
when "0100"=>tq_dout1<="00110100";
when "0101"=>tq_dout1<="00110101";
when "0110"=>tq_dout1<="00110110";
when "0111"=>tq_dout1<="00110111";
when "1000"=>tq_dout1<="00111000";
when "1001"=>tq_dout1<="00111001";
when "1010"=>tq_dout1<="01000001";
when "1011"=>tq_dout1<="01000010";
when "1100"=>tq_dout1<="01000011";
when "1101"=>tq_dout1<="01000100";
when "1110"=>tq_dout1<="01000101";
when "1111"=>tq_dout1<="01000110";
when others=>tq_dout1<="00111111";
end case;
end if;
end process;
lcd_decoder_tq2:process(clk)
begin
if clk'event and clk='1' then
case tq2 is
when "0000"=>tq_dout2<="00110000";
when "0001"=>tq_dout2<="00110001";
when "0010"=>tq_dout2<="00110010";
when "0011"=>tq_dout2<="00110011";
when "0100"=>tq_dout2<="00110100";
when "0101"=>tq_dout2<="00110101";
when "0110"=>tq_dout2<="00110110";
when "0111"=>tq_dout2<="00110111";
when "1000"=>tq_dout2<="00111000";
when "1001"=>tq_dout2<="00111001";
when "1010"=>tq_dout2<="01000001";
when "1011"=>tq_dout2<="01000010";
when "1100"=>tq_dout2<="01000011";
when "1101"=>tq_dout2<="01000100";
when "1110"=>tq_dout2<="01000101";
when "1111"=>tq_dout2<="01000110";
when others=>tq_dout2<="00111111";
end case;
end if;
end process;
lcd_decoder_jb1:process(clk)
begin
if clk'event and clk='1' then
case jb1 is
when "0000"=>jb_dout1<="00110000";
when "0001"=>jb_dout1<="00110001";
when "0010"=>jb_dout1<="00110010";
when "0011"=>jb_dout1<="00110011";
when "0100"=>jb_dout1<="00110100";
when "0101"=>jb_dout1<="00110101";
when "0110"=>jb_dout1<="00110110";
when "0111"=>jb_dout1<="00110111";
when "1000"=>jb_dout1<="00111000";
when "1001"=>jb_dout1<="00111001";
when "1010"=>jb_dout1<="01000001";
when "1011"=>jb_dout1<="01000010";
when "1100"=>jb_dout1<="01000011";
when "1101"=>jb_dout1<="01000100";
when "1110"=>jb_dout1<="01000101";
when "1111"=>jb_dout1<="01000110";
when others=>jb_dout1<="00111111";
end case;
end if;
end process;
lcd_decoder_jb2:process(clk)
begin
if clk'event and clk='1' then
case jb2 is
when "0000"=>jb_dout2<="00110000";
when "0001"=>jb_dout2<="00110001";
when "0010"=>jb_dout2<="00110010";
when "0011"=>jb_dout2<="00110011";
when "0100"=>jb_dout2<="00110100";
when "0101"=>jb_dout2<="00110101";
when "0110"=>jb_dout2<="00110110";
when "0111"=>jb_dout2<="00110111";
when "1000"=>jb_dout2<="00111000";
when "1001"=>jb_dout2<="00111001";
when "1010"=>jb_dout2<="01000001";
when "1011"=>jb_dout2<="01000010";
when "1100"=>jb_dout2<="01000011";
when "1101"=>jb_dout2<="01000100";
when "1110"=>jb_dout2<="01000101";
when "1111"=>jb_dout2<="01000110";
when others=>jb_dout2<="00111111";
end case;
end if;
end process;
--設(shè)定數(shù)據(jù)顯示的位置
loaddata:process(clk,set7)
begin
if reset='0'then
dataram<=(("00110000"),("00110000"),("00111010"),("00110000"),
("00110000"),("00111010"),("00110000"),("00110000"));
elsif rising_edge(clk)then
dataram(0)<=yz_dout1;
dataram(1)<=yz_dout2;
dataram(2)<="00111010";
dataram(3)<=tq_dout1;
dataram(4)<=tq_dout2;
dataram(5)<="00111010";
dataram(6)<=jb_dout1;
dataram(7)<=jb_dout2;
end if;
end process;
--液晶驅(qū)動(dòng)部分
control: process(clk_500hz,reset)
variable cntt,cnt2:integer;
variable cnt3:std_logic_vector(3 downto 0);
begin
if reset='0'then
current_state<=set_dlnf;
cntt:=0;cnt2:=0;
elsif rising_edge(clk_500hz)then cnt3:=cnt3+1;
case current_state is
when set_dlnf=> --功能設(shè)置
lcden<='0';
lcdda<='0';
lcdrw<='0';
data<="00111100";
cntt:=cntt+1;
if cntt>delay and cntt<=delay*2 then --延時(shí)操作
lcden<='1'; --保證液晶有足夠的使能時(shí)間
else
lcden<='0';
end if;
if cntt=delay*3 then
current_state<=clear_lcd;
cntt:=0;
end if;
when clear_lcd=> --清屏操作
lcden<='0';
lcdda<='0';
lcdrw<='0';
data<="00000001";
cntt:=cntt+1;
if cntt>delay and cntt<=delay*2 then --延時(shí)操作
lcden<='1'; --保證液晶有足夠的使能時(shí)間
else
lcden<='0';
end if;
if cntt=delay*3 then
current_state<=set_cursor;
cntt:=0;
end if;
when set_cursor=> --光標(biāo)顯示設(shè)置
lcden<='0';
lcdda<='0';
lcdrw<='0';
data<="00000110";
cntt:=cntt+1;
if cntt>delay and cntt<=delay*2 then --延時(shí)操作
lcden<='1'; --保證液晶有足夠的使能時(shí)間
else
lcden<='0';
end if;
if cntt=delay*3 then
current_state<=set_dcb;
cntt:=0;
end if;
when set_dcb=> --顯示開(kāi)關(guān)控制
lcden<='0';
lcdda<='0';
lcdrw<='0';
data<="00001111";
cntt:=cntt+1;
if cntt>delay and cntt<=delay*2 then --延時(shí)操作
lcden<='1'; --保證液晶有足夠的使能時(shí)間
else
lcden<='0';
end if;
if cntt=delay*3 then
current_state<=set_location;
cntt:=0;
end if;
when set_location=> --設(shè)置顯示數(shù)據(jù)的初始位置
lcden<='0';
lcdda<='0';
lcdrw<='0';
data<="11000000";
cntt:=cntt+1;
if cntt>delay and cntt<=delay*2 then --延時(shí)操作
lcden<='1'; --保證液晶有足夠的使能時(shí)間
else
lcden<='0';
end if;
if cntt=delay*3 then
current_state<=write_data;
cntt:=0;
end if;
when write_data=> --將數(shù)據(jù)寫(xiě)入液晶
lcden<='0';
lcdda<='1';
lcdrw<='0';
if cnt2<=7 then
data<=dataram(cnt2);
cntt:=cntt+1;
if cnt3<="1000"then
if cnt2=2 then
data<="00100000";
end if;
end if;
if cntt>delay and cntt<=delay*2 then
lcden<='1';
else
lcden<='0';
end if;
if cntt=delay*3 then
current_state<=write_data;
cntt:=0;
cnt2:=cnt2+1;
end if;
else
cnt2:=0;
current_state<=set_location;
end if;
end case;
end if;
end process;
end Behavioral;
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -