在以下 VHDL 代码中,当我使用逻辑或代码停止工作时,HD44780LCD 崩溃,但是当我删除逻辑或并删除其中一个支架时,代码再次开始工作。我正在使用 Xilinx Spartan 3E 入门板。换句话说,当我更换
SendCommand <= Holder(0);
和
SendCommand <= Holder(0) or Holder(1);
该程序行为怪异并崩溃。
这是代码:
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.STD_LOGIC_ARITH.all;
use IEEE.STD_LOGIC_UNSIGNED.all;
entity Main is
port(
CLK : in std_logic;
RIGHT : in std_logic;
left : in std_logic;
UP : in std_logic;
DOWN : in std_logic;
SF_DSW : in std_logic_vector(3 downto 0);
LED : out std_logic_vector(7 downto 0);
LCD_E : out std_logic;
LCD_RS : out std_logic;
LCD_RW : out std_logic;
SF_D : out std_logic_vector(11 downto 8)
);
end Main;
architecture Behavioral of Main is
component LCDS
port(
CLK : in std_logic;
Enable : in std_logic;
EnableCMD : in std_logic;
CMD : in std_logic_vector(7 downto 0);
ASCII : in std_logic_vector (7 downto 0);
LCD_E : out std_logic;
LCD_RS : out std_logic;
LCD_RW : out std_logic;
SF_D : out std_logic_vector(11 downto 8)
);
end component;
signal Char : std_logic_vector(7 downto 0);
signal SendChar : std_logic;
signal Command : std_logic_vector(7 downto 0) := X"80";
signal SendCommand : std_logic;
signal SDisable : std_logic_vector(2 downto 0);
signal Holder : std_logic_vector(2 downto 0);
constant MS3 : std_logic_vector(17 downto 0) := "100100100111110000";
begin
DisplayDriver : LCDS
port map(CLK, SendChar, SendCommand, Command, Char, LCD_E, LCD_RS, LCD_RW, SF_D);
SendKey : process (CLK)
begin
if rising_edge(CLK) then
if SDisable(0) = '0' then
if left = '1' then Holder(0) <= '1'; SDisable(0) <= '1'; end if;
elsif left = '1' and SDisable(0) = '1' then Holder(0) <= '0';
else
if left = '0' and SDisable(0) = '1' then SDisable(0) <= '0'; end if;
end if;
if SDisable(1) = '0' then
if right = '1' then Holder(1) <= '1'; SDisable(1) <= '1'; end if;
elsif right = '1' and SDisable(1) = '1' then Holder(1) <= '0';
else
if right = '0' and SDisable(1) = '1' then SDisable(1) <= '0'; end if;
end if;
if SDisable(2) = '0' then
if UP = '1' then Holder(2) <= '1'; SDisable(2) <= '1'; end if;
elsif UP = '1' and SDisable(2) = '1' then Holder(2) <= '0';
else
if UP = '0' and SDisable(2) = '1' then SDisable(2) <= '0'; end if;
end if;
if left = '1' then
if ((Command > X"7F") and (Holder(0) = '1')) then
Command <= Command -1;
end if;
elsif right = '1' then
if ((Command < X"D1") and (Holder(1) = '1')) then
Command <= Command +1;
end if;
end if;
if UP = '1' then
if Holder(2) = '1' then
Char <= Char +1;
end if;
end if;
if SF_DSW = X"0" then
LED <= X"00";
LED(3 downto 0) <= left&right&DOWN&UP;
LED(4) <= ((left or right) or UP);
elsif SF_DSW = X"1" then
LED <= Char;
elsif SF_DSW = X"2" then
LED <= Command;
end if;
SendCommand <= (Holder(0));
--Not working when
--SendCommand <= (Holder(0) or Holder(1));
SendChar <= Holder(2);
end if;
end process;
end Behavioral;
这是 DisplayDriver 组件代码如果它有用
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.STD_LOGIC_ARITH.all;
use IEEE.STD_LOGIC_UNSIGNED.all;
entity LCDS is
port(
CLK : in std_logic;
Enable : in std_logic;
EnableCMD : in std_logic;
CMD : in std_logic_vector(7 downto 0);
ASCII : in std_logic_vector (7 downto 0);
LCD_E : out std_logic;
LCD_RS : out std_logic;
LCD_RW : out std_logic;
SF_D : out std_logic_vector(11 downto 8)
);
end LCDS;
architecture Behavioral of LCDS is
type Conf is (S1, S2, S3, S4, Done);
type Initx is (FuncSet, DisplaySet, DisplayOn, MWait, Custom, Done);
type DelaySet is (MS5000, MS1000, MS2, US300, NS500, US160, none);
type Chars is (A, none);
signal Conf_s : Conf := S1;
signal Init_s : Initx;
signal Chars_s : Chars := none;
signal SDisable : std_logic := '0';
signal SDisableCMD : std_logic := '0';
signal DelaySet_s : DelaySet;
signal Counter : std_logic_vector(29 downto 0);
signal XLatch : std_logic := '0';
begin
Display : process(CLK, Enable, EnableCMD)
begin
if rising_edge(CLK) then
LCD_RW <= '0';
if SDisable = '0' then
if Enable = '1' then Chars_s <= A; SDisable <= '1'; end if;
elsif Enable = '1' and SDisable = '1' then Chars_s <= none;
else
if Enable = '0' and SDisable = '1' then SDisable <= '0'; end if;
end if;
if SDisableCMD = '0' then
if EnableCMD = '1' then Init_s <= Custom; SDisable <= '1'; end if;
elsif EnableCMD = '1' and SDisableCMD = '1' then Init_s <= Done;
else
if EnableCMD = '0' and SDisableCMD = '1' then SDisableCMD <= '0'; end if;
end if;
if DelaySet_s = none then
if not (Conf_s = Done) then
case Conf_s is
when S1 =>
LCD_RS <= '0';
SF_D <= X"3";
DelaySet_s <= MS2;
Conf_s <= S2;
LCD_E <= '1';
when S2 =>
LCD_RS <= '0';
SF_D <= X"3";
DelaySet_s <= US160;
Conf_s <= S3;
LCD_E <= '1';
when S3 =>
LCD_RS <= '0';
SF_D <= X"3";
DelaySet_s <= US160;
Conf_s <= S4;
LCD_E <= '1';
when S4 =>
LCD_RS <= '0';
SF_D <= X"2";
DelaySet_s <= US160;
Conf_s <= Done;
LCD_E <= '1';
when others => null;
end case;
elsif not(Init_s = Done) then
case Init_s is
when FuncSet =>
if XLatch = '0' then
LCD_RS <= '0';
SF_D <= X"2";
XLatch <= '1';
DelaySet_s <= US300;
LCD_E <= '1';
else
LCD_RS <= '0';
SF_D <= X"8";
XLatch <= '0';
delaySet_s <= US300;
Init_s <= DisplaySet;
LCD_E <= '1';
end if;
when DisplaySet =>
if XLatch = '0' then
LCD_RS <= '0';
SF_D <= X"0";
XLatch <= '1';
delaySet_s <= US300;
LCD_E <= '1';
else
LCD_RS <= '0';
SF_D <= X"8";
XLatch <= '0';
delaySet_s <= US300;
Init_s <= DisplayOn;
LCD_E <= '1';
end if;
when DisplayOn =>
if XLatch = '0' then
LCD_RS <= '0';
SF_D <= X"0";
XLatch <= '1';
delaySet_s <= US300;
LCD_E <= '1';
else
LCD_RS <= '0';
SF_D <= X"F";
XLatch <= '0';
delaySet_s <= MS2;
Init_s <= MWait;
LCD_E <= '1';
end if;
when MWait =>
XLatch <= '0';
LCD_E <= '0';
DelaySet_s <= MS2;
Init_s <= Done;
when Custom =>
if XLatch = '0' then
LCD_RS <= '0';
SF_D <= CMD(7 downto 4);
XLatch <= '1';
delaySet_s <= US300;
LCD_E <= '1';
else
LCD_RS <= '0';
SF_D <= CMD(3 downto 0);
XLatch <= '0';
delaySet_s <= MS2;
Init_s <= MWait;
LCD_E <= '1';
end if;
when others => null;
end case;
elsif Chars_s = A then
case Chars_s is
when A =>
if XLatch = '0' then
LCD_RS <= '1';
SF_D <= ASCII(7 downto 4);
XLatch <= '1';
DelaySet_s <= US300;
LCD_E <= '1';
else
LCD_RS <= '1';
SF_D <= ASCII(3 downto 0);
XLatch <= '0';
DelaySet_s <= US160;
LCD_E <= '1';
Chars_s <= none;
end if;
when others => null;
end case;
end if;
else
case DelaySet_s is
when MS5000 =>
if Counter < "1110111001101011001010000000" then
Counter <= Counter + 1;
else
LCD_E <= '0';
Counter <= (others => '0');
DelaySet_s <= none;
end if;
when MS1000 =>
if Counter < "10111110101111000010000000" then
Counter <= Counter + 1;
else
LCD_E <= '0';
Counter <= (others => '0');
DelaySet_s <= none;
end if;
when MS2 =>
if Counter < "11000011010100000" then
Counter <= Counter + 1;
else
LCD_E <= '0';
Counter <= (others => '0');
DelaySet_s <= none;
end if;
when US300 =>
if Counter < "11101010011000" then
Counter <= Counter + 1;
else
LCD_E <= '0';
Counter <= (others => '0');
DelaySet_s <= none;
end if;
when US160 =>
if Counter < "1111101000000" then
Counter <= Counter + 1;
else
LCD_E <= '0';
Counter <= (others => '0');
DelaySet_s <= none;
end if;
when NS500 =>
if Counter < "11001" then
Counter <= Counter + 1;
else
LCD_E <= '0';
Counter <= (others => '0');
DelaySet_s <= none;
end if;
when others => null;
end case;
end if;
end if;
end process;
end Behavioral;