MCU或者SOC常见驱动1:IIC通信
本文目的
简单的介绍IIC通信一下是什么,有什么用,面试可能会问道的内容
前置知识点
- 基本数电时序电路,寄存器地址知识
- 单片机中断,外设基本知识
相关内容参考《CN_UM_N32G45x Series User Manual V3.1.0.pdf》I2C 接口,p553
I2C 接口简介
I2C 接口通过数据引脚(SDA)和时钟引脚(SCL)连接到 I2C 总线与外部设备进行通信,可以连接到标准 (高达 100kHz)或快速(400kHz)的 I2C 总线。I2C 模块接收时将数据从串行转换成并行,发送时将数据从 并行转换成串行。支持中断模式,用户可以根据需要开启或禁止中断。
主要特性
- 速率:支持标速(最高 100kHz)、快速(最高 400kHz)模式和快速+(最高 1MHz)模式
- 半双工通信
- SDA和SCL均为漏极开路结构,外部上拉电阻实现**“线与”**逻辑(就是一低全低,全高为高),所以线路上不可能出现电平冲突的现象
- 器件地址为10位或者7位,10位地址需要两个字节来进行地址的描述,第一个字节为11110XX+读写位,第二个字节是低八位地址。
- 支持多主机,所以需要时钟同步和仲裁
- 先发高位
通信流程
1 开始和停止条件
- 未通信情况:SCL,SDA均为高
- 通信时候:SCL高的时候SDA不允许转换电平
- 开始信号:SCL高的时候,主机将SDA由高拉低
- 结束信号:SCL高的时候,主机将SDA由低拉高
收发过程中,SCL低的时候才允许SDA的数据变动,SCL高的时候只能读取数据。
2 主机发送过程
- SCL高,SDA拉低开始一次通信
- 读写位0,为主机发从机收。
- 主机发送一个字节(7位地址+1位读写)或者两个字节(10位地址,第1个字节为11110XX+读写位)。
- 主机后续写若干个字节,每八个时钟周期发送一个字节,第九个时钟周期主机SDA释放(会上拉拉高),以接收从机应答,从机需要把SDA拉低应答。
- 所有字节传输结束且接收应答后,下一个时钟周期,SCL高的时候,主机SDA由低拉高,通信结束。
- 其中表示图中的EV指的是在N32单片机中会出现事件,如果开启了中断则会进入中断,便于进一步的进行通信流程。
3 主机接收过程
- SCL高,SDA拉低开始一次通信
- 读写位1,为主机收从机发。
- 发送一个字节(7位地址+1位读写)或者两个字节(10位地址,第1个字节为11110XX+读写位)。
- 后续接收若干个字节,每八个时钟周期接收一个字节,第九个时钟周期从机SDA释放(会上拉拉高),接收主机应答,主机需要把SDA拉低应答,但注意需要在下一个时钟低电平的时候拉回高不然干扰从机发送了。
- 接收最后一个字节的第九个时钟周期主机不发送应答,从机释放SDA。
- 第十个时钟周期,主机在SCL拉高的时候,SDA从低拉高,通信结束。
- 其中表示图中的EV指的是在N32单片机中会出现事件,如果开启了中断则会进入中断,便于进一步的进行通信流程。
4 实际对传感器的写流程
- 执行发送流程,数据方面,第一个字节发送需要写入数据的起始寄存器地址,第二个字节开始是对该寄存器地址开始写若干个字节数据。
5 实际对传感器的读流程
- 先执行发送流程,数据是对应需要读取数据的寄存器起始地址。
- 执行读写流程,读到数据是步骤1中写入的寄存器地址开始的若干个字节数据。
每个字节的第九个时钟周期,接收器发送ACK
时钟同步与仲裁
- IIC总线支持多个主机接入,当多个主机接入的时候可能会出现总线控制冲突,有点类似于data race
- 当两个以上的主机同时发送通信起始信号的时候(在非常多主机的时候真的有可能同时),如何决定那个主机获得控制权,哪个主机没有控制权。
仲裁
- 仲裁的时候先假定多个主机的时钟频率一致,时钟频率的一致性在时钟同步的时候会进行说明。
- 前置知识点:多个主机同时改变总线信号的时候,同时发送1或者0都不会察觉到异常,发送不同信号的时候,发送1的主机由于开漏和下拉电阻的特点,会发现自己发了1,但是总线检测是0。(可以理解为每次信号的发送都会进行信号的检测看看是否是按照自己预期改变了)
- 仲裁过程
多个主机同时发起了开始信号,然后开始发送字节,当字节的每一个位都一致的时候,多个主机可以同时进行通信没什么问题,出现某个位不一致的时候,发送该位为0的主机不会发现异常,而发送该位为1的主机会察觉异常(因为检测到总线为0)退出竞争。
举个例子,主机A发送0b11110111,主机B发送0b11111001,前四个bit都是1,所以两个主机都没有察觉到出现了竞争,第五个位,主机A发送0,总线变成0,主机B发送1但是检测总线是0,主机B退出竞争,主机A接管总线。
时钟同步
上面的仲裁是多主机下的,多主机出现时钟不一致的时候需要进行时钟同步,同样是使用了开漏输入的特点进行同步。
- 主机发起开始信号之后会进行时钟信号的控制。
- 第一个主机拉低时钟之后,总线就会拉低。
- 最后一个主机拉高时钟后,总线就会拉高。
总结
- SCL时钟信号的低电平时间是所有主机的低电平时间最长那个
- SCL时钟信号的高电平时间是所有主机的高电平时间最短那个
错误条件
- 应答错误:从机未应答
- 总线错误:SCL高的时候SDA不允许变化
- 仲裁丢失:在仲裁的时候输了(发了1的)
- 过载/欠载错误:从机需要发送数据的时候,没有数据可发了就是欠载;数据寄存器还未被及时取走的时候又收到新数据,就会过载。
参考文献
《CN_UM_N32G45x Series User Manual V3.1.0.pdf》IIC接口 p553