FPGA上实现IIC读写EEPROM

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 

如果需要整个工程可以点击这里下载。

  • 1
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Cyclone10 FPGA读写eeprom(24lc04)实验Verilog源码Quartus17.1工程文件+文档资料, FPGA为CYCLONE10LP系列中的10CL025YU256C8. 完整的Quartus工程文件,可以做为你的学习设计参考。 module i2c_master_top ( input rst, input clk, input[15:0] clk_div_cnt, // I2C signals // i2c clock line input scl_pad_i, // SCL-line input output scl_pad_o, // SCL-line output(always 1'b0) output scl_padoen_o, // SCL-line output enable(active low) // i2c data line input sda_pad_i, // SDA-line input output sda_pad_o, // SDA-line output (always 1'b0) output sda_padoen_o, // SDA-line output enable (active low) input i2c_addr_2byte, input i2c_read_req, output i2c_read_req_ack, input i2c_write_req, output i2c_write_req_ack, input[7:0] i2c_slave_dev_addr, //device address input[15:0]i2c_slave_reg_addr, //word address input[7:0] i2c_write_data, output reg[7:0]i2c_read_data, output reg error ); localparam S_IDLE = 0; localparam S_WR_DEV_ADDR = 1; localparam S_WR_REG_ADDR = 2; localparam S_WR_DATA = 3; localparam S_WR_ACK = 4; localparam S_WR_ERR_NACK = 5; localparam S_RD_DEV_ADDR0 = 6; localparam S_RD_REG_ADDR = 7; localparam S_RD_DEV_ADDR1 = 8; localparam S_RD_DATA = 9; localparam S_RD_STOP = 10; localparam S_WR_STOP = 11; localparam S_WAIT = 12; localparam S_WR_REG_ADDR1 = 13; localparam S_RD_REG_ADDR1 = 14; localparam S_RD_ACK = 15; reg start; reg stop; reg read; reg write; reg ack_in; reg[7:0] txr; wire[7:0] rxr; wire i2c_busy; //It was high level after start signal and low level after stop signal wire i2c_al; //arbitrament lose(The stop signal is detected but no signal is requested.The host setting SDA is high,Actual SDA is low) wire done; wire irxack; //slave receive the respond,0 (receive),1(refuse) reg[3:0] state,next_state; assign i2c_read
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值