sinat_21805667 2015-03-26 00:34 采纳率: 0%
浏览 2161

FPGA以I2C读取at24c128,接收不到应答信号

程序如下,程序一直停留在状态“1010”,也就是接收不到ACK,求各位大神帮忙
-------------------div 50M change to 1M-----------
process(clk1,reset)
variable Count:integer range 0 to 51;
begin
if reset = '0' then--异步清零信号
Count:=0;
elsif(clk1='1' and clk1'event) then
if Count=25 then
i2cclk<='0';
Count:=Count+1;
elsif Count=50 then
Count:=0;
i2cclk<= '1';
else
Count := Count+1;

end if;
end if;

end process;

-------------------I2C write---------------------------
process(i2cclk,reset)
variable i_cnt :integer range 8 downto 0:=8 ;
variable ack_cnt :integer range 0 to 8:=0 ;
variable ack_time :integer range 0 to 100:=0 ;
variable d_cnt :integer range 0 to 80:=0 ;
variable machine_addr:std_logic_vector(7 downto 0):="10100000";
variable i2caddrh:std_logic_vector(7 downto 0):="00000000";
variable i2caddrl:std_logic_vector(7 downto 0):="10100000";
variable i2cdata:std_logic_vector(7 downto 0):="01010101";
variable i2cwr_one :std_logic:='0';--
variable i2cdata_temp :std_logic:='0';--
begin
if reset = '0' then
i2cstatewr<="0000";
machine_addr:="10100000";
i2cdata:="01010101";
i2caddrh:="00000000";
i2cdata:="01010101";
i_cnt:=8;
d_cnt:=0;
i2cwr_one:='0';
ack_cnt:=0;
led<='1';
elsif(i2cclk='1' and i2cclk'event) then
case i2cstatewr is
when "0000"=>--init
d_cnt:=d_cnt+1;
if d_cnt=1 then
i2cda<='1';
i2cclk_s<='1';
i2cstatewr<="0000";
elsif d_cnt=delay_cnt then
d_cnt:=0;
-- if i2cwr_one='0' then
i2cstatewr<="0001";
-- else
-- i2cstatewr<="0000";
-- end if;
else
i2cstatewr<="0000";
end if;
when "0001"=>--i2c start
d_cnt:=d_cnt+1;
if d_cnt=1 then
i2cda<='0';
i2cstatewr<="0001";
elsif d_cnt=delay_cnt then
d_cnt:=0;
i2cstatewr<="0011";
else
i2cstatewr<="0001";
end if;
-- when "0010"=>
-- i2cclk_s<='0';
-- i2cstatewr<="0011";

when "0011"=>--i2c send machineaddr ,addrh,addrl,data
    d_cnt:=d_cnt+1;
    if d_cnt=1 then
        i2cclk_s<='0';
        i2cstatewr<="0011";
    elsif d_cnt=delay_cnt then
        d_cnt:=0;
        i_cnt:=i_cnt-1;
        i2cstatewr<="0100";
    else
        i2cstatewr<="0011";
    end if;
when "0100"=>
    d_cnt:=d_cnt+1;
    if d_cnt=1 then
        if ack_cnt=0 then
            i2cda<=machine_addr(i_cnt);
        elsif ack_cnt=1 then
            i2cda<=i2caddrh(i_cnt);
        elsif ack_cnt=2 then
            i2cda<=i2caddrl(i_cnt);
        elsif ack_cnt=3 then
            i2cda<=i2cdata(i_cnt);
        end if;
        i2cstatewr<="0100";
    elsif d_cnt=delay_cnt then
        d_cnt:=0;
        i2cstatewr<="0101";
    else
        i2cstatewr<="0100";
    end if;
when "0101"=>
    d_cnt:=d_cnt+1;
    if d_cnt=1 then
        i2cclk_s<='1';
        i2cstatewr<="0101";
    elsif d_cnt=delay_cnt then
        d_cnt:=0;
        if i_cnt=0 then
            i_cnt:=8;
            i2cstatewr<="0110";
        else
            i2cstatewr<="0011";
        end if;
    else
        i2cstatewr<="0101";
    end if;

when "0110" => --ninth clock
    d_cnt:=d_cnt+1;
    if d_cnt=1 then
        i2cclk_s<='0';
        i2cstatewr<="0110";
    elsif d_cnt=delay_cnt then --delay_cnt then
        d_cnt:=0;
        i2cstatewr<="0111";
    else
        i2cstatewr<="0110";
    end if;
when "0111"=> 
    d_cnt:=d_cnt+1;
    if d_cnt=1 then
        i2cda<='1';
        i2cstatewr<="0111";
    elsif d_cnt=delay_cnt then
        d_cnt:=0;
        i2cstatewr<="1000";
    else
        i2cstatewr<="0111";
    end if;

when "1000"=>--wait ack
    d_cnt:=d_cnt+1;
    if d_cnt=1 then
        i2cclk_s<='1';
        i2cstatewr<="1000";
    elsif d_cnt=delay_cnt then
        d_cnt:=0;
        i2cstatewr<="1001";
    else
        i2cstatewr<="1000";
    end if; 
when "1001"=>
    i2cdata_temp:=i2cda;
    if i2cdata_temp='1' then
        i2cstatewr<="1001";
    else
        i2cstatewr<="1010";
    end if;
when "1010"=>
    d_cnt:=d_cnt+1;
    if d_cnt=1 then
        i2cclk_s<='0';
        i2cstatewr<="1010";
    elsif d_cnt=delay_cnt then
        d_cnt:=0;
        ack_cnt:=ack_cnt+1;
        if ack_cnt =3 then  
            led<='0';   
            ack_cnt:=0;
            i2cstatewr<="0000";
        else
            i_cnt:=8;
            i2cstatewr<="0011";
        end if;
    else
        i2cstatewr<="1010";
    end if; 

-- when "1000"=>--i2c stop
-- i2cclk_s<='0';
-- i2cda<='0';
-- i2cstatewr<="1001";
-- when "1001"=>--
-- i2cclk_s<='1';
-- i2cstatewr<="1010";
-- when "1010"=>
-- i2cda<='1';
-- i2cwr_one:='1';
-- i2cstatewr<="0000";
when others=>
i2cstatewr<="0000";
end case;
end if;

end process;

  • 写回答

1条回答 默认 最新

  • sinat_21805667 2015-03-27 03:16
    关注

    解决了,原来是定义inout的数据,使用时错误,对三态门理解不够导致

    评论

报告相同问题?

悬赏问题

  • ¥20 有关区间dp的问题求解
  • ¥15 多电路系统共用电源的串扰问题
  • ¥15 slam rangenet++配置
  • ¥15 有没有研究水声通信方面的帮我改俩matlab代码
  • ¥15 对于相关问题的求解与代码
  • ¥15 ubuntu子系统密码忘记
  • ¥15 信号傅里叶变换在matlab上遇到的小问题请求帮助
  • ¥15 保护模式-系统加载-段寄存器
  • ¥15 电脑桌面设定一个区域禁止鼠标操作
  • ¥15 求NPF226060磁芯的详细资料