以下内容源于朱有鹏嵌入式课程的学习与整理,如有侵权请告知删除 。
参考博客
SPI、I2C、UART(即串口)三种串行总线详解_天糊土的博客-CSDN博客_串口总线
s5pv210 I2C通信详解 - biaohc - 博客园
嵌入式常用技术概览之IIC(I2C)_C_XianRen的博客-CSDN博客_c# iic
很清晰的解读i2c协议_追风de人的博客-CSDN博客_i2c协议(推荐)
通信协议-(一)IIC总线_i2c应答与非应答-CSDN博客
三大通信协议(二):IIC通信协议-腾讯云开发者社区-腾讯云
一、I2C通信的简介
I2C通信,指两个设备之间通过I2C总线进行通信,遵循I2C通信的协议。
1、I2C总线简介
I2C(Inter-Integrated Circuit),中文应该叫内部集成电路。它是一种两线式串行通信总线,是由飞利浦公司在1980年代初设计的。由于其简单性,被广泛用于微控制器与周围外设组件之间的通信,比如EEPROM、电容触摸IC、各种传感器等。
上图是I2C总线物理拓扑图,可知I2C总线包括两根信号线:
时钟线(serial clock,SCL),用于传输时钟信号,一般是I2C主设备为从设备提供时钟信号。
数据线(serial data,SDA),用于传输通信数据(包括命令、地址、数据)。
另外这两条信号线都通过上拉电阻接到VCC上,所以总线空闲时,这两条信号线保持高电平。
2、I2C通信特征
(1)串行、同步、电平信号、低速率、半双工
- 数据在SDA线上是以串行方式传输的,每次传输8bit,即以字节为单位传输。
- 同步通信就是通信双方工作在同一个时钟下,所以同步通信的显著特征就是:通信线中有一根信号线CLK,通信的A方通过CLK信号线将 A 的时钟传输给B,B工作在A传输的时钟下。
- 因为I2C通信速率不高,而且通信双方距离很近,所以使用电平信号通信。
- I2C一般用在同一个板子上的2个IC之间,传输的数据量不大,因此本身通信速率很低(一般几百KHz)。不同I2C芯片的通信速率可能不同,在编程的时候要看具体设备允许的I2C通信最高速率。
- 半双工通信,意思就是要么只能发,要么只能收。这很自然,因为只有一根SDA信号线,如果主设备和从设备同时往SDA信号线上写数据,肯定会出现冲突的。
(2)总线上的设备分为主设备与从设备
- I2C通信时,通信双方地位是不对等的,分为主设备和从设备。
- 谁是主设备,谁是从设备,由通信双方来决定,I2C协议并无这方面的规定。任何一个设备都能像主设备一样工作,但同一时刻只能有一个主设备。通常情况下,我们把SoC中带I2C总线接口的模块作为主设备,把挂接在总线上的其他设备作为从设备。
- 通信由主设备发起和主导,从设备只是按照I2C通信协议被动地通信。
(3)允许多个从设备挂接在同一I2C总线上
- 连接到同一I2C总线上的设备数量,只受I2C总线的最大电容限制。
- 主设备通过寻址来确定与哪个器件进行通信,同一时刻只能有一个从设备和主设备通信。
- 每个设备都有一个地址,它是从设备本身固有的属性。这个地址在电路板上是唯一的,但不是全球唯一的。这个地址共7个bit,理论上有128个地址,但是有几个保留地址,比如广播地址0x00等,因此数量少于128个。系统中可能有多个同种芯片,因此从设备的地址分为固定部分和可编程部份。
(4)采用大端传输方式
- SDA传输数据是大端传输,每次传输的有效数据都是1个字节。
二、I2C通信的协议
主设备和从设备进行数据传输时遵循以下协议格式。主设备和从设备之间通过一条SDA线传输0
和1
的串行数据。串行数据序列的结构可以分为,开始信号,7bit的地址位,1bit的读写位,1bit的应答位,8bit的数据位,结束信号,具体如下图所示:
1、开始信号
SCL线为高电平期间,SDA线由高电平向低电平跳变,表示起始信号。
2、7bit的地址位
地址位通常占 7bit 数据。主设备如果需要向从设备发送、接收数据,首先要发送从设备的地址。
I2C 还支持 10 位寻址。
3、1bit的读写位
读写位占据 1bit 数据,指定了数据传输的方向。这里的读写,是从主设备对总线的操作这个角度来说的。比如写,是指主设备写数据到总线,那么从设备从总线读数据;比如读,是指主设备读取总线的数据,那么从设备写数据到总线。
- 如果主设备需要发送数据到从设备,则该位设置为
0
; - 如果主设备需要接收来自从设备的数据,则将其设置为
1
。
4、1bit的应答位
主设备每次发送完数据之后,会等待从设备的应答信号ACK。
主设备利用SDA线传输完一个字节后,就会释放SDA线。释放后的SDA线处于高电平的状态,从设备就可以控制SDA线了。
此时如果从设备下拉SDA线,而且主设备从SDA线读到了这一个低电平,则表示从设备发送了一个应答信号0(ACK)。如果从设备不下拉SDA线,则主设备从SDA线读到的依然是高电平,它表示一个非应答信号1(NACK),这会让主设备发生重启或停止流程。
5、8bit的数据位
数据位占据 8 bit ,由发送方设置。接收方如果成功收到数据,则会发送一个应答信号0,否则发送一个非应答信号1。
这步骤可以重复,直到将数据传输完毕。
6、结束信号
SCL为高电平期间,SDA线由低电平向高电平跳变,结束传送数据。
7、写寄存器的标准流程
如果主设备要往从设备的某个寄存器写入数据,则其流程如下:
- 1、Master发起START
- 2、Master发送I2C addr(7bit)和 W操作0(1bit),等待ACK
- 3、Slave发送ACK
- 4、Master发送reg addr(8bit),等待ACK
- 5、Slave发送ACK
- 6、Master发送data(8bit),即要写入寄存器中的数据,等待ACK
- 7、Slave发送ACK
第 6 步和第 7 步可以重复多次,即顺序写多个寄存器。
- 8、Master发起STOP
8、读寄存器的标准流程
如果主设备要接收来自从设备的数据,并把数据存入某个寄存器汇总,则其流程如下:
- 1、Master发送I2Caddr(7bit)和 W操作0(1bit),等待ACK
- 2、Slave发送ACK
- 3、Master发送reg addr(8bit),等待ACK
- 4、Slave发送ACK
- 5、Master发起START
- 6、Master发送I2C addr(7bit)和 R操作1(1bit),等待ACK
- 7、Slave发送ACK
- 8、Slave发送data(8bit),即寄存器里的值
- 9、Master发送ACK
第 8 步和第 9 步可以重复多次,即顺序读多个寄存器。
- Master发起STOP
三、总结
每一个通信周期的发起和结束都由主设备进行,从设备只有被动地响应主设备。
主设备先发送8位的从设备地址,其中7位是从设备地址,1位表示主设备接下来是要写数据到总线,还是从总线读取数据。主设备以广播的形式发送,总线上的所有从设备都能收到这个信息。从设备收到地址后,与本身的设备地址对比。发送方发送一段数据后,接收方需要回应一个ACK,表示收到数据。
在某个时刻,主设备和从设备只能有一个在发(发数据,即向总线写数据,这会占用总线),另一个在收(从总线读)。