打印

IIC求助

[复制链接]
1164|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
小工兵|  楼主 | 2014-4-5 18:50 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
小弟写了一个操作WC24C08的代码,经检测发现从机无应答,望高手指教
不胜感激
module i2c_controller_top(clk,rst,scl,sda,dout);
        input clk,rst;
        //input [7:0]din;
        output scl;
        inout sda;
        //input wr,rd;
        output[7:0] dout;
       
        parameter[19:0] start_a=20'b0000_0000_0000_0000_0001;
        parameter[19:0] start_b=20'b0000_0000_0000_0000_0010;
        parameter[19:0] start_c=20'b0000_0000_0000_0000_0100;
        parameter[19:0] start_d=20'b0000_0000_0000_0000_1000;
        parameter[19:0] stop_a=20'b0000_0000_0000_0001_0000;
        parameter[19:0] stop_b=20'b0000_0000_0000_0010_0000;
        parameter[19:0] stop_c=20'b0000_0000_0000_0100_0000;
        parameter[19:0] stop_d=20'b0000_0000_0000_1000_0000;
        parameter[19:0] write_a=20'b0000_0000_0001_0000_0000;
        parameter[19:0] write_b=20'b0000_0000_0010_0000_0000;
        parameter[19:0] write_c=20'b0000_0000_0100_0000_0000;
        parameter[19:0] write_d=20'b0000_0000_1000_0000_0000;
        parameter[19:0] read_a=20'b0000_0001_0000_0000_0000;
        parameter[19:0] read_b=20'b0000_0010_0000_0000_0000;
        parameter[19:0] read_c=20'b0000_0100_0000_0000_0000;
   parameter[19:0] read_d=20'b0000_1000_0000_0000_0000;
        parameter[19:0] ack_a=20'b0001_0000_0000_0000_0000;
        parameter[19:0] ack_b=20'b0010_0000_1000_0000_0000;
        parameter[19:0] ack_c=20'b0001_0000_0000_0000_0001;
        parameter[19:0] ack_d=20'b0010_0000_1000_0000_0010;
        parameter[19:0] idle=20'b0100_0000_1000_0000_0000;
        //parameter ack_d=1000_0000_1000_0000_0000;
       
        reg[7:0]clk_cnt;
        reg[3:0]dcnt;
        reg[19:0] state;
        //reg clk_en;
        reg sda_buf;
        reg[1:0] cmd=0;
        reg link;
        reg rw=0;
        reg scl;
        reg[7:0] dout;       
        reg[7:0] din;
        reg[6:0] cnt;
       
        wire dcnt_done;
        wire clk_en;
        wire sda;
        wire cnt_en=clk_cnt[6]&clk_cnt[5]&clk_cnt[4]&clk_cnt[3]&clk_cnt[2]&clk_cnt[1]&clk_cnt[0];
       
        assign dcnt_done=~|dcnt;
        //assign din=8'h0f;
        assign clk_en=&clk_cnt;
        assign sda=link?1'bz:sda_buf;
        //assign go=wr^rd;
       
        always@(posedge clk or negedge rst )begin
                if(!rst)begin
                        clk_cnt<=8'd0;
                        //clk_en<=0;
                end
                else if(clk_en)begin
                        clk_cnt<=8'd0;
                        //clk_en<=0;
                end
                else clk_cnt<=clk_cnt+8'd1;
        end
       
        always@(posedge clk or negedge rst)begin
                if(!rst)begin
                        sda_buf<=1;
                        scl<=1;
                        state<=idle;
                        dcnt<=0;
                end
                else if(clk_en) begin
                        case(state)
                                idle: begin
                                                        //sda_buf<=din;
                                                        //rw<=~rw;
                                                        dcnt<=4'd7;
                                                        cmd<=0;
                                                        link<=0;
                                                        sda_buf<=1;
                                                        scl<=1;
                                                        //if(go)
                                                        state<=start_a;
                                                        //else state<=idle;
                                                end
                        start_a: begin
                                                        sda_buf<=1;
                                                        scl<=1;
                                                        state<=start_b;
                                                end
                        start_b: begin
                                                        sda_buf<=0;
                                                        scl<=1;
                                                        state<=start_c;
                                                end
                        start_c: begin
                                                        sda_buf<=0;
                                                        scl<=0;
                                                        state<=start_d;
                                                end
                        start_d: begin
                                                        sda_buf<=0;
                                                        scl<=0;
                                                        if(rw==0)begin
                                                                state<=write_a;
                                                                /*if(cmd==0)
                                                                din<=8'ha0;
                                                                else if(cmd==1)
                                                                        din<=8'd3;
                                                                else if(cmd==2)begin
                                                                        cmd<=0;
                                                                //sda_buf<=din;
                                                                        din<=8'h0f;
                                                                end*/
                                                        end
                                                        else begin
                                                                //state<=read_a;
                                                                if(cmd==3)begin
                                                                        state<=read_a;
                                                                        //cmd<=0;
                                                                end
                                                                else state<=write_a;
                                                        end
                                                end
                   write_a: begin
                                                        if(cmd==0)
                                                                din=8'ha0;
                                                        else if(cmd==1)
                                                                din=8'd3;
                                                        else if(cmd==2)begin
                                                                if(rw==0) din=8'h0f;
                                                                else din=8'ha1;
                                                        end
                                                        scl<=0;
                                                        link<=0;
                                                        state<=write_b;
                                                        sda_buf<=din[dcnt];
                                                end
                        write_b: begin
                                                        scl<=1;
                                                        sda_buf<=din[dcnt];
                                                        state<=write_c;
                                                        link<=0;
                                                end
                        write_c: begin
                                                        scl<=1;
                                                        sda_buf<=din[dcnt];
                                                        state<=write_d;
                                                        link<=0;
                                                end
                        write_d: begin
                                                        scl<=0;
                                                        link<=0;
                                                        dcnt<=dcnt-4'd1;
                                                        if(dcnt_done)begin
                                                                //link<=1;
                                                                sda_buf<=1;
                                                                dcnt<=4'd7;
                                                                state<=ack_a;
                                                        end
                                                        else state<=write_a;
                                                end
                          ack_a: begin
                                                        scl<=1;
                                                        link<=1;
                                                        if(sda==0)begin
                                                                if(cmd==2'd2)begin
                                                                        if(rw==1)
                                                                                state<=start_a;
                                                                        else begin state<=write_a; cmd<=0; end
                                                                end
                                                                cmd<=cmd+2'd1;
                                                                state<=write_a;
                                                        end
                                                        else state<=ack_b;
                                                end
                          ack_b: begin
                                                        scl<=0;
                                                        link<=1;
                                                        if(sda==0)begin
                                                                if(cmd==2'd2)begin  
                                                                        if(rw==1)
                                                                                state<=start_a;
                                                                        else begin state<=write_a;cmd<=0;end
                                                                end
                                                                cmd<=cmd+2'd1;
                                                                state<=write_a;
                                                        end
                                                        else state<=ack_a;
                                                end
                         read_a: begin
                                                        /*if(cmd==0)
                                                                din<=8'ha0;
                                                        else if(cmd==1)
                                                                din<=8'd3;
                                                        else if(cmd==2)
                                                                din<=8'ha1;
                                                        else if(cmd==3) begin
                                                                //sda_buf<=din;
                                                                cmd<=0;
                                                        end*/
                                                                scl<=0;
                                                                state<=read_b;
                                                                link<=1;
                                                                dout[dcnt]<=sda;
                                                end
                         read_b: begin
                                                        scl<=1;
                                                        dout[dcnt]<=sda;
                                                        state<=read_c;
                                                        link<=1;
                                                end
                         read_c: begin
                                                        scl=1;
                                                        dout[dcnt]<=sda;
                                                        state<=read_d;
                                                        link<=1;
                                                end
                         read_d: begin
                                                        scl<=0;
                                                        dcnt<=dcnt-4'd1;
                                                        if(dcnt_done)begin
                                                               
                                                                dcnt<=4'd7;
                                                                state<=stop_a;
                                                        end
                                                        else state<=read_a;
                                                        link<=1;
                                                end
                         stop_a: begin
                                                        link<=0;
                                                        scl<=1;
                                                        sda_buf<=0;
                                                        state<=stop_b;
                                                end
                         stop_b: begin
                                                        scl<=1;
                                                        sda_buf<=0;
                                                        state<=stop_c;
                                                end
                         stop_c: begin
                                                        scl<=1;
                                                        sda_buf<=1;
                                                        state<=stop_d;
                                                end
                         stop_d: begin
                                                        //scl<=1;
                                                        //sda<=1;
                                                        if(cmd==3) state<=stop_d;
                                                        state<=idle;
                                                        rw<=~rw;
                                                end
                                endcase
                        end
                //end
        end

endmodule

相关帖子

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

本版积分规则

8

主题

25

帖子

1

粉丝