在电子电路设计中,常常会遇到需要将单线半双工模式的串口转换成双线,以便连接到普通的双线 USB 串口模块,如 CH340 这类常见模块的情况。本文详细介绍了如何使用特定电路实现这一转换,同时深入探讨了在电平不一致时的解决方案,还分享了在 Arduino 上的测试经验以及可能遇到的问题和相应的解决策略。
利用软件模拟串口功能,通过这个电路能进一步减少串口占用的引脚。虽然 ARM 单片机一般具备硬件单线半双工模式,无需折腾软件时序,但软件串口可以在所有 IO 引脚上实现通信,在某些特定场景下具有很大的便利性。
电路原理

电路的连接方式为:左边的RTX连接到单片机的单线串口引脚,右边的TXD和RXD分别连接到另一端的对应引脚。此电路有以下要求:
RXD引脚固定为输入模式,且具备内部上拉。
TXD引脚在空闲时输出高电平。
RTX引脚可选择开漏输出模式,并启用内部上拉;或者在输出和输入模式之间切换,输入模式要有内部上拉。
当RTX端发送数据时,RTX引脚为推挽输出模式,此时 CH340 端的TXD引脚必须保持高电平空闲状态。三极管基极跟随TXD引脚保持高电平。若RTX输出高电平,三极管不会导通,RXD内部上拉为高电平;若RTX输出低电平,三极管导通,RXD被拉低。为避免短路,RTX引脚上串了个限流电阻。
当RTX端接收数据时,RTX引脚设为上拉输入模式。当TXD输出高电平,二极管不导通,RTX保持高电平,RXD也保持高电平;TXD输出低电平,就通过二极管把RTX拉低,此时三极管基极也是低电平,不会导通,所以RXD仍然是高电平,CH340 的输出不会干扰它自身的输入。当RTX是开漏输出模式时,效果相同,只有输出低电平会使三极管导通,且能被TXD拉低。

该电路的逻辑是利用TXD作为控制RXD的使能信号,从而阻止回环;引脚利用内部上拉保持默认状态,输出引脚基本上只负责输出低电平。并且,这个电路以及配套的软件串口代码在 Arduino 上测试完全可行。
电平不一致的情况
然而,当通信双方的信号电平不一致时,情况就变得复杂了。例如,RTX端的单片机是 3.3V 电平,CH340 则是 5V 电平,1.7V 的压差足以导通二极管和三极管,需要重新考虑电路原理。
若RTX为接收状态,TXD通过二极管输出低电平时,情况和之前一样;但TXD输出的 5V 高电平会通过三极管的 BE 节跑到RTX那边去,因为此时RTX电压比较低,三极管导通。一方面,这会让RTX被输入的 5V 电平拉高,不过有 1k + 100 的限流电阻,问题不大,不会冒烟;单片机的 3.3V 电源轨可能会受到干扰,但 5V 经过两个二极管之后就接近 3.3V 了,问题应该也不大。另一方面,此时三极管导通,RXD的电压会被略微拉低,但应该不足以直接拉到低电平。
若RTX为发送状态,输出低电平时情况没有异常,而高电平时,TXD上的 5V 会跑过去,RXD会被三极管略微拉低,总体来说应该是可以兼容的。
针对这种情况,可以把三极管换成 NMOS,比如 SI2300。这样一来,CH340 一侧的 5V 就不会再冲到单片机一侧了。SI2300 的 GS 阈值电压很低,1.7V 就足以导通,所以RXD还是会被拉低到 3.3V,要是换成阈值比较高的 2N7002,基本就没问题了。使用 NMOS 时,1K 限流电阻也可以去掉。

如果单片机是 5V,而 CH340 是 3.3V,这种情况看似更危险,因为RTX的 5V 电平会直接冲到TXD,而串联的限流电阻不能太大,否则波特率就要降低。不过估计 CH340 的引脚是有 5V 耐受能力的。要是上述 “问题不大” 的情况实际不可行,就只能考虑另外附加电平转换电路,这会比较麻烦,不如调整 CH340 这边的供电,让它和单片机那边一致。