转载自点击打开链接
1.I2C协议
2条双向串行线,一条数据线SDA,一条时钟线SCL。
SDA传输数据是大端传输,每次传输8bit,即一字节(工作速率有100Kbit/s、400Kbit/s和3.4Mbit/s三种;(一般使用小于100Kbit/s))。
支持多主控(multimastering),任何时间点只能有一个主控。
总线上每个设备都有自己的一个addr,共7个bit,广播地址全0.
系统中可能有多个同种芯片,为此addr分为固定部分和可编程部份,细节视芯片而定,看datasheet。
连接到总线的接口数量由总线电容400pF的限制决定。
仲裁——多个主控器试图同时控制总线时一个裁决过程,它只允许其中的一个主控器继续占用总线,并保证在整个过程中总线上的数据不会被丢失或出错误;
1.1 I2C位传输
若SDA发生跳变,则用来表示一个会话的开始或结束(后面讲)
数据改变:SCL为低电平时,SDA线才能改变传输的bit
1.2 I2C开始和结束信号
开始信号:SCL为高电平时,SDA由高电平向低电平跳变,开始传送数据。
结束信号:SCL为高电平时,SDA由低电平向高电平跳变,结束传送数据。
1.3 I2C应答信号
即在第9个clock,若从IC发ACK,SDA会被拉低。
若没有ACK,SDA会被置高,这会引起Master发生RESTART或STOP流程,如下所示:
1.4 I2C写流程
写寄存器的标准流程为:
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
1.5 I2C读流程
读寄存器的标准流程为:
1. Master发送I2C addr(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步可以重复多次,即顺序读多个寄存器
1.6 特别注意
I2c总线死锁:(资源的相互占用)
I2C总线操作过程中,主机写(或者读)操作完成之后,拉低SCL信号为低电平(等待应答),从机输出应答信号,将SDA信号拉为低电平。如果这个时候主机异常复位,SCL就会被释放为高电平(主机发送数据状态)。此时,如果从机没有复位,就会继续I2C的应答,等待SCL变为低电平,才会结束应答信号。而对于主机来说,复位后检测SCL和SDA信号,如果发现SDA信号为低电平,则会认为I2C总线被占用,会一直等待SCL和SDA信号变为高电平。这样,主机占用SCL,从机占用SDA,而又无法获得需要的资源,产生死锁。
注意: I2c发送数据的前提是SCL信号与SDA信号均为高电平,从设备发送应答信号的前提是SCL信号与SDA信号均为低电平数据传输速率:如果从机希望主机降低传送速度可以通过将SCL主动拉低延长其低电平时间的方法来通知主机(只有当时钟线上的信号处于高电平时,数据线上的数据才是有效的 ),当主机在准备下一次传送发现SCL的电平被拉低时就进行等待, 直至从机完成操作并释放SCL线的控制控制权。
1.7 I2C的寄存器
1. 地址寄存器
2. 频率寄存器
3. 控制器存期——模块enable/中断enable、Transmit/receive 模式
4. 数据寄存器
5. 状态寄存器————一般不需自己设定
在实际操作系统中,驱动最底层的I2C都是如此,在其上面封装一层内核驱动层(adapter-client模式)实现完整的I2C架构。