第1章 基础知识
1.1 硬件I2C和软件I2C
| 特性 | 硬件 I2C | 软件 I2C |
|---|---|---|
| 实现方式 | 硬件 I2C 是利用 RK3568 芯片内部集成的专用 I2C 控制器电路来实现的。 | 软件 I2C 是在硬件 I2C 资源不足或有特殊需求时,通过软件编程来控制任意两个通用 GPIO 引脚,模拟出 I2C 协议的时序。 |
| CPU 占用 | 低 | 高 |
| 通信速度 | 高 (可达 400Kbit/s 或更高) | 低 (受 CPU 性能限制) |
| 引脚灵活性 | 固定 | 任意选择 |
| 可靠性 | 高 | 受系统负载影响 |
| 资源消耗 | 占用硬件 I2C 控制器 | 占用 CPU 时间 |
1.2 开漏输出 (Open-Drain) ------ "四两拨千斤"
这是 I2C 总线和电平转换电路的灵魂。
- 结构:
- 上管 (P-MOS):彻底断开(或者根本没有)。
- 下管 (N-MOS): 保留,接 GND。
- 工作逻辑:
- 输出低 (0): 下管导通,强力拉低到 GND。
- 输出高 (1): 下管关闭。此时引脚处于 "高阻态 (Hi-Z)" 或 "悬空" 状态。它既不推,也不挽,就像断了线的风筝。
- 如何得到高电平?
- 必须在外部接一个 上拉电阻 (Pull-Up Resistor) 到 VCC。当 N-MOS 关断时,外部电阻把电压"拉"上去。
1.3 为什么 I2C 必须用开漏?
(1) 线与逻辑 (Wired-AND) ------ 硬件实现的仲裁
I2C 总线是多设备共享的。如果设备 A 想发 1,设备 B 想发 0:
- 如果是推挽: A 输出高,B 输出低 -> 短路炸机。
- 如果是开漏:
- A 想要 1 -> A 放手(MOS管关,悬空)。
- B 想要 0 -> B 拉低(MOS管开,接地)。
- 结果: 总线电压被 B 拉低到 0。
- 现象: 只要有一个设备拉低,总线就是低。只有所有设备都放手,电阻才能把总线拉高。
- 意义: 这就是 I2C 的多主仲裁和时钟同步机制的物理基础。
(2)电平匹配 (Level Shifting)
假设 STM32 (3.3V) 要控制一个 5V 的继电器驱动芯片,或者读取 5V 的传感器。
- 推挽不行: STM32 只能输出 3.3V,推不动 5V 逻辑。
- 开漏绝技:
- STM32 设置为开漏输出。
- 上拉电阻接到 5V 电源(前提是该 GPIO 是 FT (Five Volt Tolerant) 兼容 5V 的)。
- 输出 0 时:STM32 拉到 GND。
- 输出 1 时:STM32 放手,外部电阻把电压拉到 5V。完美!
1.4 工程陷阱:上拉电阻选多大?
在 I2C 设计中,电阻 R_pull 的阻值决定了通信质量。
- 电阻太小 (强上拉, 如 1kΩ):
- 优点: 上升沿极快,通信速度快。
- 缺点: 功耗大。输出低电平时,电流 I = VCC / R 很大,不仅费电,还可能超过 N-MOS 的承受能力,导致低电平下不去(比如本来该是 0V,结果变成了 0.4V,超出了 V_IL 阈值)。
- 电阻太大 (弱上拉, 如 100kΩ):
- 优点: 省电。
- 缺点:波形变圆(鲨鱼鳍波形)。
- 原理: 任何引脚和 PCB 走线都有寄生电容 C。充电时间常数 t = R x C。R 越大,充电越慢,上升沿越缓。
- 后果: I2C 数据还没升到高电平,时钟就翻转了,导致通讯误码。
工程经验值:
- I2C 标准模式 (100kHz): 4.7kΩ 或 10kΩ。
- I2C 快速模式 (400kHz): 2.2kΩ。
- I2C 高速模式 (3.4MHz): 不能只靠电阻,需要专用恒流源上拉。