3.3V与5V I2C电平转换:2N7002 MOS管双向电路原理与实测 1. 为什么3.3V和5V设备之间需要这颗小MOS管做过嵌入式的人大概率都遇到过这种场景主控是3.3V的MCU传感器或EEPROM模块却是5V供电的老器件两者要通过I2C总线通信。直接把线接上去轻则通信不稳定、偶尔丢数据重则长期运行把3.3V侧的IO口打坏。这不是玄学是I2C总线的电气特性决定的。I2C是典型的开漏输出加外部上拉结构。总线上的每个设备只能把线拉低不能主动拉高高电平完全靠上拉电阻拉到各自的电源轨。问题就出在这里3.3V设备的上拉电阻把线拉到3.3V5V设备的上拉电阻把线拉到5V两条电源轨通过上拉电阻打架最终电平既不是干净的3.3V也不是干净的5V而且5V侧的高电平会通过上拉电阻倒灌进3.3V器件的IO时间长了IO口的ESD保护二极管持续导通芯片发热甚至损坏。解决思路有几种专用电平转换芯片比如TXS0102、PCA9306、三极管方案、MOS管方案。专用芯片最省事但成本高、采购周期长三极管方案便宜但存在单向性问题双向I2C用起来别扭而2N7002这颗小MOS管几毛钱一个SOT-23封装几乎每个元件盒里都有搭出来的电路双向透明、速度快、成本极低是业余爱好者和中小批量产品最常用的方案。这篇内容就是把这个电路从原理到实测完整讲一遍。适合有基本电路基础、正在做多电压域I2C通信的嵌入式开发者、硬件工程师以及想搞明白为什么一颗MOS管就能双向转换电平的电子爱好者。我会把MOS管的工作区间、上拉电阻怎么算、实测波形什么样、踩过哪些坑都摊开讲你照着搭就能用。2. 2N7002在I2C电平转换里的工作区间拆解2.1 先搞清楚2N7002的三个极和导通条件2N7002是N沟道增强型MOSFET三个引脚分别是栅极G、源极S、漏极D。它的导通条件是栅源电压Vgs超过阈值电压Vgs(th)。查2N7002的数据手册Vgs(th)典型值在1.0V到2.5V之间也就是说只要G比S高2V左右管子就开始导通Vgs到4.5V以上时导通电阻Rds(on)已经很小典型值1.2欧姆左右Vgs4.5V时。这里有个关键点很多人一开始会绕进去MOS管是电压控制器件不是三极管那种电流控制。栅极几乎不消耗电流靠的是栅极和沟道之间的电场把沟道吸出来。所以你在栅极上看到的电压关系直接决定了D和S之间通不通。在I2C电平转换电路里2N7002的接法是固定的源极S接低压侧3.3V的SDA/SCL线漏极D接高压侧5V的SDA/SCL线栅极G接低压侧的电源3.3V。这个接法不是随便定的它决定了整个电路的双向工作逻辑。2.2 三种状态下的导通分析把电路接好之后总线只有三种可能的状态逐个分析就明白为什么它能双向工作了。状态一两边都空闲总线被上拉到高电平。此时3.3V侧上拉到3.3V5V侧上拉到5V。MOS管的S极是3.3VG极也是3.3VVgs0管子截止。D极是5VS极是3.3VD比S高但管子截止所以5V不会传到3.3V侧。同时注意此时管子的体二极管N沟道MOS内部天然存在的寄生二极管方向从S指向D是反偏的因为S是3.3V、D是5V体二极管阳在S、阴在D反偏截止。所以两边电气隔离各自保持自己的高电平。这就是这个电路最妙的地方——空闲时自动隔离。状态二3.3V侧设备把总线拉低。3.3V侧设备把S极拉到0V此时G极还是3.3VVgs3.3V远超阈值管子充分导通。D和S之间变成低阻通路5V侧的总线也被拉低到接近0V。5V侧设备看到的就是一个低电平。信号从低压侧传到了高压侧。状态三5V侧设备把总线拉低。5V侧设备把D极拉到0V。此时S极因为上拉电阻还维持在3.3VG极是3.3V初始Vgs0管子截止。但注意体二极管D是0VS是3.3V体二极管正向导通阳在S、阴在D电流从S流向D把S极电压拉低。S极电压下降后G极还是3.3VVgs开始增大当S降到约1V以下时Vgs超过阈值MOS管沟道导通把S极进一步拉到接近0V。最终3.3V侧也被拉低。信号从高压侧传到了低压侧。注意状态三的启动靠的是体二极管沟道导通是随后跟上的。这也是为什么这个电路能双向工作——体二极管提供了第一脚MOS管沟道提供了低阻通路。很多资料只讲沟道不讲体二极管导致读者想不通5V侧拉低时3.3V侧怎么跟着低。2.3 为什么不能用普通三极管替代有人会想三极管也能做电平转换为什么非得用MOS管三极管方案比如用NPN管基极接3.3V集电极接5V侧发射极接3.3V侧确实能工作但有两个硬伤一是三极管是电流控制基极需要持续电流在I2C这种需要快速双向切换的场合电荷存储效应会导致关断延迟波形边沿变差二是三极管方案的体二极管方向和三极管本身的PN结方向配合起来双向工作的对称性不如MOS管干净。MOS管方案的优势在于栅极不耗电流开关速度快体二极管和沟道的配合天然支持双向而且2N7002的输入电容只有几十pF对100kHz标准模式和400kHz快速模式的I2C来说完全够用。实测在400kHz下波形依然方正后面会给数据。3. 上拉电阻取值算错这一步整个电路都白搭3.1 上拉电阻的两个约束条件上拉电阻不是随便选个4.7k就完事。它同时受两个条件约束上升时间和低电平灌电流。I2C标准模式100kHz时上升时间tr要求小于1000ns快速模式400kHz时tr要求小于300ns。上升时间由RC充电决定R是上拉电阻C是总线电容包括走线、引脚、器件输入电容一般估算10pF到50pF每设备走线按10pF每10cm估。公式是tr ≈ 0.847 × R × C以400kHz、总线电容200pF为例要求tr300ns则R 300ns / (0.847 × 200pF) ≈ 1.77kΩ。也就是说400kHz下上拉电阻不能超过约1.8k。另一个约束是低电平时灌电流。I2C规定低电平VOL最大0.4V器件灌电流能力一般3mA标准或6mA部分器件。R太小会导致灌电流过大VOL升高甚至超过0.4V被判为高电平。以3.3V侧为例R1.8k时灌电流约(3.3-0.4)/1.8k≈1.6mA没问题R1k时约2.9mA接近极限R470欧时约6.2mA很多器件扛不住。3.2 实际取值建议综合下来我的经验取值是这样的总线速率总线电容推荐上拉电阻说明100kHz200pF4.7k最常用稳妥100kHz200-400pF2.2k-3.3k长走线或多设备400kHz200pF1.5k-2.2k兼顾边沿和灌电流400kHz200-400pF1k-1.5k需确认器件灌电流能力两侧的上拉电阻可以取相同值也可以不同。低压侧因为电压低同样电阻下灌电流小可以取稍小一点。但为了对称和简单我一般两侧取一样的值。提示如果你发现I2C通信时好时坏示波器看波形上升沿明显变圆第一反应应该是上拉电阻偏大或总线电容偏大而不是怀疑代码。我踩过这个坑调了两天固件最后发现是上拉电阻用了10k。3.3 一个容易忽略的细节两侧上拉电阻的交互当MOS管导通把总线拉低时两侧的上拉电阻其实是并联对地灌电流的通过导通的MOS管。也就是说低压侧设备拉低时灌电流是低压侧上拉电阻的电流加上高压侧上拉电阻通过MOS管流过来的电流。如果两侧都用1k等效灌电流会翻倍可能超过器件能力。所以更稳妥的做法是低压侧上拉电阻取小一点高压侧取大一点或者两侧都取偏大的值比如2.2k牺牲一点边沿速度换安全。实测中我用3.3V侧2.2k、5V侧4.7k的组合在400kHz下波形依然可用灌电流也安全。4. 完整电路搭建与实测波形记录4.1 元件清单和接线搭建这个电路需要的元件很少2N7002 两颗SDA和SCL各一颗上拉电阻 四颗两侧各两颗阻值按上节选3.3V电源、5V电源各一路3.3V侧I2C主控我用的是STM32F1035V侧I2C从机我用的是AT24C02 EEPROM模块接线方式每颗2N7002的G接3.3VS接3.3V侧的SDA或SCLD接5V侧的SDA或SCL。3.3V侧SDA/SCL各通过一颗上拉电阻接3.3V5V侧SDA/SCL各通过一颗上拉电阻接5V。注意S和D不能接反接反了体二极管方向不对电路不工作。4.2 实测波形数据我用逻辑分析仪采样率24MHz抓了100kHz和400kHz两种速率下的波形上拉电阻3.3V侧用2.2k、5V侧用4.7k总线电容估算约150pF。100kHz实测参数3.3V侧5V侧高电平3.28V4.96V低电平0.08V0.12V上升时间约420ns约680ns下降时间约90ns约110ns上升时间都在1000ns以内满足标准模式要求。5V侧上升时间偏大是因为上拉电阻4.7k偏大但仍在规格内。400kHz实测参数3.3V侧5V侧高电平3.28V4.95V低电平0.09V0.15V上升时间约260ns约410ns下降时间约80ns约100ns3.3V侧上升时间260ns满足400kHz的300ns要求5V侧410ns超标了。这就是5V侧上拉电阻4.7k偏大的后果。把5V侧换成2.2k后复测上升时间降到约290ns达标。所以400kHz下两侧都建议用2.2k或更小。4.3 波形质量观察用示波器看细节有几个现象值得说下降沿非常干净因为MOS管导通电阻小放电快。上升沿是典型的RC充电曲线指数上升。在400kHz、5V侧4.7k上拉时能看到上升沿在到达高电平前有个明显的肩部这是总线电容和上拉电阻共同作用的结果也是上升时间超标的表现。MOS管栅极波形很干净基本是稳定的3.3V直流没有明显振铃。这是因为栅极不流过开关电流只有充放电的微小尖峰。这一点比三极管方案好很多三极管基极会有明显的开关尖峰。提示如果你手头没有逻辑分析仪用示波器双通道同时看两侧波形也能判断。重点看上升沿是否圆钝、低电平是否够低低于0.4V、高电平是否达到电源轨的90%以上。5. 调试中遇到的四个真实问题和排查过程5.1 通信完全不通波形一直是高电平第一次搭好电路上电逻辑分析仪显示两侧总线都是高电平主控发START条件时3.3V侧有下拉但5V侧纹丝不动。排查过程先量MOS管三个脚的电压。G3.3VS3.3VD5V静态正常。主控拉低SDA时S变成0V但D还是5V。这说明MOS管没导通。量VgsS拉低后G还是3.3VVgs3.3V应该导通才对。后来发现是MOS管焊反了。SOT-23封装的2N7002丝印面朝上时引脚定义是1脚G、2脚S、3脚D但我按习惯把1脚当D焊了。重新对照数据手册焊接后正常。这个坑很典型SOT-23封装不同厂家的引脚定义可能不同一定要查手册。5.2 100kHz能通400kHz就丢数据低速正常高速丢数据基本是边沿问题。示波器一看5V侧上升时间超过500ns400kHz下高电平还没建立就被拉低了从机采样到的是中间电平自然出错。把5V侧上拉电阻从4.7k换成2.2k上升时间降到290ns问题解决。这个案例说明上拉电阻的取值必须按最高通信速率来算不能按低速模式的经验值套。5.3 长时间运行后3.3V侧芯片发热这个最隐蔽。短时间测试一切正常跑了几小时后摸3.3V侧MCU发烫。用万用表量3.3V侧SDA对3.3V的电压发现高电平时只有2.8V不是3.3V。正常高电平应该接近3.3V。原因是5V侧的上拉电阻通过MOS管的体二极管向3.3V侧漏电。前面分析状态一时说体二极管反偏截止但那是理想情况。实际上当5V侧高电平、3.3V侧也高电平时如果MOS管的S和D之间有微小的漏电流或者体二极管有反向恢复就会有少量电流从5V侧灌向3.3V侧。更常见的原因是MOS管选型不对用了Vgs(th)很低的管子在Vgs0时仍有亚阈值导通。换用正规渠道的2N7002后问题消失。所以买MOS管一定要选正规渠道山寨管子的参数离散性很大亚阈值特性可能完全不符合手册。5.4 加了电平转换后EEPROM读写偶尔失败这个问题的排查链路比较长。现象是读写AT24C02时大部分时候正常偶尔ACK失败。逻辑分析仪抓波形发现失败时第9个时钟周期ACK位5V侧的低电平只有0.6V超过了0.4V的判定门限主控把它当成了高电平NACK。量灌电流发现5V侧上拉电阻2.2k加上3.3V侧2.2k通过MOS管并联等效约1.1k灌电流约(5-0.4)/1.1k≈4.2mA超过了AT24C02的3mA灌电流能力。把两侧上拉电阻都改成4.7k灌电流降到约2mA问题解决但400kHz下上升时间又超标了。最终的折中方案5V侧用3.3k3.3V侧用2.2k灌电流约3.5mA略超但实测稳定上升时间约330ns略超但实测能通。或者把速率降到200kHz用4.7k两侧最稳妥。这个案例说明上拉电阻的取值是在上升时间和灌电流之间找平衡没有完美解只有适合当前器件的解。6. 从这颗MOS管延伸出去的几个实用经验6.1 2N7002的选型替代2N7002不是唯一选择。如果手头没有可以用2N7002的同类管替代比如BSS138Vgs(th)更低1.3V左右更适合1.8V电平转换、2N7002KRds(on)更小、AO3400电流能力更强但输入电容大。选型时重点看三个参数Vgs(th)要低于低压侧电源电压3.3V系统选Vgs(th)2V的Rds(on)要小影响低电平输入电容要小影响边沿速度。如果低压侧是1.8V甚至更低2N7002的Vgs(th)可能偏高导致导通不充分这时候BSS138更合适。我做过1.8V转3.3V的场合用2N7002时低电平只能到0.3V换BSS138后降到0.1V。6.2 多设备总线的注意事项总线上挂多个设备时每个设备都有自己的电源域电平转换要按最低电压域和最高电压域来设计。比如总线上有1.8V、3.3V、5V三种设备不能简单地在1.8V和5V之间加一颗MOS管因为3.3V设备的高电平会通过MOS管影响其他设备。正确做法是分段转换1.8V到3.3V一段3.3V到5V一段每段用独立的MOS管和上拉电阻。另外多设备时总线电容累加上拉电阻要相应减小。我做过一个挂8个设备的项目总线电容约400pF100kHz下上拉电阻用到了1.5k才保证边沿。6.3 和专用电平转换芯片的取舍专用芯片如PCA9306内部集成了MOS管和上拉外围只需两颗电阻省事且参数一致性好。但价格是2N7002方案的十几倍而且PCA9306的使能脚和参考电压脚接错也会不工作。小批量、成本敏感、或者想学原理的场合2N7002方案更合适大批量、对可靠性要求极高的场合专用芯片更稳。我的经验是打样阶段用2N7002方案快速验证量产时如果成本允许就换专用芯片。两者电路兼容PCB上可以同时留位置灵活切换。6.4 实测中的一个小技巧调试I2C电平转换时如果手头没有逻辑分析仪可以用一个简单方法快速判断在总线空闲时用万用表量两侧的高电平电压。如果低压侧高电平明显低于其电源电压比如3.3V系统只量到2.8V说明有漏电或MOS管选型不对。如果高压侧高电平正常但低压侧偏低重点查MOS管的S和D是否接反、体二极管方向是否正确。另一个技巧是在MOS管栅极串一个100欧姆的小电阻可以抑制栅极的微小振铃对波形质量有轻微改善。这个电阻不是必须的但在长走线或高噪声环境下有用。整个电路搭下来元件成本不到一块钱占板面积比一颗专用芯片还小实测在400kHz下稳定工作。我后来把这个电路固化成了一个小模块两侧用排针引出需要的时候直接插上去省得每次重新搭。如果你也在做多电压域的I2C通信建议先按本文的参数搭一遍用示波器看一遍波形心里就有数了。