i2cverilog代码
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
4'd5: sda_r <= db_r[2]; 4'd6: sda_r <= db_r[1]; 4'd7: sda_r <= db_r[0]; default:
endcase
//
sda_r <= db_r[4'd7-num]; //
送
EEPROM
地址
(高
bit
开始)
cstate <= ADD2;
end
end
//
else if(`SCL_POS) db_r <= {db_r[6:0],1'b0}; //
器件地址左移
1bit
else
cstate <= ADD2;
end
ACK2:
begin
if(/*!sda*/`SCL_NEG) begin
//
从机响应信号
if(!sw1_r) begin
cstate <= DATA;
//
写操作
db_r <= `WRITE_DATA; //
写入的数据
end
else if(!sw2_r) begin
db_r <= `DEVICE_READ; //
送器件地址(读操作)
地址读需要执行该步骤以下操作
cstate <= START2;
//
读操作
end
end
else cstate <= ACK2;
//
等待从机响应
START2: begin //
读操作起始位
if(`SCL_LOW) begin
sda_link <= 1'b1; //sda
作为
output
sda_r <= 1'b1;
//
拉高数据线
sda
cstate <= START2;
end
else if(`SCL_HIG) begin //scl
为高电平中间
sda_r <= 1'b0;
//
拉低数据线
sda
,产生起始位信号cstate <= ADD3;
end
else cstate <= START2; end
ADD3:
begin
//
送读操作地址
if(`SCL_LOW) begin
if(num==4'd8) begin
num <= 4'd0;
//num
计数清零
sda_r <= 1'b1;
sda_link <= 1'b0;
//sda
置为高阻态(input)
cstate <= ACK3; end
else begin
num <= num+1'b1; case (num)
4'd0: sda_r <= db_r[7];
4'd1: sda_r <= db_r[6]; 4'd2: sda_r <= db_r[5]; 4'd3: sda_r <= db_r[4]; 4'd4: sda_r <= db_r[3];
4'd5: sda_r <= db_r[2]; 4'd6: sda_r <= db_r[1]; 4'd7: sda_r <= db_r[0]; default:
endcase
//
sda_r <= db_r[4'd7-num]; //
送
EEPROM
地址
(高
bit
开始)
cstate <= ADD3;
end
end
//
else if(`SCL_POS) db_r <= {db_r[6:0],1'b0}; //
器件地址左移
1bit
else cstate <= ADD3;
end
ACK3:
begin
if(/*!sda*/`SCL_NEG) begin
cstate <= DATA;
//
从机响应信号
sda_link <= 1'b0;
end
else cstate <= ACK3;
//
等待从机响应
end
DATA:
begin
if(!sw2_r) begin
//
读操作
if(num<=4'd7) begin cstate <= DATA;
if(`SCL_HIG) begin
num <= num+1'b1; case (num)
4'd0: read_data[7] <= sda;
4'd1: read_data[6] <= sda; 4'd2: read_data[5] <= sda; 4'd3: read_data[4] <= sda; 4'd4: read_data[3] <= sda;
4'd5: read_data[2] <= sda; 4'd6: read_data[1] <= sda; 4'd7: read_data[0] <= sda;
default:
endcase
//
read_data[4'd7-num] <= sda; // 读数据
(高
开始)
end
//
else
if(`SCL_NEG)
read_data
<=
{read_data[6:0],read_data[7]}; //
数据循环右移
end
else if((`SCL_LOW) && (num==4'd8)) begin
num <= 4'd0;
//num
计数清零
cstate <= ACK4;
end
else cstate <= DATA;
end
else if(!sw1_r) begin //
写操作
sda_link <= 1'b1;
if(num<=4'd7) begin cstate <= DATA;
if(`SCL_LOW) begin
sda_link <= 1'b1;
//
数据线
sda
作为
output
num <= num+1'b1; case (num)
4'd0: sda_r <= db_r[7]; 4'd1: sda_r <= db_r[6]; 4'd2: sda_r <= db_r[5]; 4'd3: sda_r <= db_r[4];
4'd4: sda_r <= db_r[3]; 4'd5: sda_r <= db_r[2]; 4'd6: sda_r <= db_r[1]; 4'd7: sda_r <= db_r[0];
default:
endcase
//
sda_r <= db_r[4'd7-num]; //
写入数据(高
bit
开
始)
end
//
else if(`SCL_POS) db_r <= {db_r[6:0],1'b0}; //
写
入
数
据
左移
1bit
end
else if((`SCL_LOW) && (num==4'd8)) begin
num <= 4'd0;
sda_r <= 1'b1;
sda_link <= 1'b0;
//sda
置为高阻态cstate <= ACK4;
end
else cstate <= DATA;
end
end
ACK4: begin
if(/*!sda*/`SCL_NEG) begin //
sda_r <= 1'b1; cstate <= STOP1; end
else cstate <= ACK4; end
STOP1:
begin
if(`SCL_LOW) begin
sda_link <= 1'b1;
sda_r <= 1'b0;
cstate <= STOP1;
end
else if(`SCL_HIG) begin sda_r <= 1'b1; //scl
为高时,
sda
产生上升沿(结束信号)cstate <= STOP2;
end
else cstate <= STOP1;
end
STOP2:
begin
if(`SCL_LOW) sda_r <= 1'b1;
else if(cnt_20ms==20'hffff0) cstate <= IDLE;
else cstate <= STOP2;
end
default: cstate <= IDLE;
endcase
end
assign sda = sda_link ? sda_r:1'bz;
assign dis_data = read_data;
//---------------------------------------------
endmodule
写寄存器的标准流程为:
1. Master发起START
2. Master发送I2C addr(7bit)和w操作0(1bit),等待ACK
3. Slave发送ACK
4. Master发送reg addr(8bit),等待ACK
5. Slave发送ACK
6. Master发送data(8bit),即要写入寄存器中的数据,等待ACK
7. Slave发送ACK
8. 第6步和第7步可以重复多次,即顺序写多个寄存器
9. Master发起STOP
读寄存器的标准流程为:
1. Master发送I2C addr(7bit)和w操作1(1bit),等待ACK
2. Slave发送ACK
3. Master发送reg addr(8bit),等待ACK
4. Slave发送ACK
5. Master发起START
6. Master发送I2C addr(7bit)和r操作1(1bit),等待ACK
7. Slave发送ACK
8. Slave发送data(8bit),即寄存器里的值
9. Master发送ACK
10. 第8步和第9步可以重复多次,即顺序读多个寄存器
原理整理清楚编程思路就有了,首先要有开始工作的信号,分读和写来驱动I2C,本设计用M2408这款芯片进行工作,主要是了解到datasheet中时序的要求来进行编写。
编写过程中遇到的问题是scl没有满足时序要求,还有工作状态容易漏掉,比如说地址的发送以及等待ACK 最后通过仿真及下载进行验证得到最终的结果,下图是modelsim的仿真图:。