短文标题: 开漏输出:只拉低不推高,上拉电阻是灵魂

你有没有想过一个问题:I2C总线上多个设备的SDA引脚连在一起,为什么不会短路?因为它们用的是开漏输出 ,不是推挽。谁都能拉低,但谁也不主动推高。大家都"放手"时,总线被上拉电阻拉到高电平。开漏输出只拉低不推高,上拉电阻决定高电平------这是它"合群"的根本原因。开漏输出的内部结构 ,内部只有一个接地的NMOS管:
- 输出低电平:MOS管导通,引脚拉到0V(吸收电流)
- 输出高电平:MOS管关断,引脚悬空------必须靠外部上拉电阻提供高电平
**没有上拉电阻,开漏输出等于"没输出"------引脚浮空,电平不确定。上拉电阻阻值怎么选?**上拉电阻是三要素的平衡:
- 阻值越小:上升沿越陡(速度快),但低电平时功耗越大(I = VCC / R_pullup)
- 阻值越大:功耗越低,但上升沿变缓(RC时间常数大)

I2C规范推荐:400kHz用1.5~2kΩ,100kHz用4.7~10kΩ。 阻值选取还要考虑总线电容------导线越长、设备越多,总电容越大,需更小上拉电阻保证上升时间。开漏的三个经典应用
1. 线与逻辑(多设备共享总线),多个开漏输出接在同一条线上:任何一个拉低→总线低;全部"放手"→上拉电阻拉高。I2C、1-Wire都基于此原理。
2. 电平转换(3.3V ↔ 5V),上拉电阻接5V,3.3V单片机开漏输出即可驱动5V设备。电平由上拉电压决定,适配灵活。双向通信配合MOS管和体二极管(教程3.5节)。
3. 适应不同电压的外设,同一I2C总线上不同设备工作电压不同,上拉电阻接最低的VDD(如3.3V),确保所有设备不超压。

**STM32内部上拉电阻,**STM32内部有约40kΩ上拉电阻,通过GPIOx_ODR寄存器控制:
GPIOA->CRL |= (0x08 << 0); // 上拉/下拉输入模式
GPIOA->ODR |= (1 << 0); // 使能内部上拉
内部上拉驱动弱(上升沿慢,几百kHz内),适合按键输入、低速信号。I2C等高速通信仍需外部上拉。开漏与推挽对比
这个故事的启示, 开漏输出不强,但"合群":不争不抢(不主动推高)才能协作(线与);不强求电压(靠外部电阻决定)才能适应不同电平标准。上拉电阻是开漏的灵魂,没它就"飘"了。
写在最后, I2C总线用开漏,不是因为它强,是因为它"合群"。选好上拉电阻,速度和功耗兼得。开漏+上拉=共享总线的黄金搭档。
(本文灵感源于于振南《新概念ARM32单片机》教程第3.4节、第3.6节。)
觉得有用?点赞、转发,让更多人看懂"开漏+上拉"的总线共享智慧。
