http://blog.sina.com.cn/s/blog_9bd80b7601012o9y.html
library ieee ;
use ieee.std_logic_1164.all ;
use ieee.std_logic_arith.all ;
use ieee.std_logic_unsigned.all ;
entity I2C_Control is
port (
CLKI :IN Std_logic ;
RST :IN Std_logic ;
Slave_add :in std_logic_vector(3 downto 0);
addr :in std_logic_vector(7 downto 0);
wr_rd :IN Std_logic ;
DAT1 :in std_logic_vector(7 downto 0);
Delay_Time :in integer range 0 to 255;
A :buffer std_logic_vector(2 downto 0);
WP :buffer std_logic;
SCL :buffer std_logic;
SDA :buffer std_logic
) ;
end I2C_Control ;
architecture Arch of I2C_Control is
type state1 is (Idle,Idle1, I1,I2,I3,I4,I5,I6,I7,I8,I9,I10,Iok);
signal current_state,next_state : state1;
signal I2C_Sent :std_logic_vector(26 downto 0);
begin
I2C_Sent <= Slave_add & A & wr_rd &'0'& addr &'0'& DAT1&'0' ;
process(clki,RST)
begin
if RST = '1' then
current_state <= Idle;
elsif clki'event and clki = '0' then
current_state <= next_state;
end if;
end process;
process(clki)
variable i :integer range 0 to 63;
variable cnt :integer range 0 to 1023;
begin
if clki'event and clki = '1' then
A<="111";
case current_state is
when Idle =>
SCL <= '1'; SDA <= '1';
WP <= '1';
next_state <= Idle1;
when Idle1 =>
SCL <= '1'; SDA <= '1';
WP <= '0';
next_state <= I1;
when I1 =>
SDA <= '0';
next_state <= I2;
when I2 =>
SCL <= '0';
i :=26;
next_state <= I3;
when I3 =>
SCL <= '0';
SDA <= I2C_Sent(i);
next_state <= I4;
when I4 =>
SCL <= '1';
next_state <= I5;
when I5 =>
if i= 0 then
next_state <= I6;
else
i := i-1;
next_state <= I3;
end if;
when I6 =>
SCL <= '0';
next_state <= I7;
when I7 =>
SCL<= '1';
next_state <= I8;
when I8 =>
SDA <= '1';
next_state <= I9;
when I9 =>
WP<= '1'; --1
next_state <= I10;
WHEN I10 =>
if cnt = Delay_Time then
cnt := 0;
next_state <= Idle;
else
cnt := cnt +1;
end if;
when Iok =>
SCL <='1';
SDA <= '1';
next_state <= Iok;
when others =>
next_state <= Iok;
end case;
end if;
end process;
end Arch;