本帖最后由 独活草 于 2020-8-28 08:26 编辑
总所周知,IIC接口也是嵌入式系统中常用到的硬件通讯接口之一,PGL12G 板子的开发者比较有心,在板子上集成了2路支持IIC方式通讯的设备供大家学习。一路是EEPROM 24LC04 芯片,容量为4K (2*256*8bit),由2个256Byte的block组成;一路实时时钟RTC芯片 DS1338 ;
插入说说 IIC 总线:
IIC是一种多向控制总线,也就是说多个芯片可以连接到同一总线结构下,同时每个芯片都可以作为实时数据传输的控制源。
IIC串行总线一般有两根信号线,一根是双向的数据线SDA,另一根是时钟线SCL。所有接到IIC总线设备上的串行数据SDA都接到总线的SDA上,各设备的时钟线SCL接到总线的SCL上。
PGL12G 板子,是将FPGA芯片作为IIC 主站设备,将EEPROM、RTC 芯片作为了2个从站设备;
上面介绍完了原理,接着来扒代码:
笔者首先下载官方的EEPROM测试Verilog代码,实现了预期的效果,分析一下:
主站要与从站进行IIC通讯之前,是需要知道从站的编号的,翻看上面24LC04接口部分电路图,得出:
A2 A1 A0 = 0 0 1
查找24LC04芯片资料找到:
如图介绍所示,24XX 系列的从站地址由三部分组成:控制码+片选位+读写控制位;即1010 001 0 ;转换成16进制就是0xa2 这里先默认读写控制位为 0-写 。 再看看EEPROM-test代码里:
找到了配置从站地址的地方,果然配的参数也是0xa2;
为了弄清楚怎么处理“写”与“读”时从站地址的问题,继续翻看i2c_master_top.v 代码,找到:
原来在I2C_master底层代码里,默认一开始是传入“写”从站的地址,若是有了“写”的请求时,就把这个地址加0,然后作为从站地址;若是有了“读”的请求时,就把这个地址加1,然后作为从站地址;666
仔细翻看了下I2C_master的代码:看到了IIC总线的通讯波特率是100KHz
*************************************分割线*************************************
好了,接着说说时钟芯片的测试:
按照惯例,下载了官网的Verilog代码进入FPGA芯片,成功出现了预期效果:
测试例子里是一上电,就从2000-00-00 00:00:01 开始计数;然后串口输出时间; 同样翻看时钟芯片DS1338的资料,看到: 由此可以计算出它的从站地址为 1101 000 0,换成十六进制就是0xD0;
这个测试程序里,在uart_send.v里完成读取芯片内部寄存器的时间,并且已经限制了只能是“20XX”年,也就是“年”只有2个数据位,且目前没有写通过串口输入方式修改时间的代码: 大概研究了下官方底层脚本是有write函数的,可以修改时间参数,基本思路是在串口接收函数代码段里做解析,然后write.
|