HDMI数据的接收发送实验(八)
一、 概述上一章节创建hex文件写入EDID编码接下来我们需要把ROM中的数据通过IIC协议传输到HDMI中为了能够更方便观察具体时序我们首先模拟主机发送的IIC请求这样可以根据仿真来观察IIC的传输过程。二、模拟主机发送IIC时序接口列表我们可以根据AT24CM01的顺序读取时序来确定它的传输方式根据图1可以看出它的传输过程再写出它的状态图根据图2和图3所示的时间规范设计出合适的传输时序。图1为顺序读取的时序顺序读取可以由随机地址读取发起。当微控制器接收到一个数据字节后它用一个确认来响应。只要EEPROM接收到确认微控制器就会继续递增寄存器地址并自动读取寄存器当中的数据。当微控制器没有响应0并且产生后续STOP停止条件后顺序读取结束。所以在顺序读取时读第一个数据后只要接收到ACK响应就会继续读取下一个寄存器地址的数据直到发送非应答信号和停止信号停止读取。注1: IIC总线协议中文版 page 28注2 IIC总线协议中文版 page 27下面根据IIC的传输协议画出状态图及主机发送的IIC时序图SCL的高电平时间和低电平时间分别要大于4.0us和4.7us我们的系统时钟频率为50MHz它的周期为20ns由此可以设计一个时钟分频计数器sclk_cnt在状态机不为空闲状态时开始计数。每计数到511时清零使SCL在sclk_cnt计数到255拉高计数到511时拉低。分频后的SCL的周期为10.24us并且它的时钟频率小于100KMhz可以满足需求。首先要完成开始条件的时序当检测到HMDL_RX_PHA的上升沿并且HMDL_RX_TXEN为1时IIC开始工作SCL和SDA这两条线上电之后为高在产生开始标志时这里需要满足起始条件的保持时间至少4.0us也就是数据线由高变低后SCL为高的保持时间这里再增加一个计数器scl_start_time_cnt计数到511时SDA拉低计数到1023并且sclk_cnt为511时SCL拉低。这样就满足了起始条件的时序要求。SDA作为双向接口为了可以控制它的输出所以用了两个信号来作为它的输入数据和输出数据。Sda_in为SDA的缓冲可以直接使用。Sda_out为SDA的输出。Sda_oe为控制sda_out输出的使能当sda_oe为1时sda_out数据有效sda_oe为0时sda_out数据无效表现为高阻状态。buf sda_i(sda_in,sda);assign sda (sda_oe1) ? sda_out : 1’bz;在发送器件地址时为了能在SCL的低电平的中心位置发出数据我们设计了两个信号scl_l_flag和scl_h_flag分别为SCL的低电平中心和高电平中心器件地址在7位数据中的高4位有效第8位的读写位如果为写则为A0。slave_addr_wr_shift为移位寄存器它的初始值为A0使它在SLAVE_ADDR_WR状态中icc_scl_cnt7 并且 scl_l_flag1时把0移入最低位。在每个SCL的低电平中心位置把slave_addr_wr_shift的最高位赋值给sda_out。在移出8位数据后从机会返回ACK应答当SCL为高时sda_in为低则代表接收到了响应。iic_scl_cnt计数到9时为接收ACK应答的时间段当计数到9时接收到ack应答并且到下一个scl的低电平中心位置时状态跳转到WR_ADDR。iic_scl_cnt为sda线上传输单bit数据的计数每发送或接收到一个数据计数1在SLAVE_ADDR_ER和SLAVE_ADDR_RD状态中计数为1的时候对应sda线上的第一个bit位而在WR_ADDR和RD_DATA状态中计数为0的时候对应sda线上的第一个bit位。在WR_ADDR状态中iic_scl_cnt计数到8时为接收ACK应答的时间段当计数到8时接收到ack应答并且到下一个SCL低电平中心位置时状态跳转到SCL_START_T。在IIC发送完器件地址和写寄存器地址后会发送一次重开始标志使SCL在SCL_START_T和REPEATED_START状态时为高为了使SCL的低电平时间满足时序要求使SCL在SCL_START_T状态下scl_start_time_cnt小于127时为低sda_out在SCL_START_T状态下拉高在REPEATED_START状态拉低根据时序规范重复起始条件的建立时间不小于4.7us后SCL保持高电平的时间要大于4.0us所以这里还需要scl_start_time_cnt在SCL_START_T状态时开始计数计数到511并且sclk_cnt也计数到511时状态跳转到REPEATED_START再经过一个SCL的周期后状态跳转到SLAVE_ADDR_RD再传输一次器件地址但这次的读写位为1表示接下来准备从器件读取数据发送完后同样接收ACK再跳转到RD_DATA状态。从什么位置开始读取呢其实就是重开始之前发送的写寄存器地址开始读我们发送的写寄存器地址为00H所以读的第一个寄存器地址也是00H需要读出128个字节也就是读到127的寄存器地址结束。我们每接收8位数据就要给对方发送一次ACK应答同时可以利用寄存器rd_slave_data来存储接收到的数据这样可以方便看出接收到的字节数据。当读出128个字节的数据后会发送一个不应答信号也就是最后一个字节传出结束后在iic_scl_cnt8并且rd_data_cnt127时sda_out为1然后跳转到STOP状态停止信号表现为在SCL为高时SDA由低变高。停止条件的建立时间SCL为1SDA为0最低4.0us停止信号产生后SCL还需要保持至少4.7us的高电平状态。所以需要先把SCL拉高SDA在SCL拉高之前保持为0使SDA在SCL为高时由低变高来建立IIC的停止标志。这里需要注意SCL在拉高之前也要满足SCL为低电平的最低时间的要求所以设计一个产生停止条件的计数器stop_time在STOP状态时计数器开始计数。为了满足SCL为低的最低时间要求计数到255时SDA拉低计数器加到511时拉高计数到1023时返回到IDLE状态二、 总结到此模拟主机发送IIC时序的模块完成了后边再来模拟EEPROM编写发送数据的代码发送的数据就为之前储存在ROM中的EDID数据。本文章由威三学社出品对课程感兴趣可以私信联系
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2476035.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!