我正在尝试编写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;