查看: 358|回复: 3
打印 上一主题 下一主题

求教FPGA读取I2C总线的E2PROM问题

[复制链接] qrcode

1

主题

3

帖子

9

积分

新手上路

Rank: 1

积分
9
楼主
跳转到指定楼层
发表于 2015-12-26 10:45 AM | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本人在测试读写I2C,但是搞了很久都没行,我是从单片机程序利用状态机方式改写的verilog程序,大体功能就是能够在固定地址读写1字节的数据就可以。clk频率为0.2M(分频过)
inout sda;
output scl;
reg io; //定义略写
assign sda=(io==1)?1'bz:sdat; //when io="1",sda is input state ,or sda is output state

always@(posedge clk or negedge rst)
if(!rst)
begin
(略)
end
else
begin
/*-------------------------------读I2C----------------------------------------*/
begin
case (state_h)
//--------------Start()------------//
h0:begin io<=0;sdat<=1; scl<=1; state_h<=h1; end
h1:begin sdat<=0; state_h<=h2; end//发送起始信
h2:begin scl<=0; state_h<=h3; end//钳住I2C总线准备发送或接收数据
//-----------发送器件地址Send(a0)写------------//
h3:begin if(bitcnt==8)begin bitcnt<=0; state_h<=h7; end
else begin state_h<=h4 ;end
end
h4:begin if((8'ha0< h5:begin scl<=1; state_h<=h6; end//置时14us
h6:begin scl<=0; bitcnt<=bitcnt+1; state_h<=h3; end
//------------应答Ack()-----------------//
h7:begin sdat<=0; state_h<=h8; end
h8:begin scl<=1; state_h<=h9; end
h9:begin scl<=0; state_h<=h10; end
//----------发送存储单元地址Send(0)----------//
h10:begin if(bitcnt==8)begin bitcnt<=0; state_h<=h14;end
else begin state_h<=h11 ;end
end
h11:begin if((8'h0f< h12:begin scl<=1; state_h<=h13;end
h13:begin scl<=0; bitcnt<=bitcnt+1; state_h<=h10;end
//------------应答Ack()-----------------//
h14:begin sdat<=0; state_h<=h15;end
h15:begin scl<=1; state_h<=h16;end
h16:begin scl<=0; state_h<=h17;end
//--------------Start()------------//
h17:begin sdat<=1; scl<=1; state_h<=h18;end
h18:begin sdat<=0; state_h<=h19;end
h19:begin scl<=0; state_h<=h20;end
//-----------发送器件地址Send(a1)读------------//
h20:begin if(bitcnt==8)begin bitcnt<=0; state_h<=h24;end
else begin state_h<=h21 ;end
end
h21:begin if((8'ha1< h22:begin scl<=1; state_h<=h23;end
h23:begin scl<=0; bitcnt<=bitcnt+1; state_h<=h20;end
//------------应答位Ack()-----------------//
h24:begin sdat<=0; state_h<=h25;end
h25:begin scl<=1; state_h<=h26;end
h26:begin scl<=0; state_h<=h27;end
//------------读一字节数据Read()-----------------//
h27:begin rcv<=0; io<=1; state_h<=h28;end//置数据to input state

h28:begin if(bitcnt==8)begin bitcnt<=0; ini_decay<=rcv; io<=0; state_h<=h32;end //read to ini_decay
else begin scl<=0; state_h<=h29 ;end //置时钟线为低,准备接收数据位,>4.7us
end
h29:begin scl<=1; state_h<=h30;end//置时钟线为高,使数据线数据有效
h30:begin rcv<=rcv<<1; state_h<=h31;end
h31:begin if(sda==1)rcv<=rcv+1; bitcnt<=bitcnt+1; state_h<=h28;end//读数据位,接收的数据位放入rcv sdat or sda??
h32:begin scl<=0; state_h<=h33;end
//---------------NoAck()-----------------------//
h33:begin sdat<=1; state_h<=h34;end
h34:begin scl<=1; state_h<=h35;end
h35:begin scl<=0; state_h<=h36;end
//---------------Stop()-----------------------//
h36:begin sdat<=0;scl<=1; state_h<=h37;end
h37:begin sdat<=1; state_h<=h38;end

h38:begin ini_iic_ok<=1; state_h<=h38;end //read e2prom over

default: begin state_h<=h0; end
endcase
end
///////////////////////////写I2C///////////////////////////////////////////////
begin
case(state_k)
//--------------Start()------------//
k0:begin io<=0;sdat<=1; scl<=1; wc<=0; state_k<=k1; end //write control
k1:begin sdat<=0; state_k<=k2;end
k2:begin scl<=0; state_k<=k3;end
//-----------发送器件地址Send(a0)------------//
k3:begin if(bitcnt==8)begin bitcnt<=0; state_k<=k7; end
else begin state_k<=k4; end
end
k4:begin if((8'ha0< k5:begin scl<=1; state_k<=k6;end
k6:begin scl<=0; bitcnt<=bitcnt+1;state_k<=k3;end
//------------应答位Ack()-----------------//
k7:begin sdat<=0; state_k<=k8;end
k8:begin scl<=1; state_k<=k9;end
k9:begin scl<=0; state_k<=k10;end
//----------发Send(0)----------//
k10:begin if(bitcnt==8)begin bitcnt<=0; state_k<=k14;end
else begin state_k<=k11 ;end
end
k11:begin if((8'h0f< k12:begin scl<=1; state_k<=k13;end
k13:begin scl<=0; bitcnt<=bitcnt+1; state_k<=k10;end
//------------应答位Ack()-----------------//
k14:begin sdat<=0; state_k<=k15;end
k15:begin scl<=1; state_k<=k16;end
k16:begin scl<=0; state_k<=k17;end
//------------写Send(decay)-----------------//
k17:begin if(bitcnt==8)begin bitcnt<=0; state_k<=k21; end
else begin state_k<=k18 ;end
end
k18:begin if((8'haa< k19:begin scl<=1; state_k<=k20;end
k20:begin scl<=0; bitcnt<=bitcnt+1; state_k<=k17;end
//------------应答位Ack()-----------------//
k21:begin sdat<=0; state_k<=k22;end
k22:begin scl<=1; state_k<=k23;end
k23:begin scl<=0; state_k<=k24;end
//---------------Stop()-----------------------//
k24:begin sdat<=0;scl<=1; state_k<=k25;end
k25:begin sdat<=1;state_k<=k26;end
k26:begin state_k<=k26;end //jump local

default: begin state_k<=k0; end
endcase
end end
回复

使用道具 举报

1

主题

3

帖子

9

积分

新手上路

Rank: 1

积分
9
沙发
 楼主| 发表于 2015-12-29 11:23 AM | 只看该作者
谢谢楼主                                                                                                                                                                       
回复 支持 反对

使用道具 举报

1

主题

3

帖子

9

积分

新手上路

Rank: 1

积分
9
板凳
 楼主| 发表于 2015-12-29 07:03 AM | 只看该作者
我是求教,是因为不会写程序!你怎么还。。。。服了                                                                                                                                                                       
回复 支持 反对

使用道具 举报

0

主题

2

帖子

6

积分

新手上路

Rank: 1

积分
6
地板
发表于 2015-12-29 09:16 AM | 只看该作者
da jiang you de                                                                                                                                                                       
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表