VHDL,Xilinx Waveshare 3S500E中的LCD 16x2初始化

时间:2018-12-21 17:29:31

标签: initialization vhdl xilinx lcd

我正在尝试编写vhdl代码以使用VHDL从waveshare初始化LCD16x2,我已经运行了与板卡一起发送的示例文件,但是它只能打开显示器,我真的不太了解代码,我是VHDL的新手,我这样做是出于学习目的。以下是Wave分享的示例代码:

--???21EDA??
--?????:A-C8V4
--www.21eda.com
--??LCD????
--????????21EDA????????
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; --???????????????????????????????????
        Reset:in std_logic; 
        LCD_RS : out std_logic; --Instruction/Data Register Selection 0:instruction Register, 1:Data register
        LCD_RW : out std_logic; --read/write 0:register write, 1:register read
        LCD_EN : out std_logic; --enable

        LCD_N : out std_logic; --??????
        LCD_P : out std_logic; --??????
        VSS : out std_logic; --??????
        VDD : out std_logic; --??????
        VO : out std_logic; --??????

        LCD_Data : out std_logic_vector(7 downto 0)
        ); --??????
end LCD1602;


architecture Behavioral of LCD1602 is
    type state is (set_dlnf,set_cursor,set_dcb,set_cgram,write_cgram,set_ddram,write_LCD_Data);
    signal Current_State:state;
    type ram1 is array(0 to 30) of std_logic_vector(7 downto 0);
    type ram2 is array(0 to 30) of std_logic_vector(7 downto 0);
    type ram3 is array(0 to 30) of std_logic_vector(7 downto 0);
    constant cgram1:ram1:=(x"20",x"41",x"42",x"43",x"44",x"45",x"46",x"47",x"48",x"49",x"20",x"20",x"20",x"20",x"20",x"20",x"20",x"20",x"20",x"20",x"20",x"20",x"20",x"20",x"20",x"20",x"20",x"20",x"20",x"20",x"20"); 
    constant cgram3:ram3:=(x"30",x"31",x"32",x"33",x"34",x"35",x"36",x"37",x"38",x"39",x"20",x"20",x"20",x"20",x"20",x"20",x"20",x"20",x"20",x"20",x"20",x"20",x"20",x"20",x"20",x"20",x"20",x"20",x"20",x"20",x"20"); 
    constant cgram2:ram2:=(x"57",x"57",x"57",x"A4",x"57",x"41",x"56",x"45",x"53",x"48",x"41",x"52",x"45",x"A4",x"4E",x"45",x"54",x"20",x"20",x"20",x"20",x"20",x"20",x"20",x"20",x"20",x"20",x"20",x"20",x"20",x"20"); 
    signal CLK1 : std_logic;
    signal Clk_Out : std_logic;
    signal LCD_Clk : std_logic;
    signal m :std_logic_vector(1 downto 0);
begin
    LCD_EN <= Clk_Out ; 
    LCD_RW <= '0' ; 

    LCD_N<='0';
    LCD_P<='1';
    VSS<='0';
    VDD<='1';
    VO<='1'; 


    process(CLK)
        variable n1:integer range 0 to 19999;
    begin 
        if rising_edge(CLK) then
            if n1<19999 then
                n1:=n1+1;
            else 
                n1:=0;
                Clk_Out<=not Clk_Out;
            end if;
        end if;
    end process;

    LCD_Clk <= Clk_Out;

    process(Clk_Out)
        variable n2:integer range 0 to 499;
    begin 
        if rising_edge(Clk_Out) then
            if n2<499 then
                n2:=n2+1;
            else
                n2:=0;
                Clk1<=not Clk1;
            end if;
        end if;
    end process;


    process(Clk1)
        variable n3:integer range 0 to 14;
    begin
        if rising_edge(Clk1) then
            n3:=n3+1;
            if n3<=4 then  
                m<="00";
            elsif n3<=9 and n3>4 then
                m<="01";
            else
                m<="10";
            end if;
        end if;
    end process;


process(LCD_Clk,Reset,Current_State)
    variable cnt1: std_logic_vector(4 downto 0);
