📘 I²C配置开漏输出和上拉电阻的原因
一、基本背景
I²C(Inter-Integrated Circuit)是一种串行通信总线,由主控器与多个从设备通过两根双向信号线进行通信:
- SCL(Serial Clock Line):时钟线
- SDA(Serial Data Line):数据线
I²C支持多主机与多从机,其通信特点要求任一设备都可以主动控制总线电平。为实现这一功能,需要特定的电气设计:开漏输出(Open-Drain)+上拉电阻(Pull-Up Resistor)。
二、开漏输出(Open-Drain)工作原理
✅ 定义:
开漏输出是指输出端只能拉低电平,不能主动拉高电平,当设备输出逻辑高电平时,实际处于“高阻态”(Hi-Z),不输出任何电平。
✅ 优点:
- 允许多个设备同时连接同一条线,避免信号冲突。
- 通过“线与逻辑”实现多设备仲裁(多个设备同时传输数据时不会造成电平冲突)。
三、为什么需要上拉电阻
由于开漏输出不能主动拉高电平,当总线处于空闲状态或某设备输出逻辑高时,线路会处于高阻态。此时需要上拉电阻将电平拉高至Vcc,从而确保:
- 总线默认处于高电平(空闲状态);
- 当无设备拉低时,信号能恢复高电平;
- 保证逻辑“1”的正常识别。
四、综合机制:I²C总线的电平变化
状态 | SDA/SCL输出配置 | 电平状态 |
---|---|---|
空闲 | 所有设备高阻 | 上拉电阻拉高为高电平 |
数据传输中0 | 某设备输出低电平 | 被拉低为低电平 |
数据传输中1 | 所有设备高阻 | 上拉电阻拉高为高电平 |
五、为什么不能使用推挽输出
推挽输出意味着设备可以主动拉高或拉低电平,但在I²C多主/多从环境中:
- 如果一个设备输出高电平(Vcc),另一个同时输出低电平(GND),会短路烧毁器件;
- 推挽无法实现安全的总线共享,不支持“线与逻辑”。
总结就是防止短路: 在一些情况下(比如总线), 多个GPIO口可能会连接在同一根线上, 存在某个GPIO输出高电平, 另一个GPIO输出低电平的情况. 如果使用推挽输出, 你会发现这个GPIO的VCC和另一个GPIO的GND接在了一起, 也就是短路了(凉凉了). 如果换成开漏输出呢? VCC和GND多了个电阻, 这样电路就是安全的.所以总线一般会使用开漏输出.
六、上拉电阻阻值选择建议
选择上拉电阻时需考虑通信速度、电容负载等:
- 常见值:4.7kΩ(标准模式100kbps),2.2kΩ或更低(高速模式400kbps以上)
- 过大:上升沿太慢,影响通信速率;
- 过小:功耗大,输出驱动负担重。
推荐经验公式:
R_pullup ≤ (Vcc - V_OL) / I_OL
其中:
Vcc
:供电电压V_OL
:低电平最大容许值I_OL
:允许的下拉电流(设备手册中给出)
七、总结
配置项 | 作用与意义 |
---|---|
开漏输出 | 允许多个设备控制总线而无电平冲突,实现总线仲裁 |
上拉电阻 | 提供高电平、确保信号恢复、防止悬空 |
禁用推挽 | 避免同时输出高低电平造成短路 |
I²C的这一设计使其在复杂、多设备通信场景中具备更高的稳定性和可靠性。