我想使自己熟悉Cyclone V FPGA,我有一个Cyclone V GT开发套件。开发套件带有一个16x2字符LCD(NHD-0216K3Z-NSW-BBW-V3)。 LCD通过I2C连接到FPGA,默认情况下只有2个连接SDA和SCL。我只是想让它做任何事情,但是什么也没发生。
我已经用VHDL编写了一些代码,并使用ModelSim和SignalTap进行调试。一切似乎都还可以,但是什么也没发生。液晶显示屏上电时显示未连接,并且没有任何变化。最后的过程只是将时钟用于SignalTap进行采样。
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.std_logic_unsigned.all;
entity LCD_1 is
port (
dsw : in std_logic;
clk_50M : in std_logic;
led : out std_logic;
i2c_scl : out std_logic;
i2c_sda : inout std_logic
);
end entity;
architecture Behavioral of LCD_1 is
component PLL is
port (
refclk : in std_logic;
rst : in std_logic;
outclk_0 : out std_logic
);
end component;
signal clk_5M : std_logic;
signal clk_50k : std_logic := '0';
signal sig_i2c_scl : std_logic := '1';
signal sig_i2c_sda : std_logic := '1';
signal routine : integer := 0;
signal ack : std_logic := '0';
signal ack_returned : std_logic := '0';
signal bounce : std_logic := '0';
signal data : std_logic_vector (7 downto 0);
signal rst : std_logic := '0';
signal clk_10M : std_logic;
begin
PLL_Please : component PLL
port map(
refclk => clk_50M,
rst => rst,
outclk_0 => clk_10M
);
process(clk_50M)
variable count : integer range 0 to 1000;
begin
if rising_edge(clk_50M) then
case count is
when 1000 => clk_50k <= not clk_50k;
count := 0;
when others => count := count + 1;
end case;
end if;
end process;
process(clk_50M)
variable state : integer range 0 to 1000;
begin
if rising_edge(clk_50M) then
if dsw = '0' then
case state is
when 1000 => bounce <= '1';
when others => state := state + 1;
end case;
else
bounce <= '0';
state := 0;
end if;
end if;
end process;
data <= x"50" when routine = 0 else
x"FE" when routine = 1 else
x"70";
i2c_scl <= sig_i2c_scl;
i2c_sda <= sig_i2c_sda when ack <= '0' else 'Z';
ack_returned <= i2c_sda;
process(clk_50k, bounce)
variable state : integer range 0 to 13;
variable index : integer range 7 downto 0;
begin
if rising_edge(clk_50k) then
if bounce = '1' then
case state is
when 0 => sig_i2c_sda <= '0';
state := 1;
when 1 => sig_i2c_scl <= '0';
state := 2;
when 2 => sig_i2c_sda <= data(index);
state := 3;
when 3 => sig_i2c_scl <= '1';
if index = 0 then
state := 5;
else
state := 4;
end if;
when 4 => index := index - 1;
state := 1;
when 5 => index := 7;
state := 6;
when 6 => sig_i2c_scl <= '0';
state := 7;
when 7 => ack <= '1';
state := 8;
when 8 => sig_i2c_scl <= '1';
state := 9;
when 9 => state := 10;
when 10 => sig_i2c_scl <= '0';
if ack_returned = '1' then
state := 2;
elsif routine < 2 then
routine <= routine + 1 ;
state := 2;
else
state := 11;
end if;
ack <= '0';
when 11 => state := 12;
when 12 => sig_i2c_scl <= '1';
state := 13;
when 13 => sig_i2c_sda <= '1';
end case;
else
sig_i2c_scl <= '1';
sig_i2c_sda <= '1';
state := 0;
ack <= '0';
routine <= 0;
index := 7;
end if;
end if;
end process;
process(clk_10M)
variable counter : integer range 0 to 2000;
begin
if rising_edge(clk_10M) then
case counter is
when 1000 => counter := counter + 1;
led <= '1';
when 2000 => led <= '0';
counter := 0;
when others => counter := counter + 1;
end case;
end if;
end process;
end Behavioral;