begin
    if Reset='0'then
        Current_State<=set_dlnf;
        cnt1:="11110"; 
        LCD_RS<='0';
    elsif rising_edge(LCD_Clk)then
        Current_State <= Current_State ;
        LCD_RS <= '0';

        case Current_State is
            when set_dlnf=> 
                cnt1:="00000"; 
                LCD_Data<="00000001";   --  /*????*/ 
                Current_State<=set_cursor;
            when set_cursor=>
                LCD_Data<="00111000";   --/*??8???,2?,5*7*/  
                Current_State<=set_dcb;
            when set_dcb=>
                LCD_Data<="00001100";   --/*????,???,???*/  
                Current_State<=set_cgram;
            when set_cgram=>
                LCD_Data<="00000110";
                Current_State<=write_cgram;
            when write_cgram=> 
                LCD_RS<='1';
                    if m="00" then
                        LCD_Data<=cgram1(conv_integer(cnt1));
                    elsif m="01"then
                        LCD_Data<=cgram1(conv_integer(cnt1));
                    else
                        LCD_Data<=cgram1(conv_integer(cnt1));
                    end if;
                Current_State<=set_ddram; 
            when set_ddram=> 
                    if cnt1<"11110" then
                        cnt1:=cnt1+1;
                    else
                        cnt1:="00000";
                    end if;

                    if cnt1<="01111" then
                        LCD_Data<="10000000"+cnt1;--80H 
                    else
                        LCD_Data<="11000000"+cnt1-"10000";--80H 
                    end if;

                Current_State<=write_LCD_Data;
            when write_LCD_Data=> 
                    LCD_Data<="00000000";  
                Current_State<=set_cursor;
            when others => null;
            end case;
    end if;
end process;

end Behavioral;

我试图编写自己的状态机,并使用在网上找到的说明使LCD正常工作,但直到现在仍未成功,有人可以提示我如何解决我的问题吗?提前致谢。

我的代码:

LIBRARY ieee;
USE ieee.std_logic_1164.ALL;

ENTITY LCD IS
  PORT(
    clk        : IN    STD_LOGIC;  --system clock
    reset_n    : IN    STD_LOGIC;  --active low reinitializes lcd
    rw, rs  : OUT   STD_LOGIC;  --read/write, setup/data, and enable for lcd
    lcd_enable : OUT    STD_LOGIC;  --latches data into lcd controller
    LCD_N : out std_logic; --??????
     LCD_P : out std_logic;
     VSS : out std_logic; --??????
     VDD : out std_logic; --??????
     VO : out std_logic; --??????
     lcd_data   : OUT   STD_LOGIC_VECTOR(7 DOWNTO 0)
    ); --data signals for lcd
END LCD;

ARCHITECTURE controller OF LCD IS
  TYPE CONTROL IS(power_up,initialize1,initialize2,initialize3,doneinit,sendData);
  SIGNAL    state      : CONTROL;
  CONSTANT  freq       : INTEGER := 50; --system clock frequency in MHz
BEGIN

    LCD_N<='0';
    LCD_P<='1';
    VSS<='0';
    VDD<='1';
    VO<='1'; 


  PROCESS(clk)
    VARIABLE clk_count : INTEGER; --event counter for timing
  BEGIN

    IF(clk'EVENT and clk = '1') THEN

      CASE state IS
        WHEN power_up =>
          IF(clk_count < (30000 * freq)) THEN    --wait 30 ms
            clk_count := clk_count + 1;
            state <= power_up;
          ELSE                                   --power-up complete
            clk_count := 0;
            rs <= '0';
            rw <= '0';
            lcd_data <= "00111100";--function set

                state <= initialize1;
          END IF;


        WHEN initialize1 =>
          IF(clk_count < ( 39 * freq)) THEN       --wait 39 us
            clk_count := clk_count + 1;
            state<=initialize1;
          ELSE
            clk_count := 0;
            lcd_data <= "00001111";     --Send Display On/Off
            state <= initialize2;
          END IF;

        WHEN initialize2 =>  
          IF(clk_count < (39 * freq)) THEN    --wait 39 us
            clk_count := clk_count + 1;
            state<=initialize2;
          ELSE
            clk_count := 0;
            rs <= '0';
         rw <= '0';
            lcd_data <= "00000110"; --Send Entry Mode set
         state <=initialize3;
          END IF;

        WHEN initialize3 =>  
          IF(clk_count < (39 * freq)) THEN    --wait 39 us
            clk_count := clk_count + 1;
            state<=initialize3;
          ELSE
            clk_count := 0;
            rs <= '0';
         rw <= '0';
            lcd_data <= "00000001"; --Send Display clear

          state <=doneinit;
          END IF;

        WHEN doneinit =>  
         clk_count := 0;
            rs <= '0';
         rw <= '0';
            lcd_data <= "00110001"; --
         lcd_enable<='1';
            state <=sendData;


          WHEN sendData=>



      END CASE;    

      --reset
      IF(reset_n = '0') THEN
          state <= power_up;
      END IF;

    END IF;
  END PROCESS;
END;

0 个答案:

没有答案