以下内容源于朱有鹏嵌入式课程的学习与整理,如有侵权请告知删除 。
参考博客
SPI、I2C、UART(即串口)三种串行总线详解_天糊土的博客-CSDN博客_串口总线
s5pv210 I2C通信详解 - biaohc - 博客园
嵌入式常用技术概览之IIC(I2C)_C_XianRen的博客-CSDN博客_c# iic
很清晰的解读i2c协议_追风de人的博客-CSDN博客_i2c协议(推荐)
一、I2C通信的简介
1、物理接口
(1)SCL(serial clock)
时钟线,传输CLK信号,一般是I2C主设备向从设备提供时钟的通道。
(2)SDA(serial data)
数据线,通信数据(命令、地址、数据)都通过SDA线传输。
2、通信特征
(1)串行通信
所有的数据以比特为单位在SDA线上串行传输,但每次传输8bit。
(2)同步通信
通信双方工作在同一个时钟。A方通过CLK信号线传输时钟给B,B工作在A传输的时钟下。
(3)电平信号
因为I2C通信速率不高,而且通信双方距离很近,所以使用电平信号通信。
(4)低速率通信
I2C一般用在同一个板子上的2个IC之间,传输的数据量不大,因此本身通信速率很低。一般几百KHz,不同I2C芯片的通信速率可能不同,在编程的时候要看具体设备允许的I2C通信最高速率。
3、突出特征
(1)分为主设备与从设备
- 通信由主设备发起和主导,从设备只是按照I2C时序协议被动地接受主设备的通信。
- 谁是主从设备,由通信双方来决定,I2C协议并无规定。
(2)允许多个从设备挂在一条总线上
- 主设备负责调度总线,决定某一时间与哪个从设备通信。
- 同一时刻,只能有一个从设备和主设备通信,其他从设备处于休眠状态。
- 每个I2C从设备在通信中都有一个I2C从设备地址,它是从设备本身固有的属性。这个地址在电路板上是唯一的,但不是全球唯一的。这个地址共7个bit,理论上有128个地址,但有几个保留地址如广播地址0x00等,因此数量少于128个。另外标准协议里预见了地址的局限性,扩充了10位地址的概念。
- 系统中可能有多个同种芯片,因此从设备的地址分为固定部分和可编程部份。
- 通信时主设备需要知道从设备的地址,然后在通信中通过地址来甄别是不是自己要找的那个从设备。
- IIC可以挂多少个设备?对于同一个地址的设备来说,在不进行地址扩充(片选)的情况下只能挂一个;对于不同的设备来说,标准协议里面没有限制具体的数量,这个由线路布线情况、软件情况以及工作模式确定。对于标准模式,只要总线上的负载电容不超过400pf,不超过芯片的负载能力既可以。
(3)采用大端传输方式
SDA传输数据是大端传输,每次传输的有效数据都是1个字节。
4、应用领域
SoC和周边外设之间的通信,典型的如EEPROM、电容触摸IC、各种sensor等。
二、I2C通信的协议
1、I2C通信的内容
(1)开始信号、结束信号
由上图可知,SDA总线空闲是1,且只有下拉操作,故1->0是开始信号,0->1是结束信号。
SCL为高电平时,SDA由高电平向低电平跳变,开始传送数据。
SCL为高电平时,SDA由低电平向高电平跳变,结束传送数据。
(2)位传输
SCL为高电平时,SDA线若保持稳定,那么SDA上是在传输数据bit。
若SDA发生跳变,则用来表示一个会话的开始或结束(如上面讲的)。
SCL为低电平时,SDA线才能改变传输的bit,比如原来传输1,接下来传输0。
(3)应答信号
SDA传输完一个字节后,主机会释放SDA线(传送的数据最后一位若是0,则取消下拉恢复为高电平1,或者最后一位本来就是1),释放后SDA处于高电平的状态,从机就可以控制SDA线了。若从机下拉SDA线并且主机从SDA读到了这一个低电平,则表示从机发送了一个确认信号0;若从机不下拉SDA,则主机读到SDA依然是高电平,故表示一个非应答信号1,这会引起Master发生RESTART或STOP流程
2、数据在总线上的传输协议
这里的读写,是从主机对总线的操作这个角度来说的。比如写,是指主机写数据到总线,那么从机从总线读数据;比如读,是指主机读取总线的数据,那么从机写数据到总线。
(1)write命令
如果为write命令,则主设备释放总线(If the I2C-bus is free, both SDA and SCL lines should be both at High level),即SDA为高位;然后从设备拉低SDA,表示ACK主设备;然后主设备再发送8bit数据,从设备再ACK(A),通信结束(P)。
写寄存器的标准流程:
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
8. 第6步和第7步可以重复多次,即顺序写多个寄存器
9. Master发起STOP
(2)read命令
如果为read命令,则从设备先拉低SDA表示ACK主设备,然后再发送8bit数据。主设备拉低SDA表示ACK从设备(我已经读取8bit的数据),之后结束。
读寄存器的标准流程
1、Master发送I2Caddr(7bit)和 W操作1(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
10. 第8步和第9步可以重复多次,即顺序读多个寄存器
(3)总结
- 每一个通信周期的发起和结束都由主设备进行,从设备只有被动的响应主设备。
- 主设备先发送8位的从设备地址,其中7位是从设备地址,1位表示主设备接下来是要写数据到总线,还是从总线读取数据。主设备以广播的形式发送,总线上的所有从设备都能收到这个信息。从设备收到地址后,与本身的设备地址对比。
- 发送方发送一段数据后,接收方需要回应一个ACK,表示收到数据。
- 在某个时刻,主设备和从设备只能有一个在发(发数据,即向总线写数据,这会占用总线),另一个在收(从总线读)。
换个角度总结如下:
- 起始位及其后的8个clk中都是主设备在发送(主设备掌控总线),此时从设备只能读取总线,通过读总线来得知主设备发给从设备的信息;
- 然后到了第9周期,按照协议规定从设备需要发送ACK给主设备,所以此时主设备必须释放总线(主设备把总线置为高电平然后不要动),同时从设备试图拉低总线发出ACK。
- 如果从设备拉低总线失败,或者从设备根本就没有拉低总线,则主设备看到的现象就是总线在第9周期仍然一直保持高。这意味着主设备没有收到ACK,主设备就认为刚才给从设备发送的8字节不对。