IIC协议简介
IIC总线介绍
IIC也称I2C,是一个多主从的串行总线,由飞利浦公司发明的通讯总线,属于半双工同步传输类总线,仅由两条线就能完成多机通讯,一条SCL时钟线,另外一条双向数据线SDA,IIC总线要求每个设备SCL/SDA线都是漏极开路模式,因此必须带上拉电阻才能正常工作。I2C协议占用引脚少,硬件实现简单,可扩展性强,I2C数据传输速率有标准模式(100kbps)、快速模式(400kbps)和高速模式(3.4Mbps)。
I2C是所主机总线,每个设备都可以成为主机,但任一时刻只能有一个主机。
IIC协议时序
- IDLE
表示总线空闲状态。此状态下时钟信号SCL和数据信号SDL均为高电 平,此时无I2C设备工作。 - START
表示起始状态。在IDLE状态下,时钟信号SCL继续保持高电平,数据信号SDL出现由高电平转换为低电平的下降沿,此时产生一个起始信号,与总线相连的I2C设备检测到起始信号之后,进入起始状态等待控制字节的输入。 - Read or Write
表示IIC设备读写状态。具体见下文。 - STOP
表示停止状态。完成数据读写后,SCL保持高电平,SDL产生一个由低电平转换为高电平的上升沿信号之后,产生停止信号,总线回到空闲状态。
I2C读写状态时序如下:
SCL为低电平期间,SDA允许数据变换(1代表高电平,0代表低电平)。SCL为高电平期间,SDA数据必须保持稳定,因此一个时钟周期传输1bit数据,每次传输8个bit即一个字节,主机将在最后一个数据时钟末释放SDA总线使从机应答,在传输完1字节数据后的第一个时钟周期SCL为高电平,如果SDA未被检测到低电平,则视为非应答,代表此次数据传输失败。
注意:数据传输是以高位在前,低位在后。
I2C数据读写操作
I2C单字节写步骤如下:
(1)主机产生起始信号并发送到从机,将控制命令写入从机(7位设备地址+1位读写控制命令),读写控制位设置为低电平,表示对从机进行写操作。
(2)从机接收到控制指令后,给与主机一个应答信号ACK,主机接收到ACK应答信号后开始写入寄存器地址,若寄存器地址为16位,则依次写入高8位,产生应答,再写入低8位,产生应答。若寄存器地址为8位,则直接从高位开始写入8位寄存器地址,产生应答。
(3)地址写入完成后,接收到从机应答信号之后,开始单字节数据的写入。
(4)单字节数据写入完成后,接收到从机应答信号之后,向从机发送停止信号,至此单字节数据写入完成。
注意:每次写入1字节数据从机都要产生一个应答信号。
I2C单字节读步骤如下:
(1)主机产生起始信号并发送到从机,将控制命令写入从机(7位设备地址+1位读写控制命令),读写控制位设置为低电平,表示对从机进行写操作。
(2)从机接收到控制指令后,给与主机一个应答信号ACK,主机接收到ACK应答信号后开始写入寄存器地址,若寄存器地址为16位,则依次写入高8位,产生应答,再写入低8位,产生应答。若寄存器地址为8位,则直接从高位开始写入8位寄存器地址,产生应答。
(3)地址写入完成后,接收到从机应答信号之后,主机再次向从机发送一个起始信号。
(4)主机向从机发送控制命令,读写控制位设置为高电平,表示对从机读操作。
(5)主机接收到从机的应答信号后,开始接收从机的单字节数据。
(6)主机接收完成数据之后,主机产生一个时钟周期的高电平无应答信号。
(7)主机向从机发送一个停止信号,至此单字节读操作完成。
注意:随机读操作过程中需要先进行一次写操作,因为我们需要将从机中的地址指针指到我们想要读取的地址,此次写操作也叫哑写、虚写,待从机给与应答信号后,指针指到我们想要读的地址,此时可以进行当前地址读操作了。
随机读与当前地址读的区别:
随机读:可以随机读取从机某地址的数据。
当前地址读:是指在一次读或写操作后发起的读操作,I2C设备在读写操作后,其内部的地址指针自动加1。
I2C页写与单字节写
I2C单字节写与页写的最大的区别:单字节写按照I2C协议每次写入一个字节,产生一个stop信号,页写可以允许写入多个字节数据,但不能超过设备单页包含的最大存储数,写入多个字节后,最终主机发送一个stop信号。
所有的I2C设备都支持单数据写入操作,但只有部分I2C设备支持页写操作。
Repeated Start Condition
A way to claim the bus
During an I2C transfer there is often the need to first send a command and then read back an answer right away. This has to be done without the risk of another (multimaster) device interrupting this atomic operation. The I2C protocol defines a so-called repeated start condition. After having sent the address byte (address and read/write bit) the master may send any number of bytes followed by a stop condition. Instead of sending the stop condition it is also allowed to send another start condition again followed by an address (and of course including a read/write bit) and more data. This is defined recursively allowing any number of start conditions to be sent. The purpose of this is to allow combined write/read operations to one or more devices without releasing the bus and thus with the guarantee that the operation is not interrupted
Regardless of the number of start conditions sent during one transfer the transfer must be ended by exactly one stop condition.
正常来讲:
当我们发送开始命令, 然后发送数据,收到应答,发送数据,收到应答,循环,直到收到停止位,算是通信结束。
这样会产生一个问题:
例如我们读I2C:
读的过程:start信号,从设备地址,写,待读取存储地址,stop。再一个start信号,从设备地址,读,8个时钟,从设备就把对应的数据反馈给处理器。
那么问题是,当我们写stop收到后,再发start读的时候,这个间隙会不会被打断?
有可能的,所以例如读I2C的时候应该这样
读的过程:start信号,从设备地址,写,待读取存储地址,restart,从设备地址,读,8个时钟,从设备就把对应的数据反馈给处理器。
这样就连贯了,是个原子操作了。
参考:https://www.i2c-bus.org/repeated-start-condition/
参考:https://www.ti.com/lit/an/slva704/slva704.pdf
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix