Menu Close

I2C 主设备PHY层读控制Verilog程序设计

在I2C发送对设备的地址和读操作后,就要向设备发送读数据操作,这时,控制器就需要连续发送SCL信号给设备,并且在SCL的上升沿读取设备返回的数据,在连续接收到8个数据后,控制器发送ack/nack信号给设备。这个部分就是控制器对设备的读操作。在I2C PHY层 Verilog程序结构化设计 文章中的op_cmd[1:0] = 2’b10 来实现。如图1:

图1

1.I2C读数据部分控制器程序设计

  • 接口要求:

    • 复位信号,系统时钟,系统时钟分频(由于I2C不同速度匹配)
      • input rst,
      • input sys_clk,
      • input clk_en, clk_en_half,
    • 从设备地址、启动信号、读/写标志(即该段程序之后的I2C 总线行为
      • output [7:0] data_out,  // device send data to controller
      • input [1:0] op_cmd,      // 2’b10 means controller receive data from device
      • input op_cmd_en,        // op_cmd enable , sys_clk single pulse
    • I2C 总线的内部信号:由于inout信号一般只在端口使用,因此在FPGA的内部逻辑(内部模块)将会把inout(双向口)变换成input, output类型进行传递
      • input sda_i,
      • output sda_o,
      • output sda_t,
      • input scl_i,
      • output scl_o,
      • output scl_t,
    • 握手信号:op_cmd_done 操作完成、从设备应答。当op_cmd_done产生,从设备应答后(dev_ack)同时送给上层模块。op_cmd_done 保持一个sys_clk 时钟宽度。
      • output op_cmd_done, // operation finished
      • input  master_ack         //controller send ACK/NACK to device
  • 主体程序设计

该部分程序实现的主体内容如下:初始化,在IDLE状态下检测启动请求(op_cmd = 2’b01),控制器发送数据进行串行化,等待从设备应答。串行化期间对SCL,SDA的要求是,在SCL为高电平期间设备接收控制器发送的数据,在SCL低电平后,等待半个时钟周期再变化数据,这样可以保证在pcb layout,或者FPGA 布局布线不会影响到 SCL 低电平内发送数据。当主控制器接收到8个bit数据后,控制器向设备发送ACK/NACK 。

程序的流程图如下:

I2C 主设备PHY层读控制Verilog程序设计

图2

  • 程序代码如下:


 

  • iic_phy 模块代码


 

  • 将设计的模块例化,并组装到 iic_engine的模块中,这样就可以使用SCl_en模块,充分利用以设计的成果,逐步组装成程序代码及接口如下:


 

  • 仿真程序设计:


 

  • 仿真结果

仿真波形如图3

图3

从图3可以看出,写入读命令 7’b1010_001 + read。 等待设备会ACK, 然后控制器读取设备数据,控制器回ACK 给设备。 当接收完最后一个数据后,控制器会NACK,通知设备,之后不再读取数据了。 当前的仿真程序中没有使用STOP 命令,在下面的课程中对STOP 命令再做介绍。

 

Posted in FPGA, FPGA 教材教案, Verilog, 教材与教案, 文章