文章目录
I2C通信协议简介
I2C 也叫 I²C、IIC (Inter-Integrated Circuit) ,集成电路总线是由 Phiilps 公司开发的两线式串行总线 ,用于连接微控制器及其外围设备,采用同步半双工通信方式,I2C 是带数据应答的协议,支持总线挂载多设备(一般采用 "一主多从" 模型)
两条信号线:
-
SDA(Serial Data,串行数据线)
只有一根 SDA 线 ➡️ 半双工通信方式,一根线兼具发送和接收,最大化利用资源
-
SCL(Serial Clock,串行时钟线)
SCL时钟线 ➡️ I2C 采用同步的时序,降低对硬件的依赖,并且稳定性比异步时序更高
【下面的例子是我从另一个博主:嵌入式逍遥 的文章里看见的,非常nice!!
原文链接:https://blog.csdn.net/Neutionwei/article/details/118653379 】
通过举例进一步理解I2C协议:
如图所示,老师(MCU)将球(数据)传给众多学生中的一个(众多外设设备中的一个)
首先老师将球踢给某学生,即主机发送数据给从机,步骤如下:
① 老师:开始了(start);
② 老师:A!我要发球给你!(地址/方向);
③ 学生A:到!(回应);
④ 老师把球发出去(传输);
⑤ A收到球之后,应该告诉老师一声(回应);
⑥ 老师:结束(停止);
接着老师让学生把球传给自己,即从机发送数据给主机,步骤如下:
① 老师:开始了(start);
② 老师:B!把球发给我!(地址/方向);
③ 学生B:到!
④ B把球发给老师(传输);
⑤ 老师收到球之后,给B说一声,表示收到球了(回应);
⑥ 老师:结束(停止)。
html
从上面的例子可知,都是老师(主机)主导传球,按照规范的流程(通信协议),以保证传球的准确性,
收发球的流程总结如下:
① 老师说开始了,表示开始信号(start)
② 老师提醒某个学生要发球,表示发送地址和方向(address/read/write)
③ 该学生回应老师(ack)
④ 老师发球/接球,表示数据的传输
⑤ 收到球要回应:回应信号(ACK)
⑥ 老师说结束,表示IIC传输结束
以上就是I2C的传输协议,如果是使用IO口来模拟I2C协议,那么就得需要依次实现上述每个步骤
(上面的例子就是采用 "一主多从" 的模型,大部分情况下我们也只使用 "一主多从" 的模型,本文也只介绍 "一主多从" 的模型)
I2C协议硬件规定
-
所有I2C设备的SCL连在一起,SDA连在一起
-
设备的SCL和SDA均要配置成开漏输出模式
可防止总线争用并消除驱动器损坏的机会
因为 I2C 是半双工通信,所以 SDA 既需要在输出和输入之间反复切换,如果总线时序没有协调好,极有可能发生主机和从机的两个 SDA 引脚同时处于输出状态,如果此时又正好是一个输出高电平一个输出低电平那么就会引起电源短路
为了避免由于总线没有协调好而导致电源短路的问题,I2C 禁止所有设备输出强上拉的高电平,采用外置弱上拉电阻加开漏输出电路结构
【这里忘记 开漏输出模式 的,我的另一篇文章 GPIO通用输入输出口 中有介绍】
-
SCL 和 SDA 各添加一个上拉电阻,阻值一般为4.7KΩ左右
当没有设备将其拉低时,可将信号恢复至线路的高电平
I2C协议软件规定
I2C时序基本单元
在 I2C 总线处于空闲状态时,SCL 和 SDA 都处于高电平状态
-
起始条件:SCL高电平期间,SDA从高电平切换到低电平
-
终止条件:SCL高电平期间,SDA从低电平切换到高电平
-
发送一个字节 :SCL低电平期间,主机将数据位依次放到SDA线上(高位先行),然后释放SCL,从机将在SCL高电平期间读取数据位,所以SCL高电平期间SDA不允许有数据变化,依次循环上述过程8次,即可发送一个字节
-
接收一个字节:SCL低电平期间,从机将数据位依次放到SDA线上(高位先行),然后释放SCL,主机将在SCL高电平期间读取数据位,所以SCL高电平期间SDA不允许有数据变化,依次循环上述过程8次,即可接收一个字节(主机在接收之前,需要释放SDA)
-
发送应答:主机在接收完一个字节之后,在下一个时钟发送一位数据,数据0表示应答,数据1表示非应答
-
接收应答:主机在发送完一个字节之后,在下一个时钟接收一位数据,判断从机是否应答,数据0表示应答,数据1表示非应答(主机在接收之前,需要释放SDA)
I2C典型时序
-
指定地址写
对于指定设备(Slave Address),在指定地址(Reg Address)下,写入指定数据(Data)
【分析】
-
当前地址读
-
指定地址读
STM32 专栏文章均参考 《STM32入门教程-2023版 细致讲解 中文字幕》教程视频