admin 发表于 2018-12-28 15:41:27

【设计实例】I2C协议读写EEPROM存储器完整设计加仿真文件


如果您还没有注册本论坛,将无法下载论坛中附件,但是注册论坛非常简单,使用微   信 扫码即可注册。
也可以在小梅哥任意一个Q群内直接索取邀请码使用邀请码注册,小梅哥创建的任意一个群都可以。



在2014年参加培训的时候写过一次IIC协议的控制器,后来,又讲解了I2C协议的公开课,培训时候也讲解过该内容,但是一直没有亲自动手写过一个完整的I2C协议控制器,一直偷懒用的网友提供的现成的,进来兴致大发,写了一个简单的I2C控制器,使用状态机加线性序列机的思维实现了整个设计,还是比较清晰易懂的。
24LC64和24C04两种存储器的存储器地址段长度不同,24LC64是2个字节地址,24C04是一个字节地址,因此这里分别作了两个工程,来对应仿真测试,仿真脚本已经设置好,直接运行仿真就可以看到效果啦。




以下收录了几个网友在学习过程中的疑问和解答:

问:请问这个IIC协议中为什么有读写信号是直接跳到读写状态,不用到起始状态吗,不太懂,能解答一下吗


答:一次完整的写寄存器过程,包括起始状态,写器件地址,写存储器地址,写数据,仅在写器件地址之前需要产生起始位,后面的写存储器地址,写数据都不需要产生起始位。这个程序只是完成一个字节的数据传输,因此存在无需传输起始位的过程。
============================================================

问:文件夹里面的这个AC_IIC control文件和i2c bit_shift文件是不是一样的功能啊,有一个是用序列机写的是吗

答:第一个没用,忘了删了。即AC_IIC control用状态机思维写的,最后发现在细节上处理不是很方便,就舍弃了,新写了一个叫i2c bit_shift的文件,该文件使用的是状态机加序列机的方式写的。
============================================================

问:这个里面Go=1;Cmd=3,WR=1,Rd=4,STA=2,这个CMD&WR,CMD&RD,CMD&WR都不是0,也不是1,是一个数,这个要怎么执行啊,如果说if里面的条件不为0就是真,那这个三个条件都为真,执行哪一个啊,语法没学好,望指教。

答:if else 是有优先级的,这个优先级的判定和C语言里面的if else一样,所以当然是执行优先级高的。因为cmd是上层应用层传下来的指令,不会同时出现WR和RD都有效的情况的。
============================================================
问:小梅哥,我想问一下,在iic这个协议里,如果地址是两个字节长度的话你是用这个addr_mode等于0表示一个字节,等于1表示两个字节吗,但如果是一个字节为什么他这里写入的是addr而不是【7:0】呢,有点不懂这个地方,有人能解答一下吗。


答:嗯,这里是为了写程序方便这么定义的。最开始写的时候,如过存储器长度是2个字节,应用层,就直接把存储器地址给到addr端口上,如果是1个字节的,就给到addr的高8位上。但是这种思路不是很好接收,因为自己后面调试的时候也经常性的把地址直接给addr,而不管模式是0还是1,所以后面OV7670的程序(详见:http://www.corecourse.cn/forum.php?mod=viewthread&tid=27814)就改进了下,加了个根据mode的值在驱动层切换高低字节的操作。

下图中,根据mode的值,切换了addr的高低字节。


============================================================

问:请问这里为什么字节为1的时候cnt=1写完地址的时候要加STO啊,他应该接着写device_id,应该不需要停止位的写入吧。(注意,该问题问的是使用该控制器初始化OV7670的程序中的内容,详见:http://www.corecourse.cn/forum.php?mod=viewthread&tid=27814)

答:需要,EEPROM不需要,但是OV7670、OV5640等摄像头的协议中,和标准的IIC协议差别就在这里,这里是需要加停止位的。
============================================================

问:小梅哥,你写的这个iic协议是不是一次只能写或者读一个数据啊,不能连续读写多个数据是吗
答:是的,在FPGA中,一般用来初始化各种器件设备,如图像、视频、音频系统里面的各种器件,这些器件都支持单次读写模式,没有页读写模式,而这个控制器本身是用来初始化这些器件用的,就没有考虑多字节模式,这样程序简单,占用的资源也最少。
============================================================

问:我想请问一下开发板上的PCF8563内部是不是就包含了一个EEPROM存储器。(注意,该问题问的是使用该控制器读写RTC芯片PCF8563的程序中的内容,详见:
http://www.corecourse.cn/forum.php?mod=viewthread&tid=27816)
答:就是几个寄存器,不是eeprom
问:我看到的也是几个寄存器,所以我不太懂为什么在PCF8563仿真的时候这个testbench里要添加EEPROm的这个仿真芯片呢

还是说这里是把PCF这个芯片看成一个EEPROM呢,
答:看成一个eeprom 借eeprom的仿真模型来仿真的,因为8563没仿真模型


问:这个i2c_control应答标志位为什么还要和i2c_shift_bitl应答标志位或运算一下,这里有点不明白,为什么不能直接输出i2c_shift_bitl应答标志位。ack是i2c_control输出的,ack_o是调用i2c_shift_bit传过来的。

答:一次读写包含多次底层的i2c_bit shift过程,只有这么多次都有应答(ack为0),才能确定此次读写成功,所以将这每次i2c_bit shift过程的应答结果相或,只要其中有一次没有应答(ack_o为1),则会导致ack为1,从而证明此次读/写过程失败。

laidaihua 发表于 2019-1-2 17:29:47

Good...

wx_o5BM74Mj 发表于 2019-1-9 14:41:47

很棒,正好需要学习,希望小梅哥多做一些实例

wl_lov 发表于 2019-1-13 21:38:42

支持一下,多搞一些例程正好需要学习

xiaosong06 发表于 2019-1-23 10:27:52

正好学习学习,先加收藏,保存起来~~~

淮右布衣233 发表于 2019-10-31 17:20:47

梅哥牛逼,我好好研究一下代码。谢谢

liuyun2020 发表于 2020-3-6 11:54:55

小梅哥牛啤,我是之前看了您的关于i2c的教程视频,尝试着写但是很糟糕,看到大佬写的就是好:loveliness:

劉帥 发表于 2020-8-6 11:32:58

感谢小梅哥,这种学习方式我学得很快

满眼星_Ph1FH 发表于 2020-9-8 09:26:31

多谢小梅哥 。。。。。非常感谢。。。。。

煮猪猪 发表于 2021-7-11 11:35:07

小梅哥   我想问一下 从机接收到正确的数据之后是怎么给主机发送响应位的?三态门在接收到8位正确的数据之后就将sda_en信号拉低,此时sda信号不就为高阻态了吗?怎么能在下一个时刻检测到sda为0(也就是响应位为0)
页: [1] 2
查看完整版本: 【设计实例】I2C协议读写EEPROM存储器完整设计加仿真文件