当前位置:网站首页>【FPGA】设计思路——I2C协议
【FPGA】设计思路——I2C协议
2022-08-11 03:28:00 【春风浅作序】
一、模块框图
二、状态转移图
三、端口列表
1、控制模块:
input clk ,
input rst_n ,
input rd_en ,//读请求,按键控制
input [7:0] din ,//接收串口的数据
input din_vld ,//串口数据完成标志
input [7:0] rd_data ,//接收接口端的数据
input done ,//rd_data数据完成标志
input ready ,//串口端空闲标志
output reg [7:0] dout ,//将数据读出到串口
output reg dout_vld,//串口数据完成标志
output reg [3:0] cmd ,//向接口端发送数据
output reg req ,//向接口端发送请求
output reg [7:0] wr_data ,//向接口端发送数据
2、接口模块
input clk ,
input rst_n ,
//控制模块
input req ,//接收请求
input [3:0] cmd ,//接收命令
input [7:0] wr_data ,//接收控制模块传入的数据
output done ,//一个字节传输完成标志
output reg [7:0] rd_data ,//将读取的数据传入控制模块
//output reg slave_ack ,//写入数据后EEPROM应答信号
//eeprom
input i2c_sda_i ,//EEPROM传到接口模块的串行数据
output reg i2c_scl ,//I2C时钟
output reg i2c_sda_oe ,//输出使能信号
output reg i2c_sda_o //接口模块传到EEPROM的串行数据
四、设计思路
1、控制模块
(1)状态机设计
assign idle2rd_req = state_c == IDLE && rd_en;
assign idle2wr_req = state_c == IDLE && (wfifo_usedw > WR_LEN - 2);
assign rd_req2rd_wait = state_c == RD_REQ && (1'b1);
assign rd_wait2rd_req = state_c == RD_WAIT && (done & cnt_byte < RD_LEN - 1);
assign rd_wait2done = state_c == RD_WAIT && end_cnt_byte;
assign wr_req2wr_wait = state_c == WR_REQ && (1'b1);
assign wr_wait2wr_req = state_c == WR_WAIT && (done & cnt_byte < WR_LEN - 1);
assign wr_wait2done = state_c == WR_WAIT && end_cnt_byte;
assign done2idle = state_c == DONE && (1'b1);
(2)字节计数器设计
assign add_cnt_byte = (state_c == RD_WAIT | state_c == WR_WAIT) & done ;
assign end_cnt_byte = add_cnt_byte && cnt_byte == ((state_c == WR_WAIT)?(WR_LEN-1):(RD_LEN-1)) ;
(3)设计一个task,用于发送请求,命令,数据
读状态时:
第0字节发送(请求,{开始命令,写命令},{I2C器件地址,写请求});
第1字节发送(请求,写命令,寄存器地址};
最后一个字节发送(请求,{写命令,停止命令},wfifo中的输出数据);
写状态时:
第0字节发送(请求,{开始命令,写命令},{I2C器件地址,写请求});
第1字节发送(请求,写命令,寄存器地址};
第2字节发送(请求,{开始命令,写命令},{I2C器件地址,读请求}};
最后一个字节发送(请求,{读命令,停止命令},0);
(4)寄存器地址设计
读地址:
初始为0,每当一次完整的读操作完成(即rd_wait2done),地址自增读入的数据个(即rd_addr <= rd_addr + RD_LEN - 3)
写地址:
初始为0,每当一次完整的写操作完成(即wr_wait2done),地址自增写入的数据个(即wr_addr <= wr_addr + WR_LEN - 2)
(5)输出到串口端数据设计
即dout 与 dout_vld
dout等于rfifo的输出数据
dout_vld等于rfifo的读请求
(6)FIFO设计
数据宽度为8,深度为默认256
wfifo:
数据输入为串口端输入的数据
读请求:写状态且开始有数据
wfifo_rdreq = state_c == WR_WAIT & done & cnt_byte > 1;
写请求:非满且输入有效
wfifo_wrreq = ~wfifo_full && din_vld;
rfifo:
数据输入为接口端输入的数据
读请求:非空且串口端空闲
rfifo_rdreq = ready && ~rfifo_empty;
写请求:读状态且开始有数据
rfifo_wrreq = ~rfifo_full && state_c == RD_WAIT && done && cnt_byte >2;
2、接口模块
(1)状态机设计
assign idle2start = state_c == IDLE && (req && (cmd & `CMD_START));
assign idle2write = state_c == IDLE && (req && (cmd & `CMD_WRITE));
assign idle2read = state_c == IDLE && (req && (cmd & `CMD_READ));
assign start2write= state_c == START && (end_cnt_bit && (command & `CMD_WRITE));
assign start2read = state_c == START && (end_cnt_bit && (command & `CMD_READ));
assign write2rack = state_c == WRITE && end_cnt_bit;
assign rack2stop = state_c == RACK && (end_cnt_bit && (command & `CMD_STOP));
assign rack2idle = state_c == RACK && (end_cnt_bit && (command & `CMD_STOP) == 0);
assign read2sack = state_c == READ && end_cnt_bit;
assign sack2stop = state_c == SACK && (end_cnt_bit && (command & `CMD_STOP));
assign sack2idle = state_c == SACK && (end_cnt_bit && (command & `CMD_STOP) == 0);
assign stop2idle = state_c == STOP && end_cnt_bit;
(2)计数器设计
I2C时钟
非IDLE状态开启,
每记完250个系统时钟周期结束一次。
bit时钟
每当I2C时钟结束时开启一次,
结束状态为:读/写状态记完8bit,其余状态记完1bit。
(3)I2C时钟设计
初始为1,跳出IDLE状态后拉低,记到I2C时钟一半(125)时拉高,记完一个I2C时钟后拉低。
(4)I2C输出设计
初始为1
起始状态,I2C时钟低电平中间时将信号拉高,确保能检测到起始信号,I2C时钟高电平中间时将信号拉低
写状态且I2C时钟低电平中间时,将控制模块传入的数据进行并串转换输出
发送应答信号且I2C时钟低电平中间时,如果有停止命令,则发高电平,否则发低电平。
结束状态,I2C时钟低电平中间时将信号拉低,确保能检测到停止信号,I2C时钟高电平中间时将信号拉高。
(5)I2C输出使能设计
开始状态、结束状态、写状态、发送应答状态为高电平,其余为低电平。
(6)接收EEPROM数据设计
读状态且I2C时钟高电平中间时,串并转换
(7)接收EEPROM应答设计
接收应答且I2C时钟高电平中间时,应答信号等于输入信号。
边栏推荐
- Redis老了吗?Redis与Dragonfly性能比较
- 用户如何克服程序化交易中的情绪问题?
- EasyCVR接入海康大华设备选择其它集群服务器时,通道ServerID错误该如何解决?
- 成都纸质发票再见!开住宿费电子发票即将全面取代酒店餐饮加油站发票
- The problem that Merge will be lost again after code Revert has been solved
- 字体反扒
- MYSQLg高级------回表
- "Life Is Like First Seen" is ill-fated, full of characters, and the contrast of Zhu Yawen's characters is too surprising
- Design and Realization of Employment Management System in Colleges and Universities
- JS-DOM element object
猜你喜欢
The development of the massage chair control panel makes the massage chair simple and intelligent
Summary of debugging skills
A simple JVM tuning, learn to write it on your resume
JS-DOM element object
多商户商城系统功能拆解26讲-平台端分销设置
二叉树相关代码题【较全】C语言
Is Redis old?Performance comparison between Redis and Dragonfly
常用认证机制
CSDN 博客更换皮肤
MongoDB 基础了解(二)
随机推荐
Goodbye Guangzhou paper invoices!The issuance of electronic invoices for accommodation fees will completely replace the invoices of hotels, restaurants and gas stations
What is third-party payment?
MYSQLg高级------回表
A practice arrangement about map GIS (below) GIS practice of Redis
Is Redis old?Performance comparison between Redis and Dragonfly
Detailed explanation of VIT source code
高校就业管理系统设计与实现
AI + medical: for medical image recognition using neural network analysis
80端口和443端口是什么?有什么区别?
I didn't expect MySQL to ask these...
FTP错误代码列表
二叉树相关代码题【较全】C语言
The "top pillar" slides, and new growth is extremely difficult to shoulder the heavy responsibility. Is Ali "squatting" to jump higher?
程序化交易与主观交易对盈利曲线的影响!
font
C语言 recv()函数、recvfrom()函数、recvmsg()函数
[BX] and loop
STC8H开发(十五): GPIO驱动Ci24R1无线模块
云平台下ESB产品开发步骤说明
正式发布丨VS Code 1.70