Learning

导航

I2C VHDL程序

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;

 

posted on 2016-08-30 21:00  xinjie  阅读(1531)  评论(0编辑  收藏  举报