说明:
此文章是在阅读了一些列面试相关资料之后对于一些常见问题的整理,主要针对的是嵌入式软件面试中涉及到的问答,努力精准的抓住重点进行描述。若有不足非常欢迎指出,感谢!在总结过程中有些答案没标记参考来源,若有参考到您的回答请联系我,我会将其补上,最后希望各位都能够找到理想的工作!
I2C具有以下特点(为什么使用I2C):
- 只需要SDA、SCL两条总线;
- 没有严格的波特率要求;
- 所有组件之间都存在简单的主/从关系,连接到总线的每个设备均可通过唯一地址进行软件寻址;
- I2C是真正的多主设备总线,可提供仲裁和冲突检测;
- 最大主设备数:无限制;
I2C通信协议描述:
S:开始(当 SCL 线为高时,SDA 线上出现由高到低的信号,表明总线上产生了起始信号。平时空闲状态时SCL(时钟线) 和 SDA (数据线)都为高电平)
Slave Address:地址信息
R/W:读写位(如果主器件希望将数据发送到节点,则读⁄写位处于低电平。如果主器件请求从节点得到数据,则该位处于高电平。)
A:ACK(接收器【从设备】在接收8位数据【即每个数据帧后】后,在第9个时钟周期拉低SDA)
NA:NOACK(接收器【从设备】在接收8位数据【即每个数据帧后】后,在第9个时钟周期拉高SDA)
PS:A和NA是由从设备发给主设备的
DATA:数据帧(SDA在SCL为低电平的时候变化,SDA在SCL为高电平的时候保持。所以能够理解其实都是在SCL为高电平的时候采集SDA的数据进行记录。)如下图所示:
P:停止位(SDA 线上出现由低到高的信号,表明总线上产生了停止信号)
多想一步:
1.SDA时钟线可由主设备驱动,也可以由从设备驱动。那么万一存在主设备将SDA拉高,从设备将SDA拉低怎么办?
涉及I2C的硬件设计:
SDA的驱动是由DATAN1OUT/DATAN2OUT来控制,以DEVICE1为例:当DATA IN为1时,该设备的SDA=0(因为吸附后接地);当DATA IN为0时,SDA由外部电路(默认上拉电阻)来决定。那么枚举情况就是如下,这就是能够避免电路冲突的原因。
Aout | Bout | SDA |
0 | 0 | 1 |
0 | 1 | 0 |
1 | 0 | 0 |
1 | 1 | 0 |
2. 主从设备驱动如何协调,例如主设备每发送完8个CLK的数据帧之后,从设备怎么知道回复1个CLK的ACK信息?
同样可以从上面的硬件图中得到解答,当8个CLK发送完毕之后,主设备不控制SDA,这时SDA的信号取决于外部电路(若都没有操作默认为高电平)情况,这时候主动权就在接收到数据的从设备手中,他在第9个CLK将SDA信号置为0(置为低电平,这也就是为什么ACK为低电平,NOACK为高电平),而其他从设备不对SDA进行操作。
3.从硬件图中我们看到从设备也可以驱动SCL,这是为什么?SCL不应该是由主设备驱动的嘛
当主设备驱动SCL发送完8个CLK的数据帧之后,也正常收到了从设备的ACK,这时候说明从设备已经正常接收到了主设备的数据。那么从设备可能需要先对这个数据进行处理,希望主设备先不要发送数据。那么这时候从设备就可以主动拉低SCL信号线,根据上述表格我们也可以知道,这样无论主设备的SCL对应的元件如何操作,整个SCL均为低电平。