I2C
示例列表
本章介绍 I2C 示例的详细信息。RTL87x2G 为 I2C 外设提供以下示例。
功能概述
I2C 总线是一种双线串行接口,由串行数据线( SDA )和串行时钟线( SCL )组成。 这2条线用于在连接到总线的设备之间传输信息。
I2C 总线上的每个设备都有一个唯一的地址,可以根据设备的功能作为发送器或接收器操作。
在进行数据传输时,设备也可以被视为主设备或从设备。 主设备负责总线上发起数据传输,并生成允许传输的时钟信号。 一旦主设备发起数据传输,任何被寻址的设备都被视为从设备。
特性列表
支持最多 4 个 I2C。
双线 I2C 串行接口:由串行数据线 (SDA) 和串行时钟 (SCL) 组成。
支持主设备模式和从设备模式。
支持 7/10 位寻址模式。
支持 standard mode(0 到 100Kb/s)、fast mode(小于等于 400Kb/s)和 fast mode plus(小于等于 1000Kb/s)。
支持 40MHz 时钟源。
支持中断或轮询模式操作。
发送 FIFO 深度:24。
接收 FIFO 深度:24。
支持 GDMA 传输。
系统框图
I2C 的体统框图如下图所示:

I2C 系统框图
通信协议
在 SDA 线上发送的每个字节必须为 8 位。 每次传输可以发送的字节数没有限制,每个字节后必须跟随一个响应位。 数据的最高有效位 (MSB) 最先传输。
如果从设备需要完成其他功能,如内部中断服务程序,它可以接收或发送下一个完整的数据字节。时钟线 SCL 可以保持低电平以迫使主设备进入等待状态。 当从设备准备好接收下一个数据字节并释放时钟线 SCL 时,数据传输继续。

I2C 传输协议原理图
I2C Command
当第一个数据写入到 I2C TX FIFO 中,传输开始,硬件会自动发送命令。传输将在主设备发出 STOP 信号后终止。 写入 I2C TX FIFO 的命令格式如下所示:
Function Description |
BIT[31:11] |
BIT[10] |
BIT[9] |
BIT[8] |
BIT[7:0] |
---|---|---|---|---|---|
Command Format |
Reserved |
Restart |
Stop |
Command |
Data |
Write data |
0 |
0 |
0 |
0 |
xxxxxxxx |
Write the last data |
0 |
0 |
1 |
0 |
xxxxxxxx |
Read data |
0 |
0 |
0 |
1 |
0 |
Read the last data |
0 |
0 |
1 |
1 |
0 |
主设备通信模式
I2C 主设备支持如下通信模式:Master Write,Master Read 和 Master Repeat Read。 在 LoopBack 示例中,详细介绍了三种通信模式的示例程序。
用户可以通过将参数 I2C_InitTypeDef::I2C_DeviveMode
设置为 I2C_DeviveMode_Master
来将 I2C 设备模式设置为主设备,设置为 I2C_DeviveMode_Slave
来将 I2C 设备模式设置为从设备。
下面将介绍上述三种模式在 7-bit 地址和 10-bit 地址模式下的通信时序。
7-Bit 地址模式
Master Write
函数 I2C_MasterWrite()
实现了 I2C 主设备在轮询模式下写入数据的功能。
主设备通过 7 位从设备地址向从接收器传输数据。传输方向不变。 所有数据以字节格式传输,单次数据传输的字节数没有限制。 主设备发送地址和读/写位后,或主设备向从设备传输一个字节的数据后,从接收器必须响应确认信号。 当从接收器没有响应 ACK 脉冲时,主设备通过发出停止条件中止传输。 从设备必须保持 SDA 线为高电平,以便主设备中止传输。

7-Bit 地址模式下 Master Write 示意图
Master Read
函数 I2C_MasterRead()
实现了 I2C 主设备在轮询模式下读取数据的功能。
在第一次响应中,主设备-发送器变为主设备-接收器,从设备-接收器变为从设备-发送器,并且第一次响应仍由从设备生成。 如果主设备正在接收数据,主设备在接收到一个字节的数据后会向从设备-发送器发送一个确认脉冲,除了最后一个字节。 NACK 是主设备-接收器通知从设备-发送器这是最后一个字节的方式。 从设备-发送器在检测到无确认(NACK)后释放 SDA 线,以便主设备能够发出停止条件。

