找回密码
 立即注册
搜索
查看: 2595|回复: 0

基于 FPGA 的模拟 I2C协议设计(附代码)

[复制链接]

346

主题

14

回帖

3万

积分

版主

Rank: 7Rank: 7Rank: 7

积分
36982
发表于 2024-8-10 13:26:59 | 显示全部楼层 |阅读模式
本帖最后由 眼镜一米二 于 2024-8-10 13:31 编辑

叁芯智能科技FPGA就业班08月开班中



今天给大侠带来基于FPGA的 模拟 I2C 协议设计,包括 I2C 总线解析以及模拟 I2C 接口程序的基本框架、I2C 协议的具体实现、程序的仿真与测试。篇幅较长,话不多说,上货。


之前也有相关文章介绍,这里超链接一下,仅供各位大侠参考。


源码系列:基于FPGA的 IIC 设计(附源工程)






导读





I2C(Inter-Integrated Circuit),其实是 I2C Bus简称,中文就是集成电路总线,它是一种串行通信总线,使用多主从架构,由飞利浦公司在1980年代为了让主板、嵌入式系统或手机用以连接低速周边设备而发展。I2C的正确读法为“I平方C”("I-squared-C"),而“I二C”("I-two-C")则是另一种错误但被广泛使用的读法。自2006年10月1日起,使用 I2C 协议已经不需要支付专利费,但制造商仍然需要付费以获取 I2C 从属设备地址。


I2C 简单来说,就是一种串行通信协议,I2C的通信协议和通信接口在很多工程中有广泛的应用,如数据采集领域的串行 AD,图像处理领域的摄像头配置,工业控制领域的 X 射线管配置等等。除此之外,由于 I2C 协议占用的 IO 资源特别少,连接方便,所以工程中也常选用 I2C 接口做为不同芯片间的通信协议。I2C 串行总线一般有两根信号线,一根是双向的数据线SDA,另一根是时钟线SCL。所有接到 I2C 总线设备上的串行数据SDA都接到总线的SDA上,各设备的时钟线SCL接到总线的SCL上。


在现代电子系统中,有为数众多的 IC 需要进行相互之间以及与外界的通信。为了简化电路的设计,Philips 公司开发了一种用于内部 IC 控制的简单的双向两线串行总线 I2C(Intel-Integrated Circuit bus)。1998 年当推出 I2C 总线协议 2.0 版本时,I2C 协议实际上已经成为一个国际标准。


在进行 FPGA 设计时,经常需要和外围提供 I2C 接口的芯片通信。例如低功耗的 CMOS 实时时钟/日历芯片 PCF8563、LCD 驱动芯片 PCF8562、并行口扩展芯片 PCF8574、键盘/LED 驱动器 ZLG7290 等都提供 I2C 接口。因此在 FPGA 中模拟 I2C 接口已成为 FPGA 开发必要的步骤。


本篇将详细讲解在 FPGA 芯片中使用 VHDL/Verilog HDL 模拟 I2C 协议,以及编写 TestBench仿真和测试程序的方法。


第一篇内容摘要:本篇会介绍 I2C 总线解析,包括 I2C 总线概述、I2C 协议的基本概念、I2C协议的时序要求,还会介绍模拟 I2C 接口程序的基本框架等相关内容。


一、I2C总线概述


下面先对 I2C 协议中有关数据格式和时序的内容进行介绍,这里没有涉及的地方请参考《THE I2C-BUS SPECIFICATION VERSION 2.1 JANUARY 2000》。


1.1 I2C 总线概述


I2C 协议作为一个串行总线标准尽管没有并行总线的数据吞吐能力,但是它的以下特点使其有着广泛的应用:


• 只需要两条总线—串行数据线 SDA 和串行时钟线 SCL;

• 每个连接到总线的器件都可以通过惟一的地址和一直存在的简单的主/从节点关系软件设定地址,主节点可以发送数据或接收数据;

• 是真正的多主总线,当两个或更多主节点同时初始化数据传输时,可以通过冲突检测和仲裁防止数据被破坏;

