I2C通信协议学习笔记

基于STM32F407ZGT6实现,个人总结记录使用。

1. 概述

  I2C(Inter-Integrated Circuit,内部集成电路)总线是由PHILIPS公司开发的两线式串行通讯总线,由数据线SDA和时钟SCL构成的。I2C总线支持任何IC,每个器件有唯一的地址识别,可作为一个发送器或一个接收器,实现CPU与被控IC之间、IC与IC之间的双向传送。高速I2C总线一般可以达到400kbps以上。

  I2C总线在传送数据过程中共有三种类型的信号,分别是:开始信号结束信号应答信号

  开始信号:SCL为高电平时,SDA由高电平向低电平跳变,开始传送数据;

  结束信号:SCL为高电平时,SDA由低电平向高电平跳变,结束传送数据;

  应答信号:接收数据的IC在接收到8bit数据后,向发送数据的IC发出特定的低电平脉冲,表示已收到数据。CPU向受控单元发出一个信号后,等待受控单元发出一个应答信号,CPU接收到应答信号后,根据实际情况作出是否继续传递信号的判断;若CPU未收到应答信号,判断售空单元出现故障;

  起始信号是必需的,而结束信号和应答信号是不强制要求的。

  由开发板资料了解到,ST为规避PHILIPS公司I2C专利问题,故STM32的硬件I2C设计的复杂、稳定性差。用软件模拟I2C的方式,可移植性好。

2. I2C总线通信方式

  • (显然)I2C是半双工的通讯方式;

  • 7位地址:固定地址(4bit)+ 可编程地址(3bit)+ 读写状态(1bit,0 - 读,1 - 写);

    请添加图片描述

  • 8位地址:所谓8bit地址,就是厂商把地址分为了写地址和读地址,原理与7位地址相同;

I2C通信协议学习笔记_第1张图片

  • 10位地址:10bit寻址和7bit寻址是兼容的,我的理解是,在7位地址的基础上拓展地址位数,增加I2C总线上可挂载的IC设备数量;

请添加图片描述

  • 保留地址:
从机地址+R/W 描述
0000 0000 呼叫地址
0000 0001 起始字节
0000 001X CBUS地址
0000 010X 保留供不同的总线格式
0000 011X 保留将来用
0000 1XXX HS模式主机码
1111 0XXX 10位从机地址
1111 1XXX 保留将来用

