I2C 协议抓包,学习,总结

I2C 调查

标准I2C协议介绍

I2C总线是由Philips公司开发的一种简单、双向二线制同步串行总线。它只需要两根线即可在连接于总线上的设备之间通信。I2C的两根线SDA(串行数据线)和SCL(串行时钟线)都是双向I/O线,接口电路为开漏输出,需通过上拉电阻接电源VCC,当总线空闲时,两根线都是高电平。

常见的硬件结构图(一个适配器,两根线,若干设备而已)

image-20211022174809213

I2C时序介绍

起始信号

启动信号描述: SCL为高电平时,SDA由高电平变成了低电平

image-20211012184634814

停止信号

停止信号描述:SCL为高电平时,SDA由低电平变成高电平

image-20211012184811769

重启信号

在I2C总线启动了起始信号,并且未启动停止信号过程中,再次发送起始信号,那么这个信号也被称为重启信号

总线闲信号

当SDA和SCL都为高,此时主控制器和从设备都未对这两根线进行操作,仅由I2C的上拉电阻将这两根线拉高

总线忙信号

当主控制器发起了START信号时,到发起STOP信号期间,I2C总线都处于忙状态

读写信号

image-20211013095331787

应答信号

一般情况下,主控制器或者从设备,谁读取到对方的发过来的数据,谁就需要发送应答信号,比如主控制器将数据发送给从设备,从设备接收到后,将在总线上回复应答信号

image-20211022173727178

非应答信号

非应答信号出现有两种情况,一种是异常情况,比如主控制器发送的数据,从设备未回复应答信号,即认为回复的是非应答信号,那么说明在传输数据过程中出现了异常,比如设备地址未设置正常,又比如,在某些需要主设备额外给设备提供时钟的情况下,并没有提供时钟,即从设备未能正常工作,都会认为从设备回复的是NCK。

还有一种是正常情况,即当主控制器接收到了从设备发送的数据后,主控制器主动发送NCK,来告诉从设备,已经成功读取到了数据,不再继续读取数据了。

image-20211022173840998

image-20211013102032739

image-20211013102209139

标准I2C协议读写介绍

I2C写一个寄存器
  • 整体流程如下

image-20211013103108349

  • 抓包分析如下

    从设备地址为0x34,寄存器地址为0x01,写入的值为0x04

image-20211021175906675

image-20211021180004368

I2C 读一个寄存器

读从设备地址为0x34,寄存器地址为0x01的值

image-20211021180035070

  1. 发送START信号
  2. 发送设备地址+写命令(0x34+Write), 等待设备回复ACK
  3. 写入即将要读的设备的寄存器地址(0x01),等待设备回复ACK
  4. 发送STOP信号
  5. 发送START信号(步骤4, 5其实可以合并为一个操作,即重启信号)
  6. 发送设备地址+读命令(0x34+Rread),等待设备回复ACK
  7. 读取设备回复的寄存器的值(0x04),主控制器发送NCK(高电平),告知设备结束接受数据,再发送STOP信号,停止当次传输
I2C 连续写多个寄存器

标准的I2C支持连续写多个I2C寄存器,需要I2C控制器和I2C从设备都需要支持该标准时,才真正有这个特性。

通过I2C,连续写入n个数据,从设备的某一个基地址(连续,依次写入,硬件一般会自动递增寄存器地址)

image-20211022175059893

I2C 连续读多个寄存器

标准的I2C支持连读读错了I2C寄存器,需要I2C控制器和I2C从设备支持该标准时,才真正有这个特性。

通过I2C,连续读n个数据,从设备的某一个基地址(连续,依次读出,硬件一般会自动递增寄存器地址)

image-20211022175728547

I2C数据仲裁介绍

一般只有在I2C总线系统中同时存在2个I2C住设备时,才会出现总线仲裁失败的问题。

image-20211013140054532

参考链接: I2C总线的仲裁机制

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
最近一个项目需要做I2C的slave,在opencores.org上面找到了一个I2C的代码,不过是master的。 下载来看看,发现里面有一个I2C slave的行为级代码。 于是自己根据这个代码改写了一个I2C slave RTL的代码,并修改了原来那个设计的testbench,将rtl的Slave替换了原来的behavior的Slave,在modelsim里面作了前仿,完全通过。还有一个myram.v文件,是一个register file,和slave相连,存储数据用的。 用synplify做综合,使用x3s400-4的器件,占用LUT<100,速度接近200MHz。性能比较优化。 代码做了详尽的注释,语言采用verilog,并且写了仿真的脚本。解压了直接运行simbehav.bat就可以了。如果modelsim安装的时候注册了环境变量(path),脚本调用modelsim,输入run -all即可看到仿真结果。 虽然不是很复杂,不过对于广大需要做I2C的RTL slave的工程师来说,还是很有参考价值的。 1、 设计流程 将I2C slave的行为模型改为rtl模型。 进行等效仿真,直到波形一致,通过timing check,数据正确。 再进行rtl优化设计 2、 注意要点 a) 时钟的设计 b) 对于restart condition的时序是否正确 c) 3、 进度 a) 11-12:initial状态的bitcnt不对,需要认真比对/设计 b) 11-13:initial基本解决(sda_in的问题)。Sda三态冲突,原因不明。比对原设计 c) 11-14:sda三态冲突解决,原因为sda在初始化时没有将sda_oen赋值(由sm赋值,但是sm没有做async reset)。同时注意verilog的大小写敏感。 d) 11-15:仿真出现错误:read出来的数据非期望值。写入逻辑完全正确。Read时由于sda_oe在sm中有一个cycle_pulse的延迟,导致了mem_do[7]串行移出时错位。在更改了sm的代码风格后再研究解决方法。 e) 11-16:仿真完全匹配波形。计划:优化结构,提高稳定性sm改为每个时钟打一下。 关于I2C的SDA三态转换: Master在发送完第8个bit后随后将sda释放(posedge后大概1/4 scl周期),此时slave需要在第九个bit对应的scl的posedge拉低sda。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值