• 串行的 8 位双向数据传输位速率在标准模式下可达 100kbit/s,快速模式下可达400kbit/s,高速模式下可达 3.4Mbit/s;

• 片上的滤波器可以滤去总线数据线上的毛刺波,保证数据完整;

• 连接到相同总线的 IC 数量只受到总线的最大电容(400pF)限制。



总线不仅仅是互连的线,还包含系统通信的所有格式和过程。I2C 总线结构上的特点保证了其应用时的简洁,另外其完备的协议避免了所有混乱、数据丢失和妨碍信息的可能性。


1.2 I2C 协议的基本概念



I2C 总线支持任何 IC 生产过程(NMOS、CMOS 和双极性)。串行数据线 SDA 和串行时钟线 SCL在连接到总线的器件间传递信息。每个器件都有一个惟一的地址作为识别的标志(无论是微控制器、LCD 驱动器存储器还是键盘接口),并且都可以发送数据和接收数据。很明显 LCD 驱动器只需要接收数据,而存储器需要接收和发送数据。图 1 所示的是一个高性能集成电视的例子。




图 1 高性能集成电视





从图 1 可以看到,应用 I2C 总线是非常方便的。用通俗的话讲 I2C 总线的硬件设计工作就是连接 SDA 和 SCL 两条线,依靠 I2C 协议完成软件工作。在 I2C 协议中应理解如下的概念。


1)主/从节点

主节点负责初始化总线的数据传输,并产生允许传输的时钟信号。此时任何被寻址的器件都被认为是从节点。当有多个主节点在总线上传输数据时,每个主节点产生自己的时钟信号。挂接到总线上的所有外围器件、外设接口都是总线上的节点。


2)总线上节点的寻址方式

在任何时刻总线上只有一个主控器件(主节点)实现总线的控制操作,对总线上的其他节点寻址,可分时实现点-点的数据传送。因此总线上每个节点都有一个固定的节点地址。

I2C 总线上主节点的地址由软件给定,此地址存放在 I2C 总线的地址寄存器中。I2C 总线上所有的外围器件都有规范的器件地址。器件地址由 7 位数字组成,它和 1 位方向位构成了 I2C 总线器件的寻址字节 SLA(Slave address)。


器件地址是 I2C 总线外围接口器件固有的地址编码,器件出厂时就已给定。数据方向位规定了总线上主节点对从节点的数据传送方向。



1.3 I2C协议的时序要求

1)总线上的数据传递时序


I2C 总线上数据传递时序如图 2 所示,具体步骤如下。




图 2 I2C 总线的数据传递时序





• 首先主节点器件发送一个起始信号。

• 接下来主节点器件发送从节点地址和读写方式,一共 8 位。其中从节点地址 7 位,读写方式 1 位。

• 与传输地址一致的从节点器件应答(即 ACK)。

• 开始数据传输,传输数据数量不限。每个字节(八位)后面跟接收数据方的应答位。例如主节点器件读取从节点数据,从节点发送数据,主节点应答;主节点器件写数据到从节点,主节点发送数据,从节点应答。

• 数据传输结束,主节点器件发送一个终止信号结束整个过程。


采用 I2C 总线后对传送的字节数没有限制,只要求每传送一个字节后对方回应一个应答位。在发送时首先发送的是数据的最高位(MSB,Most Significant Bit)。每次传送开始有起始信号,结束时有停止信号。在总线传送完一个字节后,可以通过对时钟线(SCL)的控制使传送暂停。例如当某个外围器件接收 N 个字节数据后需要一段处理时间以便继续接收以后的字节数据,这时可在应答信号后使 SCL 变为低电平控制总线暂停。如果主节点要求总线暂停也可使时钟线保持低电平控制总线暂停。


2)总线上的时序信号


I2C 总线为同步传输总线,总线信号完全与时钟同步。I2C 总线上与数据传送有关的信号有起始信号 S、终止信号 P、应答信号 A 以及位传送信号。下面将对这些信号一一介绍。

(1)起始信号

起始信号(Start Condition)如图 3 所示。当时钟线 SCL 为高电平时,数据线 SDA 从高电平向低电平变化将形成起始信号,启动 I2C 总线。


(2)终止信号

终止信号(Stop Condition)如图 3 所示。当时钟线 SCL 为高电平时,数据线 SDA 从低电平向高电平变化将形成终止信号,停止 I2C 总线。


(3)应答信号


如图 3 所中 ACK 第 9 个时钟脉冲对应应答位,相应数据线上低电平时为应答信号,高电平时为非应答信号。



图 3 起始信号和终止信号



(4)位传送信号


在 I2C 总线启动后或应答信号后的第 1~8 个时钟脉冲对应于一个字节的 8 位数据传送。脉冲高电平期间,数据串行传送;低电平期间为数据准备,允许总线上数据电平变换。



二、模拟 I2C接口程序的基本框架


模拟 I2C 接口程序的基本框架如图 4 所示。




图 4 模拟 I2C 接口程序的基本框架


1)程序接口


用于和应用程序连接的接口,将应用程序的数据按照 I2C 协议的方式通过 SDA 传递给外部器件。包括下列内容:

• clk_I FPGA 外部时钟信号。

• rst_I 同步重起信号。

• arst_I 异步重起信号。

• adr_I 从节点地址。

• dat_I 输入数据。

• dat_o 输出数据。

• we_I 写有效信号。

• stb_I 接口有效信号。

• cyc_I 有效总线周期输入。

• ack_o 应答信号输出。

• inta_o 中断信号输出。


2)时钟设置寄存器

I2C 协议提供了 3 种速度模式:正常速度模式 100kbit/s、快速模式 400kbit/s、高速模式3.5Mbit/s。SCL 输出的时钟信号频率和速度模式一致。程序内部使用 5 倍 SCL 信号作为时钟,而 FPGA 外部时钟需要经过分频得到程序内部使用的时钟。

例如:采用正常速度 100kbit/s,FPGA 外部时钟为 50MHz,则时钟设置寄存器需要设置为(50MHz/5*100kHz – 1=99)。


3)时钟产生模块

时钟产生模块产生 4 倍 SCL 频率的时钟信号,它为位传输控制模块中所有同步动作提供触发信号。


4)命令寄存器

命令寄存器共 8 位,它决定是否在总线上产生各种时序信号、是否读/写数据,各位表示的含义如表 1 所示。



表 1 命令寄存器内容



5)状态寄存器

状态寄存器用来显示当前总线的状态,例如是否接收到从节点的应答信号、是否忙、是否在传递数据等,具体内容如表 2 所示。



表 2 状态寄存器内容



6)数据传输寄存器

数据传输寄存器用于保存等待传输的数据。当传递从节点地址信息时,前 7 位保存从节点地址,最后一位保存读写命令;当传递普通数据时,8 位保存一个字节数据。数据传输寄存器具体内容如表 3 所示。



表 3 数据传输寄存器内容



7)数据接收寄存器

数据接收寄存器用于保存通过 I2C 总线接收到的最后一个字节内容,具体内容如表4所示。



表 4 数据接收寄存器内容




8)字节传输控制模块

字节传输控制模块以字节为单位控制 I2C 总线的数据传输。这个模块按照命令寄存器设置的内容将数据传输寄存器内容传递到 I2C 总线的接收端,或者从 I2C 总线发送端接收数据并保存到数据接收寄存器中。


9)位传输控制模块

位传输控制模块以位为单位进行 I2C 总线的数据传输和产生各个 I2C 协议命令(如开始、停止、重复开始等)。字节传输控制模块控制位传输控制模块的各种动作。例如读取一个字节数据,位传输控制模块需要执行 8 个读的命令。


10)数据移位寄存器

数据移位寄存器保存的数据总是和当前的数据传输相关的。例如在进行读操作时,主节点通过移位寄存器依次通过 SDA 获得来自 I2C 发送端的数据,完成后数据拷贝到数据接收寄存器中。在写操作时,数据传输寄存器中的数据拷贝到数据移位寄存器中,然后依次通过 SDA 将数据传输到 I2C 总线的接收端。



