⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lcd_driver.vhd

📁 一些很好的FPGA设计实例
💻 VHD
字号:
--文件名:lcd_driver.vhd

--功  能:驱动LCD显示,并可以对显示的数据进行设置

--说  明:液晶显示的数值
--------------############################################-------------

---------              AB:CD:EF

--            “S4”键控制“A”段的数据
--            “S6”键控制“B”段的数据

--            “S7”键控制“C”段的数据
--            “S8”键控制“D”段的数据

--            “S9” 键控制“E”段的数据
--            “S10”键控制“F”段的数据

--------------############################################-------------

--注  意:在使用液晶的时候,千万要注意防静电(手最好不要触碰液晶表面)

--        否则液晶很容易被损坏;


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;   --系统时钟输入
           reset : in std_logic;  --复位信号,在下完程序之后需要对液晶进行复位清零
           set1,set2,set3,set4,set5,set6,set7 : in std_logic;  
		    --set1~set6为数据的预置位,set7是复位清零信号;
           lcden : out std_logic; --接LCD使能端
           lcdda : out std_logic; --接LCD_da信号输入端
           lcdrw : out std_logic; --接LCD读写信号输入端
           data :inout std_logic_vector(7 downto 0));--接LCD数据输入位 
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

--(液晶)数据交换频率
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;

--按键置数模块
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;

--数据译码
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;

--设定数据显示的位置
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;

--液晶驱动部分
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=>			      --功能设置
				  lcden<='0';
				  lcdda<='0';
				  lcdrw<='0';
				  data<="00111100";
				  cntt:=cntt+1;
				if cntt>delay and cntt<=delay*2 then	--延时操作
				  lcden<='1';	--保证液晶有足够的使能时间	    
				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 --延时操作
				   lcden<='1';	--保证液晶有足够的使能时间						    
				 else                
				   lcden<='0';
				 end if;

				 if cntt=delay*3 then
				   current_state<=set_cursor;
				   cntt:=0;
				 end if;

       when set_cursor=>				   --光标显示设置
				    lcden<='0';
				    lcdda<='0';
				    lcdrw<='0';
				    data<="00000110";
				    cntt:=cntt+1;
                      if cntt>delay and cntt<=delay*2 then --延时操作
				    lcden<='1'; --保证液晶有足够的使能时间							    
				  else                
				    lcden<='0';
				  end if;

				  if cntt=delay*3 then
				    current_state<=set_dcb;
				    cntt:=0;
				  end if;

	 when set_dcb=>				     --显示开关控制
				    lcden<='0';
				    lcdda<='0';
				    lcdrw<='0';
				    data<="00001111";
				    cntt:=cntt+1;
				  if cntt>delay and cntt<=delay*2 then --延时操作
				    lcden<='1'; --保证液晶有足够的使能时间							    
				  else                
				    lcden<='0';
				  end if;

				  if cntt=delay*3 then
				    current_state<=set_location;
				    cntt:=0;
				  end if;

	 when set_location=>			  --设置显示数据的初始位置
				    lcden<='0';
				    lcdda<='0';
				    lcdrw<='0';
				    data<="11000000";
				    cntt:=cntt+1;
				  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;
				  end if;

      when write_data=>		              --将数据写入液晶
				    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;




⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -