基于fpga的ds1337读写控制

描述

01分析

前文对ds1337的功能做了详细讲解,FPGA控制不需要使用中断功能,并且默认晶体振荡器处于工作状态。所以在ds1337处于工作状态后,先对日历相关寄存器进行初始化,然后每隔一段时间读取日历寄存器的数据,通过ILA抓取初始化和读出的数据,查看ds1337芯片是否正常工作,最后把分秒的时间通过两个数码管显示。

ds1337芯片的原理图如下所示,通过I2C总线进行通信。

晶体振荡器

图1 ds1337原理图

4位数码管采用两片74hc595芯片进行驱动,该芯片的驱动数码管的原理可以在前面的一篇文章中查看。

晶体振荡器

图2 数码管原理图

顶层模块的框图如下所示,包含一个ds1337的读写控制模块ds1337_drive,I2C接口驱动模块iic_drive,另外两个模块用于驱动数码管显示分和秒的数据。

此处I2C采用连续地址读写方式,由于只需要对日历寄存器进行读写,所以只需要读写前七个寄存器的数据即可。上电后对连续的7个地址数据进行初始化,然后每隔500ms读取一次前面七个寄存器的数据。

由于前面设计I2C驱动模块时,对于多字节数据,会先发高位,所以秒寄存器的数据会在高字节,年寄存器的数据会在最低的字节中。后面数码管显示秒和分的数据,也是对读取的高两个字节的数据进行显示。

晶体振荡器

图3 顶层框图

其实上述框图中I2C的驱动模块,数码管的驱动模块在前文都已经提供且详细讲解了,本文只是调用这些通用模块,根据原理图稍作修改即可。这些模块的代码本文就不讲解了,需要了解的可查看前文,需要代码的可以在工程中进行查看。

ds1337读写控制模块也很简单,只需要上电后先对ds1337进行初始化,初始化具体数值采用参数化设置。然后在I2C驱动模块空闲500ms后读取日历寄存器的数据。对应代码如下所示:

02上板调试

由于此处并没有ds1337芯片的仿真模型,可以使用eeprom的I2C仿真模型替代。由于是多字节读写,前文eeprom的仿真模型对多字节数据的仿真也不支持,所以本文就不对工程进行仿真,直接使用ILA在线调试工具抓取I2C读写时序,来判断ds1337是否读写成功。

说到这里,其实对于ILA使用不熟练的同学,可以观察一下我对ILA的例化,顶层的ILA就可以抓取所有底层模块中的信号,并且不需要把底层模块信号从端口引出,就是利用”.”这个符号实现的。

由于ds1337的寄存器中的数据采用BCD码进行编码,则ILA抓取的数据使用十六进制进行显示,可以直接认为是对应的十进制数据。

顶层初始化设置的ds1337初始时间为2年3月15日星期天11时37分42秒,使用ILA抓取初始化波形如下所示:

晶体振荡器

图4 抓取初始化时序

将初始化的开始信号放大,结果如下图所示,需要初始化的数据为56’h42371100150302,表示2年3月15日星期天11时37分42秒,由于先写高位数据,所以秒在高字节,年在低字节数据。

晶体振荡器

图5 放大初始化数据

I2C初始化写时序如下图所示,黄色信号表示I2C双向数据信号,红色信号表示I2C的时钟信号,而天蓝色表示该模块的I2C数据输出,紫红色信号表示I2C的数据输出使能信号,低电平表示从机应答,高电平表示主机输出信号。

首先输出起始位之后,输出器件地址,然后再输出寄存器地址0,之后就写入7字节的数据,数据写完之后发送停止位,初始化写入完成。

晶体振荡器

图6 I2C写时序放大

ds1337初始化之后,就会按每秒计时运行,然后抓取读ds1337芯片日历寄存器的波形,结果如下所示。粉色信号就是抓取的I2C读取信号rdata,抓取的数据为56’h57371100150302,表示2年3月15日星期天11时37分57秒,由于经过了一段时间,所以读取的数据相对初始值已经过了几秒了。

晶体振荡器

图7 I2C读时序

就不对时序进行分析了,前文读写eeprom的时候已经对I2C时序进行了详细分析,在经过一段时间,抓取读取时序如下所示,读取的数据为56’h113811001503 02,表示2年3月15日星期天11时38分11秒。

晶体振荡器

图8 I2C读时序

最后数码管的显示如下所示,初始化的时为37分42秒,之后就一直运行。

本文工程就是对ds1337的功能做了验证,也是对I2C模块的连续读写能力再次进行测试,功能均正常。

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分