三、I2C协议的具体实现




FPGA 设计一般按照从顶向下的模式进行:首先设计芯片功能,规划各个模块功能;然后按照规划实现各个模块。本篇由 3 个代码文件组成:i2c_master_bit_ctrl.v 完成位传输的功能、i2c_master_byte_ctrl.v 完成字节传输的功能、i2c_master_top.v 完成整个程序的控制功能,并提供给外部程序的接口。在 ISE 中创建一个项目,然后加入上面 3 个文件。下面依次介绍 3 个文件的内容。本篇讲解采用 Verilog HDL。








3.1 位传输的实现

i2c_master_bit_ctrl.v 完成位传输的功能。位传输的功能包括数据按位传输的实现和 I2C协议各个命令的实现两部分。

如图 5 所示开始和重复开始命令的产生包括 5 个阶段:idle 和 A、B、C、D 等。停止命令包括 4 个阶段:idle 和 A、B、C 等。读、写一个字节通过 8 次位操作完成。



图 5 位传输完成数据的传输和各个命令的实现



实现代码如下:



3.2 字节传输的实现

字节传输的具体实现流程如图 6 所示。



图 6 字节传输控制模块流程图


字节传输控制模块控制以字节为单位的数据传输。它根据命令寄存器的设置将数据传输寄存器中的内容传输到外部节点,将外部节点的数据接收到数据接收寄存器中。


实现代码如下:




3.3 程序主体的实现


程序主体部分完成与外部程序的接口、与总线上外部节点的连线、完成程序内部各个寄存器的构建、控制字节传输控制模块等功能。代码如下:




四、程序的仿真与测试


I2C 协议的模拟程序完成后,还需要通过仿真程序对程序的功能进行测试。对本程序的仿真包括 3 个部分:第一部分是主节点的仿真,模拟数据读/写;第二部分是从节点的仿真,模拟数据的接收和应答;第三部分是仿真主程序,负责整个仿真过程的控制。



4.1 主节点的仿真


主节点仿真的内容包括读数据、写数据和比较数据 3 部分,代码如下:



4.2 从节点的仿真


从节点仿真程序需要模拟从主节点接收数据,并发出应答信号,代码如下:




4.3 仿真主程序


仿真主程序完成主节点数据到从节点的控制,代码如下:




4.4 仿真结果


在 ModelSim 中可以看到仿真的结果。如图 7 所示是发送开始状态并写地址“a0”时的图形,此时在图上表示为 SCL 处于高时 SDA 的一个下降沿,然后是数据“1010,0000”。




图 7 发送开始信号并写地址 a0



如图 8 所示为发送数据“01”和“a5”时的图形,在图上表示为:数据“0000,0001”和“1010,0101”。




图 8 发送数据“01”和“a5”


如图 9 所示的是发送停止状态信号和数据“5a”时的图形,在图上表示为 SCL 处于高时SDA 的一个上升沿,然后是数据“0101,1010”。



图 9 发送停止状态信号和数据“5a”


仿真程序说明 I2C 程序符合 I2C 协议的时序和数据格式,可以实现模拟 I2C 协议的任务。


五、总结


     本篇首先说明了 I2C 协议相关的内容,介绍协议基本概念和数据传输各个命令的具体含义以及协议对时序的要求。接下来介绍模拟 I2C 协议程序的框架,详细讲解框架中各个模块的功能并介绍详细代码。最后通过一个完成的仿真程序完成对程序的测试。I2C 在应用中有着广泛的用途,本篇希望通过这个例子为各位大侠提供一个可行的解决方案。













本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|小黑屋|冀ICP备20011060号-2|叁芯智能

GMT+8, 2024-12-22 02:37 , Processed in 0.076175 second(s), 20 queries .

Powered by Discuz! X3.4

© 2017-2018

快速回复 返回顶部 返回列表