I2C通信原理是什么?常见问题有哪些

浏览量:12
时间: 2026-08-12 09:57:09
分类:嵌入式单片机经验级别:初级难度:★★☆☆☆题型:原理分析+代码实现

单片机I2C通信波形调试嵌入式开发
I2C是单片机开发中最常用的串行通信协议之一

本文概述

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数据线就能实现多设备通信。它是主从结构,主机产生时钟信号并发起通信,从机通过地址来识别。总线的物理层是开漏输出结构,需要外部上拉电阻,所以多个设备可以挂在同一条总线上,不会出现电平冲突。

第二,关键信号和时序

S

起始信号 Start

当SCL为高电平时,SDA从高电平跳变到低电平,就产生起始信号。起始信号表示一次数据传输的开始,由主机产生。

P

停止信号 Stop

当SCL为高电平时,SDA从低电平跳变到高电平,就产生停止信号。停止信号表示一次数据传输结束,总线回到空闲状态。

A

应答信号 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位地址模式,虽然用得少但要知道

准备动作

  1. 自己写过软件模拟I2C的代码,能背出起始、停止、发字节、收字节的函数结构

  2. 熟悉至少一款单片机的硬件I2C配置方法和常见问题

  3. 了解I2C常见故障排查方法,会用示波器看I2C波形

  4. 知道SPI和I2C的区别,各自的优缺点和适用场景

  5. 准备一个实际项目中使用I2C接口的案例

核心关键词

I2C协议、SCL、SDA、起始信号、停止信号、应答ACK、上拉电阻、开漏输出、主从架构、软件模拟I2C


声明:本网站所收集的部分公开资料来源于互联网,转载的目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。仅供学习交流使用,不构成商业目的。版权归原作者所有,如果您发现网站上有侵犯您的知识产权的作品,请与我们取得联系,我们会及时删除。侵权投诉
相关推荐HOT
开班信息