FPGA上实现IIC读写EEPROM
1、IIC协议简介
IIC(Inter-Integrated Circuit)其实是IICBus简称,所以中文应该叫集成电路总线,它是一种串行通信总线,使用多主从架构,由飞利浦公司在1980年代为了让主板、嵌入式系统或手机用以连接低速周边设备而发展。I²C的正确读法为“I平方C”(“I-squared-C”),而“I二C”(“I-two-C”)则是另一种错误但被广泛使用的读法。自2006年10月1日起,使用I²C协议已经不需要支付专利费,但制造商仍然需要付费以获取I²C从属设备地址。
IIC协议的起始和结束条件如下图所示:
2、IIC协议读过程
这里给出的是针对某个地址的单次读,IIC也有连续读的,就是顺着当前地址一直读下去,不过我个人觉得那种方式用的不多,还是针对某个地址读的方式用的多。
IIC协议写过程
IIC写过程,也是有连续写的,但是这里只给出针对某个地址写的,单次写数据,也是用的较多的。
FPGA实现IIC读写EEPROM
主要代码:
module iic_rw_test(
input clk,
input rst_n,
input iic_done,
input [7:0] data_read,
output reg exc_iic,
output reg iic_rw_ctl,
output [7:0] data_write,
output reg [7:0] addr,
output reg error
);
reg [2:0] cnt_fsm;
reg [2:0] cnt;
reg [9:0] wait_cnt;
always @(posedge clk or negedge rst_n) begin
if(!rst_n) begin
exc_iic <= 1'b0;
// iic_rw_ctl <= 1'b0;
// data_write <= 8'd0;
// addr <= 8'd0;
cnt_fsm <= 3'd0;
cnt <= 3'd0;
wait_cnt <= 10'd0;
end
else begin
if(iic_rw_ctl == 1'b0) begin
case(cnt_fsm)
3'd0:begin
if(cnt == 3'd3) begin
cnt_fsm <= cnt_fsm + 1'b1;
cnt <= 3'd0;
end
else begin
cnt <= cnt + 1'b1;
cnt_fsm <= cnt_fsm;
end
end
3'd1:begin
exc_iic <= 1'b1;
cnt_fsm <= cnt_fsm + 1'b1;
end
3'd2:begin
exc_iic <= 1'b0;
if(iic_done == 1'b1) begin
cnt_fsm <= cnt_fsm + 1'b1;
end
else begin
cnt_fsm <= cnt_fsm;
end
end
3'd3:begin
if(wait_cnt == 10'd500) begin
cnt_fsm <= 3'd0;
wait_cnt <= 10'd0;
end
else begin
cnt_fsm <= cnt_fsm;
wait_cnt <= wait_cnt + 1'b1;
end
end
default: ;
endcase
end
else begin
case(cnt_fsm)
3'd0:begin
if(cnt == 3'd3) begin
cnt_fsm <= cnt_fsm + 1'b1;
cnt <= 3'd0;
end
else begin
cnt <= cnt + 1'b1;
cnt_fsm <= cnt_fsm;
end
end
3'd1:begin
exc_iic <= 1'b1;
cnt_fsm <= cnt_fsm + 1'b1;
end
3'd2:begin
exc_iic <= 1'b0;
if(iic_done == 1'b1) begin
cnt_fsm <= cnt_fsm + 1'b1;
end
else begin
cnt_fsm <= cnt_fsm;
end
end
3'd3:begin
if(wait_cnt == 10'd500) begin
cnt_fsm <= 3'd0;
wait_cnt <= 10'd0;
end
else begin
cnt_fsm <= cnt_fsm;
wait_cnt <= wait_cnt + 1'b1;
end
end
default: ;
endcase
end
end
end
always @(posedge clk or negedge rst_n) begin
if(!rst_n) begin
iic_rw_ctl <= 1'b0;
error <= 1'b0;
addr <= 8'd0;
end
else begin
if(iic_done == 1'b1) begin
if(iic_rw_ctl == 1'b0) begin
if(addr <255) begin
addr <= addr + 1'b1;
end
else begin
addr <= 8'd0;
iic_rw_ctl <= 1'b1;
end
end
else begin
if(addr <255) begin
addr <= addr + 1'b1;
if(addr == data_read) begin
error <= 1'b0;
end
else begin
error <= 1'b1;
end
end
else begin
addr <= 8'd0;
end
end
end
else begin
addr <= addr;
iic_rw_ctl <= iic_rw_ctl;
end
end
end
assign data_write = addr;
endmodule
如果需要整个工程可以点击这里下载。
来源:CSDN
作者:来不及了,快上车
链接:https://blog.csdn.net/qq_36662353/article/details/103846151