01 IIC
up的视频讲解: https://space.bilibili.com/1455872040
1 ✨IIC简介

IIC(Inter‑Integrated Circuit)全称是集成电路间总线 它主要通过两条线进行通信
- 一条时钟总线
SCL - 一条数据总线
SDA
2 🎏 IIC通信协议
2.1 物理连接

在上节课 我们学习了UART全双工通信的工作方式 而 IIC的收发数据都在一条线上 同一时刻 只能其中一个发送 另一个接收 叫作半双工通信的工作方式
-
这条 传输数据的线 以及对应的端口就叫作
SDA全称是 Serial Data 串行数据 -
半双工通信的优点在于 它能够便捷地实现 一对多的通信
-
可以被多个设备共用的线就叫总线 所以这也是为什么叫IIC叫做集成电路间总线
而全双工通信的方式与之相对 往往实现的是 点对点的通信 因为它需要给每个收发通路一个独立的端口 才能实现同时收发的功能

IIC通信属于串行通信中的 同步通信
-
这条时钟线就叫做
SCL它的全称是Serial Clock串行时钟 -
我们已经知道异步通信是通过提前约定波特率的方式 也就是通过约定时钟频率的方式来同步
-
而同步通信意味着通信双方有一条独立的时钟 通信双方以这条时钟线上的时钟为工作基准 进行同步
-
控制时钟线上时钟的设备 叫作
Master主设备也可以简称主机 -
而其他的设备 则叫作
slave从设备也可以简称从机

IIC通信中 每一个IIC设备的SDA以及SCL端口 都是 开漏输出 的方式
-
这种将
PMOS禁用掉的输出方式 首先就可以避免 一个设备上拉到电源 另一个设备下拉到地 从而短路的情况 -
禁用掉PMOS管后 设备无法主动输出高电平 只能通过NMOS管输出低电平 或者将端口释放
-
所以工程上采用
外接上拉电阻的方式 在设备将端口释放之后 通过上拉电阻来实现高电平
在IIC通信中 这种方式还有其他的优势 当其中一个设备 通过NMOS下拉到地的时候 整条总线就为低电平 当所有设备都将 端口释放的时候 此时外部的 上拉电阻就会将总线上拉至高电平 即 线与 的效果
时钟拉伸 Clock Strech
-
虽然SCL的时钟是由 主设备控制 但是当主设备的时钟来的太快的时候 从设备还没来得把这个数据处理好的时候
-
从设备可以主动将时钟线拉低 主设备没有上拉功能 所以就只能等从设备将时钟线释放之后才能继续发时钟
2.2 电平标准

我们在来看到上拉电阻的电源 这也是开漏数据的另一个好处 通过外接上拉电阻 高电平的电压值就可以由外部自定义 而不是芯片固定的3.3v
-
这个上拉电源的取值也对应着IIC通信协议的电平标准
-
IIC电平标准规定 当电压大于等于 0.7倍的电源电压时 判定为
1 -
当电压小于0.3倍的电源电压时 判定为
0
当这个VCC等于3.3V的时候 我们会发现它是兼容TTL电平标准的
2.3 数据帧

IIC通信的数据帧和UART通信的最大的区别在于 IIC需要通过 两条线的配合 来实现数据的传输
-
当时钟线 为高电平的时候 数据线的一个下降沿就触发
起始信号 -
在时钟线 为高电平的时候 数据线一个上升沿 就触发
停止信号 -
当发出起始信号后 主设备 就开始输出时钟信号 每一个时钟信号就对应着一位
数据固定为 8位 -
第九个时钟的时候 对应的是
应答位ACK也就是设备接收到这8位数据之后 就会主动将数据线拉低 代表着它接收到了

IIC通信中 主机有两种寻址方式 一种 是 7位寻址 另一种 是 10位寻址
-
对于7位寻址而言 起始信号后的第一帧 就是地址 其中 前7位就是对应要寻找的从设备的地址 最后一位 如果是0 就是主设备写 如果是1 就是主设读
-
而10位寻址 就会用到开头的两个数据帧 第一个数据帧前面四个1和一个0是固定的10位寻址的标记
这种方式的优点在于接收方在接收数据的时候
- 移位寄存器是从低位往高位移的 高位先发也就是高位先进移位寄存器
- 当它被移到高位的时候就可以直接读取 而不用进行比特的翻转
3 🌐IIC外设结构

时钟控制器: 就是微控制器作为主设备生成时钟用的
地址寄存器: 和地址比较器 是微控值器作为从设备时用的
Control logic逻辑控制器: 他就是控制SDA与SCL之间的配合 从而生成或者解析IIc的数据帧
CCR: 主要是配置标准模式 和快速模式 的时钟频率
CR1和CR2: 主要是配置 时钟拉伸 ACK应答 以及 是否开启中断等等
3.1 主设备写

当微控制器作为主设备写的时候 它具体是这样
-
CPU将数据写到
DR寄存器之后 DR寄存器就会将数据 拷贝到发送移位寄存器拷贝完成之后将对应标志位置为1 -
然后
逻辑控制器会根据IIC通信协议的规则 首先将数据线拉低 此时时钟线是高电平 从而向从设备发出起始信号 然后将一位寄存器里的数据 每一位对应一个时钟发送出去 -
当发送完8位之后 从设备接收到了 就会将数据线拉低 进行应答 然后主设备就接着发下一帧数据

当微控制器作为主设备读数据的时候
-
此时由从设备 发过来的数据 通过
逻辑控制器解析之后 -
一位一位 存到
接收移位寄存器里面 因为IIC是高位优先 所以第一个接收到的高位数据 被移到最高位的时候 刚好就可以直接拷贝到DR寄存器 -
拷贝完成之后就会将对应标志位置为1 然后CPU就可以对数据进行读取
✅地址与ACK别混在一起
以OLED为例,7位地址0x3C与HAL接口参数0x78描述的是同一个设备:后者是前者左移一位。总线地址字节的最低位用于读写方向,而每个字节之后的第9个时钟用于应答。
开漏只能主动拉低,逻辑高依靠上拉;上拉过弱会使上升沿太慢,过强会增加器件灌电流。不能认为“开了内部上拉就一定能高速通信”。先100 kHz调通,再按器件电气要求提高速度。
读多个字节时,主机通常对中间字节ACK、最后一个字节NACK后STOP。遇到HAL_BUSY先测总线是否被拉低,再查上一次事务是否正常结束,不要无限循环重试掩盖故障。