I2C是一种两线式串行通信协议,只需要SCL时钟线和SDA数据线两根线,就能实现多个设备之间的通信。核心特点是开漏输出加上拉电阻、主从架构、7位或10位地址、应答机制。常见速率有标准模式100Kbps和快速模式400Kbps,是单片机连接传感器、存储器等外设最常用的接口之一。
I2C只有两根线:SCL时钟线和SDA数据线,都是开漏输出加上拉电阻
主从架构,主机产生时钟发起通信,从机通过地址识别
起始信号SCL高电平时SDA下降沿,停止信号SCL高电平时SDA上升沿
每传完1字节有1位应答,接收方拉低SDA表示收到数据
面试题
请讲一下I2C通信的工作原理,以及实际使用中常见的问题和解决方法。
包括I2C的信号定义、起始停止条件、数据传输过程、应答机制,以及硬件I2C和软件模拟I2C的区别。
面试官考察点
是否真正理解I2C协议的底层信号时序
是否知道上拉电阻的作用和选型方法
是否有实际调试I2C问题的经验
是否了解硬件I2C和软件模拟I2C的优缺点和适用场景
回答思路
第一,I2C的基本特点
I2C是飞利浦推出的两线式串行总线,只需要SCL时钟线和SDA数据线就能实现多设备通信。它是主从结构,主机产生时钟信号并发起通信,从机通过地址来识别。总线的物理层是开漏输出结构,需要外部上拉电阻,所以多个设备可以挂在同一条总线上,不会出现电平冲突。
第二,关键信号和时序
起始信号 Start
当SCL为高电平时,SDA从高电平跳变到低电平,就产生起始信号。起始信号表示一次数据传输的开始,由主机产生。
停止信号 Stop
当SCL为高电平时,SDA从低电平跳变到高电平,就产生停止信号。停止信号表示一次数据传输结束,总线回到空闲状态。
应答信号 ACK
每传输完8位数据后,第9个时钟周期由接收方将SDA拉低,表示应答,说明已经收到数据。如果SDA保持高电平就是非应答NACK。
第三,数据传输过程
一次完整的I2C数据传输过程是:起始信号 → 发送从机地址(7位或10位)+ 读写位 → 等待从机应答 → 传输数据字节(每字节后有应答)→ 停止信号。读操作和写操作的主要区别是地址字节的最低位,0表示写,1表示读。读操作时主机在收到最后一个字节后要发送NACK,告诉从机不再继续读了。
第四,硬件I2C和软件模拟I2C的对比
硬件I2C
优点:速度快,不占用CPU资源,支持更高速率
优点:时序精准,CPU只需要读写寄存器
缺点:引脚固定,不能随便换引脚
缺点:有些单片机硬件I2C有bug,容易卡死
适用:对速率要求高,引脚合适的场景
软件模拟I2C
优点:任何GPIO都可以用,引脚灵活
优点:时序可控,出了问题容易排查
优点:没有硬件bug问题,稳定性好
缺点:占用CPU时间,速率一般不太高
适用:引脚不够用或硬件I2C有缺陷时
第五,常见问题和排查方法
| 问题现象 | 可能原因 | 解决方法 |
|---|---|---|
| 一直收不到应答 | 地址不对或设备没接上 | 检查从机地址,用示波器看SDA波形 |
| 数据时好时坏 | 上拉电阻不合适或干扰大 | 调整上拉电阻值,检查电源和走线 |
| 总线卡死拉低 | 从机一直拉着SDA不放 | 发9个时钟脉冲让从机释放总线 |
| 速率上不去 | 上拉电阻太大或负载电容大 | 减小上拉电阻,缩短走线长度 |
面试官追问
追问1:I2C的上拉电阻怎么选?阻值怎么计算?
上拉电阻的选择要考虑两个边界:最小值由VCC除以输出低电平时的最大灌电流决定,一般3V供电时最小1K左右。最大值由总线上升沿时间要求决定,速率越高最大值越小。经验值的话,标准模式100Kbps一般选4.7K到10K,快速模式400Kbps选1K到4.7K。实际使用中先用4.7K试,波形不好再调整。
追问2:I2C总线上最多能挂多少个设备?
理论上I2C的7位地址可以有127个地址,但实际受两个因素限制:一是地址空间,很多设备地址是固定的,不能冲突;二是总线负载电容,一般总电容不能超过400pF,每个设备引脚和走线都会贡献电容,设备太多总电容就超标了。实际项目中挂七八个设备是比较常见的,再多就要考虑总线电容的问题了。
追问3:I2C时钟拉伸是什么?
时钟拉伸是I2C协议中的一个机制,允许从机在接收到数据后把SCL拉低,让主机等待从机准备好再继续。这样慢速从设备可以控制传输节奏。但实际使用中很多设备并不支持时钟拉伸,软件模拟I2C一般也不实现这个功能。STM32的硬件I2C是支持时钟拉伸的。
追问4:软件模拟I2C的延时怎么确定?
软件模拟I2C的延时决定了总线速率。比如要做100Kbps的I2C,每个时钟周期是10微秒,高低电平各5微秒左右。但要留余量,实际延时可以比理论值大一点。还要注意GPIO翻转的速度,如果CPU主频不高,语句执行本身也要占用时间,实际速率会比计算的慢一些。最好的方法是用示波器测实际波形,根据测量结果调整延时。
失分表达
"I2C是全双工的"——I2C是半双工,收发不能同时进行
"上拉电阻随便接就行"——上拉电阻影响速率和信号质量,需要选型
"应答是主机发的"——应答是接收方发的,取决于谁在接收数据
"地址就是7位"——还有10位地址模式,虽然用得少但要知道
准备动作
自己写过软件模拟I2C的代码,能背出起始、停止、发字节、收字节的函数结构
熟悉至少一款单片机的硬件I2C配置方法和常见问题
了解I2C常见故障排查方法,会用示波器看I2C波形
知道SPI和I2C的区别,各自的优缺点和适用场景
准备一个实际项目中使用I2C接口的案例
核心关键词
I2C协议、SCL、SDA、起始信号、停止信号、应答ACK、上拉电阻、开漏输出、主从架构、软件模拟I2C

扫码关注




























