打印

用vhdl写的i2c无应答

[复制链接]
890|1
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主

首先,我的硬件没问题,我是在配置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  =>          
                                         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;
                                                                if shift_addr='0' then
                                                                  shift<=table1(cnt_data_w+1);
                                                                else
                                                                  shift<=table2(cnt_data_w+1);
                                                                end if;
                                                    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
                                                                         
                                                                          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
                                                                         
                                                                         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_wait;
                                else
                                        i2c_state<=i2c_wait;
                                        cnt_idle<=cnt_idle+1;
                end if;       
                    cnt_data_w<=0;                                       
        end case;                                 
   end if;                         
end process;
end Behavioral;

相关帖子

沙发
aspire_su|  楼主 | 2013-12-6 20:32 | 只看该作者
这个是仿真图

QQ截图20131206195129.png (12.44 KB )

QQ截图20131206195129.png

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

2

主题

8

帖子

0

粉丝