首先,我的硬件没问题,我是在配置saa7113 ,急求解
下面是我的程序,
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
entity saa is
port(
clk_50m:in std_logic;
rst:in std_logic;
i2c_clk: inout std_logic;
i2c_data:inout std_logic;
saa7113_vpo:in std_logic_vector(7 downto 0);
saa7113_v:in std_logic;
saa7113_h:in std_logic;
-- ack:out std_logic;
saa7113_llc:in std_logic
);
end saa;
architecture Behavioral of saa is
---------------------------------------------------
---------------------------------------------------------
signal clk_div:integer range 0 to 249;
signal clk_400k: std_logic:='0';
-----------------------------------------------
type state is (i2c_wait,i2c_start,i2c_stop,i2c_write,i2c_idle);
signal i2c_state:state:=i2c_wait;
type write_state is (data,ack);
signal inner_state:write_state:=data;
signal cnt_bit:integer range 0 to 7;--×Ö½Ú¼ÆÊý
signal shift:std_logic_vector(7 downto 0);
signal cnt_data_w:integer range 0 to 33;
signal cnt_idle:std_logic_vector(15 downto 0);
signal cnt_delay:std_logic_vector(19 downto 0):=(others=>'0');
---------------------------------------------------
SIGNAL phase0 : std_logic;
SIGNAL phase1 : std_logic;
SIGNAL phase2 : std_logic;
SIGNAL phase3 : std_logic;
--------------------------------------------
signal shift_addr:std_logic;--shift table
signal sda_buf:std_logic;
signal scl_buf:std_logic;
signal temp:std_logic;
signal sda_valid:std_logic;
------------------------------------------------------------
type table_b is array(0 to 33) of std_logic_vector(7 downto 0);
type table_a is array(0 to 25) of std_logic_vector(7 downto 0);
signal table1:table_a:=((x"4a"),(x"01"),(x"08"),(x"c0"),(x"33"),(x"00"),(x"00"),(x"e0"),(x"0d"),(x"b8"),(x"01"),(x"80"),
(x"47"),(x"40"),(x"00"),(x"01"),(x"2a"),(x"38"),(x"0c"),(x"e8"),(x"00"),(x"00"),
(x"00"),(x"00"),(x"00"),(x"00"));
signal table2:table_b:=((x"4a"),(x"40"),(x"02"),(x"ff"),(x"ff"),(x"ff"),(x"ff"),(x"ff"),(x"ff"),(x"ff"),(x"ff"),(x"ff"),
(x"ff"),(x"ff"),(x"ff"),(x"ff"),(x"ff"),(x"ff"),(x"ff"),(x"ff"),(x"ff"),(x"ff"),
(x"ff"),(x"ff"),(x"ff"),(x"ff"),(x"00"),(x"00"),(x"07"),(x"80"),(x"00"),(x"00"),
(x"00"),(x"00"));
begin
-------------------------------------------------------------
--ack<=sdl_buf;
temp<=sda_buf when (sda_valid)='1' else 'Z';
i2c_data<=temp;
i2c_clk<=scl_buf;
---------------------------------------
PROCESS(clk_50m,rst)
BEGIN
IF (NOT rst = '1') THEN
clk_div <= 0;
phase0 <= '0';
phase1 <= '0';
phase2 <= '0';
phase3 <= '0';
ELSIF rising_edge(clk_50m)THEN
IF (clk_div /= 249) THEN -- 125
clk_div <= clk_div + 1;
ELSE
clk_div <= 0;
END IF;
case clk_div is
when 62 => phase1 <= '1';
when 125 => phase2 <= '1';
when 187 => phase3 <= '1';
when 249 => phase0 <= '1';
when others=>
phase0 <= '0';
phase1 <= '0';
phase2 <= '0';
phase3 <= '0';
end case;
END IF;
END PROCESS;
---------------------------------------------------
-----------
process(clk_50m,rst)
begin
if rst='0' then
cnt_delay<=(others=>'0');
elsif rising_edge(clk_50m) then
if cnt_delay=800000 then
if i2c_state=i2c_wait then
cnt_delay<=(others=>'0');
end if;
else
cnt_delay<=cnt_delay+1;
end if;
end if;
end process;
------------------------------------
process(rst,clk_50m)
begin
if rst='0' then
sda_valid<='0';
scl_buf<='1';
sda_buf<='1';
cnt_bit<=7;
cnt_data_w<=0;
cnt_idle<=(others=>'0');
shift<=(others=>'0');
shift_addr<='0';
i2c_state<=i2c_wait;
inner_state<=data;
elsif rising_edge(clk_50m) then
------------------------------------
if i2c_state=i2c_idle then
scl_buf<='1';
else
if phase0='1' then
scl_buf<='1';
else
if phase2='1' then
scl_buf<='0';
end if;
end if;
end if;
--------------------------------
case i2c_state is
when i2c_wait =>
sda_valid<='0';
if cnt_delay=800000 then
i2c_state<=i2c_start;
sda_valid<='1';
sda_buf<='1';
else
i2c_state<=i2c_wait;
end if;
when i2c_start =>
sda_valid<='1';
if phase1='1' and sda_valid='1'then
sda_buf<='0';
shift<=x"4a";--4A slave address w --4B slave address r
end if;
if phase3='1'and sda_buf='0' then
i2c_state<=i2c_write;
sda_buf<=shift(7);
end if;
cnt_data_w<=0;
cnt_bit<=7;
inner_state<=data;
when i2c_write =>
case inner_state is
when data =>
sda_valid<='1';
if phase3='1' then
if cnt_bit=0 then
inner_state<=ack;
cnt_data_w<=cnt_data_w+1;
sda_valid <= '0';
cnt_bit<=7;
else
sda_buf<=shift(cnt_bit-1);
i2c_state<=i2c_write;
cnt_bit<=cnt_bit-1;
inner_state<=data;
end if;
end if;
when ack =>
inner_state<=ack;
sda_valid <= '0';
if phase0='1' then
sda_buf<=i2c_data;
end if;
if phase1='1' then
if sda_buf='1' then
i2c_state<=i2c_start;
end if;
end if;
if phase3='1' then
sda_valid<='1';
cnt_bit<=7;
if shift_addr='0' then
if cnt_data_w=24 then -------
cnt_data_w<=0;
i2c_state<=i2c_stop;
sda_buf <= '0';
inner_state<=data;
else
shift<=table1(cnt_data_w+1);
inner_state<=data;
sda_buf<=shift(7);
end if;
else
if cnt_data_w=33 then -------
cnt_data_w<=0;
i2c_state<=i2c_stop;
sda_buf <= '0';
inner_state<=data;
else
shift<=table2(cnt_data_w+1);
inner_state<=data;
sda_buf<=shift(7);
end if;
end if;
end if;
end case;
when i2c_stop=>
sda_valid<='1';
IF (phase0 = '1') THEN
sda_buf <= '0';
END IF;
IF (phase1 = '1') THEN
sda_buf <= '1';
END IF;
IF (phase3 = '1') THEN
if shift_addr='1'then
i2c_state<=i2c_idle;
shift_addr<='0';
else
shift_addr<='1';
i2c_state<=i2c_start;
end if;
END IF;
when i2c_idle=>
shift<=(others=>'0');
sda_valid<='0';
cnt_bit<=7;
if cnt_idle=553 then
cnt_idle<=(others=>'0');
i2c_state<=i2c_idle;
else
i2c_state<=i2c_idle;
cnt_idle<=cnt_idle+1;
end if;
cnt_data_w<=0;
end case;
end if;
end process;
end Behavioral;
|