3. I2C的模式配置

  • 引脚配置:

    • SCL、SDA可以配置为推挽输出、开漏输出(上拉);
    • SCL、SDA可以配置为开漏输出、开漏输出(开漏输出可以防止多个期间存在短路,必须内部上拉(软件上拉)或外接上拉);
    • SCL、SDA可以配置为推挽输出、推挽输出与浮空输入(切换模式)
    • (关于上述引脚配置,我的理解是,若只有一个I2C的主机设备,使用推挽输出+推挽输出即可;若有多个I2C的主机设备,应至少将SDA配置为开漏输出,原因附在下一点结尾)
  • 开漏输出的作用、线与

    • 防止短路:在某些情况下,多个GPIO口可能会连接在同一根线上,存在某个GPIO输出高电平,另一个GPIO输出低电平的情况;如果使用推挽输出,你会使得这个GPIO口的VCC和另个一个GPIO的GND连接在一起,也就形成短路;换成开漏输出,VCC和GND之间会多一个电阻,故总线一般会使用开漏输出;

    • 实现线与:根据《STM32F4xx中文参考手册》7.3.10-输出配置一节,将I/O端口进行编程作为输出时,开漏模式与推挽模式的区别在于,前者输出“1”呈高阻态不激活P-MOS,后者输出“1”可激活P-MOS呈高电平(VDD)。但参考手册中的图片并没有将输出驱动器的逻辑图画明白,这里我找到了野火有关GPIO工作原理的视频中用到的图片,将下图替换掉参考手册中输出驱动器的示意部分更好理解。

      I2C通信协议学习笔记_第2张图片

      推挽输出模式:是根据两个MOS管的工作方式命名。在该结构中输入高电平时,经反向器变为低电平,Ug = 0,满足上房PMOS管的导通条件(Ug < Us = VDD,下方NMOS仍处于截止状态(Ug = Us = VSS),故对外输出高电平;反之,在该结构中输入低电平时,经反向器变为高电平,Ug = 1,满足下方NMOS管的导通条件(Ug > Us),上房PMOS管仍处于截止状态(Ug = Us),故对外输出低电平。当引脚高低电平切换时,两个MOS管轮流导通,PMOS负责灌电流,NMOS管负责拉电流,使此电路结构的负载能力和开关速度相比普通方式下有很大的提升。

      I2C通信协议学习笔记_第3张图片

      开漏输出模式:PMOS管完全不工作,若在该结构输入高电平时,经反向器变为低电平,Ug = 0,PMOS管关闭,NMOS管处于截止状态,输出呈高阻态;若在该结构输入低电平时,经反相器变为高电平,Ug = 1,PMOS管关闭,NMOS管导通,使输出接地,呈低电平输出。

    I2C通信协议学习笔记_第4张图片

    因此,当多个开漏输出模式引脚连接在一起时,只有当所有引脚都呈高阻态,才由上拉电阻提供高电平;若其中有一个引脚为低电平,那么整条线路上的引脚都为低电平。即**“线与”特性**;我的理解是,开漏输出模式更适合I2C总线上有多个主机设备的情况,因为主机设备要发送数据时要先将SDA拉高后再拉低,作为数据发送开始信号。而此时,若有其他主机设备的SDA处于低电平,那么此时由于“线与”特性使得该主机设备无法将SDA拉高,即有其他主机正在占用SDA数据线,暂时无法抢占。需要等到已占用的主机设备发送数据完成后,将SDA信号设置为高阻态后才可进行。

  • I2C 三种模式,根据SCL与SDA保持时间长度所决定的。例如:标准模式下SCL高电平保持时间最小为4.7μs,快速模式下要求SCL高电平保持时间最小为0.7μs。

标准模式/S 快速模式/F 高速模式
速率 100KHz 400KHz 3.4MHz
数据保持时间 0.9us 72/150ns
器件寻址 7bit 7bit/10bit 7bit/10bit

4. 时序分析

I2C通信协议学习笔记_第5张图片

以软件模拟推挽输出,100KHz为例;

参数 含义 最小值 最大值
tR SCL/SDA上升时间 - 1μs
tF SCL/SDA下降时间 - 300ns
tHIGH SCL高电平脉冲宽度(保持时间) 4.0μs -
tLOW SCL低电平脉冲宽度(保持时间) 4.7μs -
tSU:STA 开始信号初始部分SCL高电平最小保持时间(建立时间) 4.7μs -
tHD:STA 开始信号SDA跳变后到SCL第一个下降沿(保持时间) 4.0μs -
tSU:DAT 数据信号建立时间 250ns -
tHD:DAT 数据信号保持时间 0 3.45μs
tSU:STO 结束信号初始部分SCL高电平最小保持时间 4.0μs -
tBUF 总线最小空闲间隔 4.7μs -
fSCL 时钟频率 - 100kHz
  • 开始信号:SCL - 高电平,SDA 由高→低跳变;tSU:STA,tHD:STA

  • 结束信号:SCL - 高电平,SDA 由低→高跳变;tSU:STO,tBUF

  • 应答信号:SCL - 高电平,SDA - 低电平,且SCL高电平保持时间 ≤ SDA低电平保持时间;

  • 非应答信号:SCL - 高电平,SDA - 高电平,且SCL高电平保持时间 ≤ SDA高电平保持时间;

  • 检测应答信号:在SCL为高电平的时候读取SDA的状态,SDA此时为输入模式,0 - 应答,1 - 非应答;在SCL为低电平时,允许数据发生变化;SDA为高电平时可以占用总线,再将SDA拉低,开始通信;若SDA为低电平时,说明SDA已经被占用;SCL为高电平时,要求数据稳定;SCL为低电平时,允许数据改变;

  • 发送一个字节数据:SDA转为推挽输出模式或开漏输出模式,SCL为高电平时,要求数据稳定;SCL为低电平时,允许数据改变;

  • 接收一个字节数据:SDA转为输入模式,SCL - 高电平,读取数据;

5. 代码实现

暂略

6. 其他

  • I2C的上拉电阻一般选用4.7k~10kΩ之间;
  • I2C协议没有规定总线上设备最大数目,但规定了总线电容不能超过400pF;所以实际应用时,因管脚、PCB都会存在电容,一般只能挂载4~8个器件;

7. 参考的资料来源

  • 常用通信协议——IIC详解(全网最全)_阿波罗啦啦啦啦的博客-CSDN博客_iic
  • [IIC总线解析_DingUXiu的博客-CSDN博客_iic总线](https://blog.csdn.net/jjc_c/article/details/107550341)(读写过程,后续补)
  • STM32----IIC详解_冷瑾瑜的博客-CSDN博客_stm32iic
  • IIC总线–基础知识及应用_机器人107的博客-CSDN博客
    .net/qq_45604814/article/details/116099878)
  • IIC总线–基础知识及应用_机器人107的博客-CSDN博客
  • 野火F407开发板-霸天虎视频-【入门篇】_哔哩哔哩_bilibili

你可能感兴趣的:(STM32,记录,stm32,嵌入式)