7-Bit 地址模式下 Master Read 示意图
Master Repeat Read
函数 I2C_RepeatRead()
实现了 I2C 主设备在轮询模式下先写入后读取数据的功能。
在执行写前读操作时,开始条件和从设备地址会被重复发送,但读/写位是相反的。

7-Bit 地址模式下 Master Repeat Read 示意图
10-Bit 地址模式
Master Write
函数 I2C_MasterWrite()
实现了 I2C 主设备在轮询模式下写入数据的功能。
主设备发送器以 10 位从设备地址向从设备接收器发送数据。传输方向不变。

10-Bit 地址模式下 Master Write in 10-Bit Addressing Mode
Master Read
函数 I2C_MasterRead()
实现了 I2C 主设备在轮询模式下读取数据的功能。
主设备发送器以 10 位从设备地址向从设备接收器发送数据。 在第二个读/写位之后,传输方向发生变化,主设备发送器变为主设备接收器,从设备接收器变为从设备发送器。

10-Bit 地址模式下 Master Read 示意图
Master Repeat Read
函数 I2C_RepeatRead()
实现了 I2C 主设备在轮询模式下先写入后读取数据的功能。
主设备向从设备发送数据,然后从同一从设备读取数据。传输方向在第二个读/写位后发生改变。

10-Bit 地址模式下 Master Repeat Read 示意图
I2C GDMA
I2C GDMA TX
在 I2C 传输过程中,当 TX FIFO 内数据的数量小于或等于初始化中设置的 I2C_InitTypeDef::I2C_TxWaterlevel
值时,会触发一次 GDMA burst 搬运。
GDMA 一次 burst 会将 GDMA_InitTypeDef::GDMA_DestinationMsize
个数据写入 I2C TX FIFO 中。
I2C GDMA TX 时,推荐设置 I2C_InitTypeDef::I2C_TxWaterlevel
的值为 I2C_TX_FIFO_SIZE - MSize
。

I2C GDMA TX 示意图
I2C GDMA RX
在 I2C 传输过程中,当 RX FIFO 内数据的数量大于或等于初始化中设置的 I2C_InitTypeDef::I2C_RxWaterlevel
+ 1 时,会触发一次 GDMA burst 搬运。
GDMA 一次 burst 会从 I2C RX FIFO 中获取 GDMA_InitTypeDef::GDMA_SourceMsize
个数据。
I2C GDMA RX 时,推荐设置 I2C_InitTypeDef::I2C_RxWaterlevel
的值为 MSize - 1
。

I2C GDMA RX 示意图
常见问题
时钟速度配置说明
I2C 时钟速度与 SCL 上升时间有关,该时间受上拉电阻和电容影响。
用户可以配置变量 I2C_InitTypeDef::I2C_RisingTimeNs
来校准 I2C 时钟速度。I2C_InitTypeDef::I2C_RisingTimeNs
的默认值为 50。
以下示例演示了 I2C 时钟速度的校准方法,以 I2C 的时钟源 40 MHz 为例:
将变量
I2C_InitTypeDef::I2C_RisingTimeNs
设置为 100。测量 I2C 时钟速度。例如,如果实际测得的频率为 411 KHz,则周期为:1/411 KHz = 2433 ns。
计算
I2C_InitTypeDef::I2C_RisingTimeNs
的实际值。SCL Low Time = SCL Low Period - SCL Falling Time + SCL Rising Time.
SCL High Time = SCL High Period + SCL Falling Time.
SCL Frequency = 1 / (SCL High Time + SCL Low Time).
根据公式 a 到 c,SCL Period = SCL Low Period + SCL High Period + SCL Rising Time.
SCL Low Period (ns) + SCL High Period (ns) = SCL Period (ns) - APP 中配置的
I2C_InitTypeDef::I2C_RisingTimeNs
= 2500 - 100 = 2400.实际
I2C_InitTypeDef::I2C_RisingTimeNs
值 = 实际周期 - (SCL Low Period + SCL High Period) = 2433 - 2400 = 33。因为 I2C 的时钟源设置为 40MHz,I2C 时钟的精度为 25ns。因此,设置
I2C_InitTypeDef::I2C_RisingTimeNs
需要对齐到 25ns。