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

📄 led_vhdl.vhd

📁 LCD点阵阵控制,可输出不同的图形和位置.可随意调整显示格式.
💻 VHD
字号:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

library UNISIM;
use UNISIM.VComponents.all;

entity lcd is
    Port ( clk,reset       : in  std_logic;			  lcd_data 	 		: out std_logic_vector (7 downto 0);    	     lcd_en,lcd_rs,lcd_reset,lcd_rw :    out std_logic );
end lcd;

architecture lcd_arch of lcd is

signal 	lcd_we_n          : std_logic;signal 	lcd_en_int   		: std_logic;signal 	w_comp_n   			: std_logic;signal	seq_count 	 		: std_logic_vector ( 5 downto 0);signal	lcd_rs_data 	 	: std_logic_vector ( 8 downto 0);signal	delay_count 	 	: std_logic_vector (21 downto 0);signal	lcd_addr 	 		: std_logic_vector ( 5 downto 0);type state_lcd_write_type is (lcd_write_idle, lcd_write_1, lcd_write_2, lcd_write_3, lcd_write_4);signal state_lcd_write : state_lcd_write_type;type state_type is (idle, wait_1, wait_2, state_1, state_2, state_3, done);signal state : state_type;begin

lcd_reset <= reset;sequencer_state_register: process (clk, reset)       begin         if (reset = '0') then	state <= idle;    		elsif (clk'event and clk = '1') then				case state is               when idle=>						if (delay_count(21) = '1') then state <= wait_1;						else                            state <= idle;						end if;				      when wait_1=>						if (delay_count(21) = '1') then state <= state_1;						else                            state <= wait_1;						end if;					               when state_1=> state <= state_2;					when state_2=>						if((w_comp_n = '0')and(lcd_addr = "000110"))then							state <= wait_2;														elsif(w_comp_n = '0') then state <= wait_1;						else                       state <= state_2;						end if;--	The following sections performs the writing of the above message to the LCD --	panel. Similar to the initialization section, a fix delay is inserted between--	2 LCD writes. The 22-bit counter used in the initialization section is also--	used here to generate the fix delay.               when wait_2=>						if (delay_count(21)= '1')then state <= state_3;						else                          state <= wait_2;						end if;					               when state_3=>						if((w_comp_n = '0')and(lcd_addr = "100111"))then							  state <= done;							elsif(w_comp_n = '0')then state <= wait_2;						else                      state <= state_3;						end if;						when done=> state <= done;				end case;			end if;end process sequencer_state_register;--	The following section generates a write enable (lcd_we_n) signal based on the--	state of the above state machine that is used to generate the lcd_en signal.sequencer_state_logic: process (state)		begin			case state is					when idle   => lcd_we_n <= '1';					when wait_1 => lcd_we_n <= '1';												when wait_2 => lcd_we_n <= '1';							when state_1=>	lcd_we_n <= '0';										when state_2=>	lcd_we_n <= '0';					when state_3=>	lcd_we_n <= '0';										when done   =>	lcd_we_n <= '1';			end case;end process sequencer_state_logic;--	The following sections uses the lcd_we_n signal to generate the lcd_en signal and--	a write complete signal (w_comp_n). The w_comp_n signal is used to reset various--	counters that are used to generate LCD control signals.state_lcd_write_register: process (clk, reset)        begin				if (reset = '0') then	state_lcd_write <= lcd_write_idle;    			elsif (clk'event and clk = '1') then					case state_lcd_write is                  when lcd_write_idle=>							  if (lcd_we_n = '0') then state_lcd_write <= lcd_write_1;							  else							state_lcd_write <= lcd_write_idle;							  end if;							when lcd_write_1=>							  if (seq_count = "000101")then	state_lcd_write <= lcd_write_2;															  else									state_lcd_write <= lcd_write_1;							  end if;							when lcd_write_2=>							  if (seq_count = "011110")then state_lcd_write <= lcd_write_3;															  else  								  state_lcd_write <= lcd_write_2;							  end if;							when lcd_write_3=>							  if (seq_count = "110010")then state_lcd_write <= lcd_write_4;															  else  								  state_lcd_write <= lcd_write_3;							  end if;							when lcd_write_4=> state_lcd_write <= lcd_write_idle;	             end case;				 end if;end process state_lcd_write_register;state_lcd_write_logic: process (state_lcd_write)         begin				case state_lcd_write is              when lcd_write_idle=>	lcd_en_int <= '0'; w_comp_n <= '1';				  when lcd_write_1   =>	lcd_en_int <= '0'; w_comp_n <= '1';				  when lcd_write_2   =>	lcd_en_int <= '1'; w_comp_n <= '1';				  when lcd_write_3   => lcd_en_int <= '0'; w_comp_n <= '1';				  when lcd_write_4   =>	lcd_en_int <= '0'; w_comp_n <= '0';				end case;end process state_lcd_write_logic;--	The following process provides the LCD initialization data and also the ASCII--	characters needed to write the "Digital Lab Xilinx Spartan3" to the LCD panel. Once,--	the "Digital Lab" is written to the first line of the LCD, hex 0xc0 is written to--	the LCD control register to start at line 2 and write the "Xilinx Spartan3" to the--	LCD panel. The lcd_rs_data consist of the lcd_rs signal (MSB) and 8 bits of data--	(lcd_data).process (lcd_addr)	begin		case lcd_addr is			when "000000"	=> lcd_rs_data	<= "000111000";	--	lcd initializations			when "000001"	=> lcd_rs_data	<= "000111000";			when "000010"	=> lcd_rs_data	<= "000000110";				when "000011"	=> lcd_rs_data	<= "000001110";			when "000100"	=> lcd_rs_data	<= "000000001";			when "000101"	=> lcd_rs_data	<= "010000000";			when "000110"	=> lcd_rs_data	<= "000001100";			when "000111"	=> lcd_rs_data	<= "100100000";	--	lcd first line, "DIGITAL LAB"			when "001000"	=> lcd_rs_data	<= "100100000";						when "001001"	=> lcd_rs_data	<= "101000100"; --D			when "001010"	=> lcd_rs_data	<= "101001001"; --I			when "001011"	=> lcd_rs_data	<= "101000111"; --G			when "001100"	=> lcd_rs_data	<= "101001001"; --I			when "001101"	=> lcd_rs_data	<= "101010100"; --T			when "001110"	=> lcd_rs_data	<= "101000001"; --A			when "001111"	=> lcd_rs_data	<= "101001100"; --L						when "010000"	=> lcd_rs_data	<= "100100000";						when "010001"	=> lcd_rs_data	<= "101001100"; --L			when "010010"	=> lcd_rs_data	<= "101000001"; --A			when "010011"	=> lcd_rs_data	<= "101000010"; --B			when "010100"	=> lcd_rs_data	<= "100100000"; 						when "010101"	=> lcd_rs_data	<= "100100000";			when "010110"	=> lcd_rs_data	<= "100100000";			when "010111"	=> lcd_rs_data	<= "011000000";	--	start at lcd second line			when "011000"	=> lcd_rs_data	<= "101011000"; --X	--	lcd second line, "Xilinx Spartan3"			when "011001"	=> lcd_rs_data	<= "101001001"; --I			when "011010"	=> lcd_rs_data	<= "101001100"; --L			when "011011"	=> lcd_rs_data	<= "101001001"; --I			when "011100"	=> lcd_rs_data	<= "101001110"; --N			when "011101"	=> lcd_rs_data	<= "101011000"; --X			when "011110"	=> lcd_rs_data	<= "100100000"; 						when "011111"	=> lcd_rs_data	<= "101010011"; --S		   when "100000"	=> lcd_rs_data	<= "101010000"; --P			when "100001"	=> lcd_rs_data	<= "101000001"; --A			when "100010"	=> lcd_rs_data	<= "101010010"; --R			when "100011"	=> lcd_rs_data	<= "101010100"; --T			when "100100"	=> lcd_rs_data	<= "101000001"; --A			when "100101"	=> lcd_rs_data	<= "101001110"; --N			when "100110"	=> lcd_rs_data	<= "100110011"; --3			when "100111"	=> lcd_rs_data	<= "100100000"; 			when others		=> lcd_rs_data	<= "111111111";		end case;end process;--	The following is a 22-bit free running counter that is cleared when the reset--	signal is asserted or the MSB of the counter goes to 1. This counter is used--	to generate delays between back-to-back writes to the LCD panel during the --	initialization and also normal write cycles.  process (clk)  begin	if (clk'event and clk = '1') then		if ((reset = '0') or (delay_count(21) = '1')) then			   delay_count <= (others => '0');		else	delay_count <= delay_count + 1;		end if;	end if;  end process;--	The following counter is used by the sequencer to generate the lcd_en signal.--	The counter is reset at the end of each write to the LCD when the w_comp_n--	signal goes active.  process (clk)  begin	if (clk'event and clk = '1') then		if((reset='0')or(w_comp_n='0'))then seq_count<=(others=>'0');		elsif (lcd_we_n = '0')         then seq_count<=seq_count + 1;		end if;	end if;  end process;--	The following block generates the address pointer to the LCD initialization and--	data values. The counter is incremented at the end of each write to the LCD panel--	when the w_comp_n signal goes active.process (clk)  begin	if (clk'event and clk = '1') then		if   (reset = '0') then lcd_addr<=(others => '0');		elsif(w_comp_n='0')then lcd_addr<=lcd_addr + 1;		end if;	end if;end process;--	The following sections define the LCD data and control signals. For this reference--	design, the lcd_rw signal is set to "0" forcing all LCD accesses to be write cycles.    lcd_data   	<= lcd_rs_data(7 downto 0);    lcd_en   		<= lcd_en_int;    lcd_rs   		<= lcd_rs_data(8);    lcd_rw   		<= '0';end lcd_arch;

⌨️ 快捷键说明

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