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

📄 lcd_gram.vhd

📁 用于控制LCD12832液晶图形显示的源程序
💻 VHD
字号:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;



entity lcd_gram is
    Port ( clk : in std_logic;				 --40MHZ
           rst_n : in std_logic;
           lcd_rs : out std_logic;
           lcd_rw : out std_logic;
		   lcd_en  : buffer std_logic;
		   lcd_data : out std_logic_vector(7 downto 0));
end;

architecture behav of lcd_gram is

component data_rom
	PORT
	(
		address		: IN STD_LOGIC_VECTOR (8 DOWNTO 0);
		inclock		: IN STD_LOGIC ;
		q		: OUT STD_LOGIC_VECTOR (7 DOWNTO 0)
	);
end component;

--------------------------------
signal rs : std_logic;
signal rw : std_logic;
signal en : std_logic;
signal data : std_logic_vector(7 downto 0);
signal showdata : std_logic_vector(7 downto 0);
--------------------------------
signal cnt : std_logic_vector(8 downto 0);
signal cnt_rst : std_logic;
--------------------------------
signal div_cnt : std_logic_vector(14 downto 0);
signal clk_div : std_logic;
--------------------------------
signal line_done : std_logic;
signal frame_done : std_logic;
--------------------------------
type state_gram is (idle,setbase1,setbase2,setmode1,setmode2,setcurs1,setcurs2,setexte1,setexte2,wr_y_addr1,wr_y_addr2,wr_x_addr1,wr_x_addr2,wr_data1,wr_data2);
signal current_state,next_state : state_gram;
--------------------------------


begin
-------------------------------
 lcd_rs <= rs;
 lcd_rw <= rw;
 lcd_en <= en;
 lcd_data <= data;
-------------------------------
 rw <= '0';
-------------------------------
clock_div : process (clk, rst_n)
begin
 if rst_n = '0' then
  div_cnt <= (others => '0');
 elsif clk'event and clk = '1' then
  div_cnt <= div_cnt + 1;
 end if;
end process; 
process (div_cnt)
begin
 if (div_cnt = 16#7FFF#) then
  clk_div <= '1';
 else 
  clk_div <= '0';
 end if;
end process;
--------------------------------
state_turn : process (clk_div, rst_n)
begin
 if rst_n = '0' then
  current_state <= idle;
 elsif clk_div'event and clk_div = '1' then
  current_state <= next_state;
 end if;
end process;
--------------------------------
state_com : process (current_state,line_done,frame_done,cnt,showdata)
begin
 rs <= '0';
 en <= '0';
 cnt_rst <= '0';
 data <= (others => '0');
 case current_state is
  when idle => next_state <= setbase1;

  when setbase1 => next_state <= setbase2;data <= "00110000";en <= '1';
  when setbase2 => next_state <= setmode1;data <= "00110000";

  when setmode1 => next_state <= setmode2;data <= "00000110";en <= '1';
  when setmode2 => next_state <= setcurs1;data <= "00000110";

  when setcurs1 => next_state <= setcurs2;data <= "00001100";en <= '1';
  when setcurs2 => next_state <= setexte1;data <= "00001100";

  when setexte1 => next_state <= setexte2;data <= "00110110";en <= '1';
  when setexte2 => next_state <= wr_y_addr1;data <= "00110110";cnt_rst <= '1';

  when wr_y_addr1 => next_state <= wr_y_addr2;data <= "100" & cnt(8 downto 4);en <= '1';
  when wr_y_addr2 => next_state <= wr_x_addr1;data <= "100" & cnt(8 downto 4);

  when wr_x_addr1 => next_state <= wr_x_addr2;data <= "10000000";en <= '1';
  when wr_x_addr2 => next_state <= wr_data1;data <= "10000000";


  when wr_data1 => next_state <= wr_data2;data <= showdata;en <= '1';rs <= '1';
  when wr_data2 => rs <= '1';data <= showdata;
                   if (line_done = '1') then
                    if (frame_done = '1') then
                     next_state <= idle;
                    else
                     next_state <= wr_y_addr1;
                    end if;
                   else
                    next_state <= wr_data1;
                   end if;

  when others => next_state <= idle;
 end case;
end process;
----------------------------------
cnt_p : process(clk_div,cnt_rst)
begin
 if clk_div'event and clk_div = '1' then
  if cnt_rst = '1' then 
   cnt <= (others => '0');
  elsif (current_state = wr_data2) then
   cnt <=cnt + 1;
  end if;
 end if;
end process;
process(cnt)
begin
 if (cnt(3 downto 0) = "1111") then
  line_done <= '1';
 else
  line_done <= '0';
 end if;
 if (cnt(8 downto 4) = "11111") then
  frame_done <= '1';
 else
  frame_done <= '0';
 end if;
end process;
rom1 : data_rom port map (address => cnt, inclock =>clk, q => showdata);
end;

⌨️ 快捷键说明

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