I2C笔记.docx
- 文档编号:23519715
- 上传时间:2023-05-17
- 格式:DOCX
- 页数:12
- 大小:18.10KB
I2C笔记.docx
《I2C笔记.docx》由会员分享,可在线阅读,更多相关《I2C笔记.docx(12页珍藏版)》请在冰豆网上搜索。
I2C笔记
Modelsim仿真:
(1)CLK采集到ACK信号与SCL上升沿有时间的先后,故会产生不定态。
所以应当在SCL上升沿之后给SDA赋值高阻态。
(2)在下一个SCL上升沿到来的时候正好ACK由1变为0,这时也会产生不定态。
应当在SCL上升沿之前给SDA赋值。
(3)当SDA作为输出信号时,只是当SCL的上升沿才才输出
(4)写一个跟踪信号与ACK一样,当ACK为1给SDA赋值为高阻
(5)应该像写Quartus中的程序一样,写出测试程序
(6)assignSDA_rise=SDA_R1&&~SDA_R2;
assignSDA_fall=~SDA_R1&&SDA_R2;
///////////////////////////////为什么SDA的上升、下降沿用赋值语句来表达;而SCL的上升、下降沿要用时钟沿来触发?
?
always@(posedgeCLK)
if(SCL_R1&&~SCL_R2)
SCL_rise<=1;
else
SCL_rise<=0;
always@(posedgeCLK)
if(~SCL_R1&&SCL_R2)
SCL_fall<=1;
else
SCL_fall<=0;
(7)在赋值的时候也通过SCL上升沿来触发,可以用一个计数器来计算,达到输出数目时就用$finish语句来介绍操作。
(8)当第九个上升沿检测到ACK信号时,同时第九个下降如检测到ACK则产生ACK_OUT高,SDA则输出。
(9)IO口双向冲突,总线被强制拉成不定态。
(10)开始时用SCL_rise检测到ACK信号,再用ACK&&SCL_fall检测到ACK_OUT,当ACK_OUT为正时产生高阻态。
3'b001:
begin
case(state_write)
4'b0000:
beginctrl_reg[7]<=SDA;state_write<=4'b0001;end
4'b0001:
beginctrl_reg[6]<=SDA;state_write<=4'b0010;end
4'b0010:
beginctrl_reg[5]<=SDA;state_write<=4'b0011;end
4'b0011:
beginctrl_reg[4]<=SDA;state_write<=4'b0100;end
4'b0100:
beginctrl_reg[3]<=SDA;state_write<=4'b0101;end
4'b0101:
beginctrl_reg[2]<=SDA;state_write<=4'b0110;end
4'b0110:
beginctrl_reg[1]<=SDA;state_write<=4'b0111;end
4'b0111:
beginctrl_reg[0]<=SDA;state_write<=4'b1000;
ACK<=1;data_out<=0;end
4'b1000:
beginstate<=3'b010;ACK<=0;state_write<=4'b0000;end//这句表示在第九个SCL上升沿的时候,Slave端不进行操作。
在进行读操作的时候,Slave正好在第九个SCL下降沿把ACK传给Master,然后Slave在第九个SCL上升沿把RAM中的数据读取出来,在第十个SCL下降沿的时候传给Master。
3'b100:
begin
if(ctrl_reg==re7||ctrl_reg==re6||ctrl_reg==re5||ctrl_reg==re4||
ctrl_reg==re3||ctrl_reg==re2||ctrl_reg==re1||ctrl_reg==re0)
begin
case(count_re)
4'b0000:
beginaddress={ctrl_reg[3:
1],addr_reg[7:
0]};
data_re_buff=memory[address];ACK=1;
data_out=data_re_buff[7];count_re=4'b0001;end
4'b0001:
begindata_out=data_re_buff[6];count_re=4'b0010;end
4'b0010:
begindata_out=data_re_buff[5];count_re=4'b0011;end
4'b0011:
begindata_out=data_re_buff[4];count_re=4'b0100;end
4'b0100:
begindata_out=data_re_buff[3];count_re=4'b0101;end
4'b0101:
begindata_out=data_re_buff[2];count_re=4'b0110;end
4'b0110:
begindata_out=data_re_buff[1];count_re=4'b0111;end
4'b0111:
begindata_out=data_re_buff[0];count_re=4'b1000;end
4'b1000:
begindata_out=0;count_re=4'b0000;state=3'b011;end//state=3'b011continuetoreaduntilmasterresetorstop
default:
begincount_re=4'b0000;ACK=0;end
if(ctrl_reg==re7||ctrl_reg==re6||ctrl_reg==re5||ctrl_reg==re4||
ctrl_reg==re3||ctrl_reg==re2||ctrl_reg==re1||ctrl_reg==re0)
begin
case(count_re)
4'b0000:
beginaddress<={ctrl_reg[3:
1],addr_reg[7:
0]};
data_re_buff<=memory[address];ACK<=1;//dataofRAMdoesnotsendtodata_re_buff阻塞和非阻塞语句的差别
data_out<=data_re_buff[7];count_re=4'b0001;end
4'b0001:
begindata_out<=data_re_buff[6];count_re=4'b0010;end
4'b0010:
begindata_out<=data_re_buff[5];count_re=4'b0011;end
4'b0011:
begindata_out<=data_re_buff[4];count_re=4'b0100;end
4'b0100:
begindata_out<=data_re_buff[3];count_re=4'b0101;end
4'b0101:
begindata_out<=data_re_buff[2];count_re=4'b0110;end
4'b0110:
begindata_out<=data_re_buff[1];count_re=4'b0111;end
4'b0111:
begindata_out<=data_re_buff[0];count_re=4'b1000;end
4'b1000:
begindata_out=0;count_re=4'b0000;state=3'b011;end//state=3'b011continuetoreaduntilmasterreset
default:
begincount_re=4'b0000;ACK=0;end
endcase
/*wireSDA_R1,SDA_R2,SCL_R1,SCL_R2;
wireSDA_rise,SDA_fall,SCL_rise,SCL_fall;
always@(posedgeCLK)
if(INT)
begin
SDA_R1=1;SDA_R2=1;
SCL_R1=1;SCL_R2=1;
end
else
begin
case(state_check)
1'b0:
beginSDA_R1=SDA;SCL_R1=SCL;state_check=1;end
1'b1:
beginSDA_R2=SDA_R1;SCL_R2=SCL_R1;state_check=0;end
default:
state_check=0;
endcase
end
assignSDA_rise=SDA_R1&&~SDA_R2;
assignSDA_fall=~SDA_R1&&SDA_R2;
//////////////////////////////////////////
STARTandSTOP
//////////////////////////////////////////
always@(posedgeCLK)//attenationgivevaluewhenwritetestmodule
if(INT)
begin
start<=0;
stop<=0;
end
else
begin
start<=SDA_fall&&SCL_R1;
stop<=SDA_rise&&SCL_R1;
end
//////////////////////////////////////////
CheckSCLtoachievecyclepluse
fallandrisestageoftheSCL
//////////////////////////////////////////
always@(posedgeCLK)
if(SCL_R1&&~SCL_R2)
SCL_rise<=1;
else
SCL_rise<=0;
always@(posedgeCLK)
if(~SCL_R1&&SCL_R2)
SCL_fall<=1;
else
SCL_fall<=0;
always@(posedgeCLK)
if(start)
///////////////////////////////////////////////////////////////////////以下为test_top程序
`include"./I2C_last_slave.v"
`timescale1ns/1ns
moduleI2C_test_TOP;
regCLK,SCL,INT;
integercount,state_check;
wireSDA;
regACK;
regSDA_IN;//thesameastheSDA
assignSDA=(ACK==1)?
SDA_IN:
1'bz;
initial
begin
ACK=1;
SCL=1;
SDA_IN=1;
INT=1;
CLK=0;
count=0;
#50INT=0;
#100SDA_IN=0;
#500SDA_IN=1;
#1000SDA_IN=0;
#1000SDA_IN=1;
#1000SDA_IN=0;
#1000SDA_IN=1;
#1000SDA_IN=1;
#1000SDA_IN=1;
#1000SDA_IN=0;
#1400ACK=0;
repeat(1200)
begin
case(count)
4'b0000:
#900beginACK=1;SDA_IN=1;count=4'b0001;end
4'b0001:
#1000beginACK=1;SDA_IN=1;count=4'b0010;end
4'b0010:
#1000beginACK=1;SDA_IN=1;count=4'b0011;end
4'b0011:
#1000beginACK=1;SDA_IN=1;count=4'b0100;end
4'b0100:
#1000beginACK=1;SDA_IN=1;count=4'b0101;end
4'b0101:
#1000beginACK=1;SDA_IN=1;count=4'b0110;end
4'b0110:
#1000beginACK=1;SDA_IN=1;count=4'b0111;end
4'b0111:
#1000beginACK=1;SDA_IN=1;count=4'b1000;end
4'b1000:
#1200beginACK=0;count=4'b0000;end
endcase
end
//`definestim#500SDA=1'b;;//comparetoPage2of135examples
#800ACK=1;SDA_IN=1;
#1000SDA_IN=0;
#1000SDA_IN=1;
#1000SDA_IN=0;
#1000SDA_IN=1;
#1000SDA_IN=1;
#1000SDA_IN=1;
#1000SDA_IN=1;
#1200ACK=0;
repeat(9)
begin
#1000ACK=0;
end
#1200ACK=1;SDA_IN=1;//Thereare8bitssendoutdata
#10$finish;
end
always#10CLK=~CLK;
always#500SCL=~SCL;
I2C_last_slavem1(.SDA(SDA),.SCL(SCL),.INT(INT),.CLK(CLK));
endmodule
`include"./I2C_last_slave.v"
`timescale1ns/1ns
moduleI2C_test_TOP;
regCLK,SCL,reset;
integercount,state_check;
reg[10:
0]count_data;
wireSDA,INT;
regACK;
regSDA_IN;//thesameastheSDA
regSCL_rise,SCL_fall;
assignSDA=(ACK==1)?
SDA_IN:
1'bz;
initial
begin
ACK=1;
SCL=1;
SDA_IN=1;
reset=1;
CLK=0;
count=0;
#50reset=0;
#100SDA_IN=0;
#500SDA_IN=1;
#1000SDA_IN=0;
#1000SDA_IN=1;
#1000SDA_IN=0;
#1000SDA_IN=1;
#1000SDA_IN=1;
#1000SDA_IN=1;
#1000SDA_IN=0;
#1880ACK=0;
count_data=0;
repeat(1200)
begin
case(state)
4'b0000:
if(SCL_fall)begin#100SDA_IN=1;state=4'b0001;end
4'b0001:
if(SCL_fall)begin#100SDA_IN=0;state=4'b0010;end
4'b0010:
if(SCL_fall)begin#100SDA_IN=1;state=4'b0011;end
4'b0011:
if(SCL_fall)begin#100SDA_IN=0;state=4'b0100;end
4'b0100:
if(SCL_fall)begin#100SDA_IN=1;state=4'b0101;end
4'b0101:
if(SCL_fall)begin#100SDA_IN=0;state=4'b0110;end
4'b0110:
if(SCL_fall)begin#100SDA_IN=1;state=4'b0111;end
4'b0111:
if(SCL_fall)begin#100SDA_IN=0;state=4'b1000;end
4'b1000:
if(SCL_fall)begin#100SDA_IN=1;state=4'b0000;end
default:
beginSDA_IN=0;state=4'b0000;end
end
//`definestim#500SDA=1'b;;//comparetoPage2of135examples
#20ACK=1;SDA_IN=1;
#1000SDA_IN=0;
#1000SDA_IN=1;
#1000SDA_IN=0;
#1000SDA_IN=1;
#1000SDA_IN=1;
#1000SDA_IN=1;
#1000SDA_IN=1;
#1880ACK=0;
repeat(9)
begin
#1000ACK=0;
end
#1200ACK=1;SDA_IN=1;//Thereare8bitssendoutdata
#10$finish;
end
always#10CLK=~CLK;
always#500SCL=~SCL;
always@(posedgeCLK)
if(reset)
begin
SDA_R1=1;SDA_R2=1;
SCL_R1=1;SCL_R2=1;
end
else
begin
case(state_check)
1'b0:
beginSDA_R1=SDA;SCL_R1=SCL;state_check=1;end
1'b1:
beginSDA_R2=SDA_R1;SCL_R2=SCL_R1;state_check=0;end
default:
state_check=0;
endcase
end
assignSDA_rise=SDA_R1&&~SDA_R2;
assignSDA_fall=~SDA_R1&&SDA_R2;
always@(posedgeCLK)
if(SCL_R1&&~SCL_R2)
SCL_rise<=1;
else
SCL_rise<=0;
always@(posedgeCLK)
if(~SCL_R1&&SCL_R2)
SCL_fall<=1;
else
SCL_fall<=0;
always@(posedgeCLK)//attenationgivevaluewhenwritetestmodule
if(reset)
begin
start<=0;
stop<=0;
end
else
begin
start<=SDA_fall&&SCL_R1;
stop<=SDA_rise&&SCL_R1;
end
I2C_last_slavem1(.SDA(SDA),.SCL(SCL),.INT(INT),.CLK(CLK),.reset(reset));
Endmodule
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- I2C 笔记