从电源角度分析设计UART串口的引出方法

从电源角度分析设计UART串口的引出方法

前言

前段时间设计了一个电路板,主控是一片ESP32-WROOM-E,板子上面集成了使用CH340做的USB转串口通信功能,以方便电脑连接。但是工作状况稍微有些复杂,其中有的时候会出现CH340由USB供电了,但是ESP32没有上电的情况,在这种情况下,发现ESP32的3V3电源输入引脚本应是0V电压没有输入,却惊人的出现了1V以上的电压。后经过与FY的协同排查,认定是一起由于串口没有进行认真设计导致的典型的IO灌电流缺陷。

虽然这没有给ESP32的工作带来影响,但是极有可能是导致我的外围模拟电路设计失效的罪魁祸首(未验证)。但是据说当同样的case出现在STC51上时就会导致严重的问题,因为STC51只有当芯片完全断电之后才能够完成重置,而串口漏过来的电流会阻止STC51进行重置。

复习串口知识

在电路设计时,串口由于过于简单而经常被忽略掉其真实的运作原理。因为一般连上线就能跑所以能跑就行,就会在复杂的case中出现奇怪的问题。

首先,一个设备的串口外设最少具有两根线,一根TX,一根RX。

对于RX线来说,是负责收数据的一方,因此它的IO状态会被配置为高阻抗、输入,来采样信号线上的电平状态。

对于TX线来说,是负责发数据的一方,因此它需要操作信号线的电平状态,通常绝大多数时候都是以推挽(Push-Pull)模式工作。部分设备支持配置成类似I2C的开漏(Open-Drain)模式。

UART以高电平作为静默状态。RX引脚当高电平被拉低时尝试读取数据;TX引脚首先拉低电平然后再发送数据。

开漏工作

UART一般不会配置在开漏模式。

开漏时,IO口与VCC之间接了个电阻(几k到几百k都有可能),并且IO与GND之间有一个MOS管或三极管。(反过来和GND之间有电阻,和VCC之间有晶体管的也是可以的)。当这个管子关闭时,从VCC流到IO口的电流无法到达GND,因此IO就能够输出高电平。但因为这个高电平是VCC走了一个大电阻过来的,所以它没有多少电流,甚至无法点亮一个led,只能说是意思意思这里有点电压。所谓没有驱动能力。

而当打开这个管子时,从VCC过了个电阻之后那点微弱的电流被立马释放去了GND,因而IO口就会显示出低电平来。此时如果信号线上有别的电源,那么这个电源的电流也会从打开的管子这里释放去GND,在外部电源的帮助下是可以实现较大的电流流过的,因而具有驱动能力。

开漏时只有一个状态能够通过大电流,从而带动负载。

推挽工作

在以推挽模式工作,输出高电平时,IO口可以看作会打开这个IO口与VCC之间的MOS管,VCC的电压电流就会顺着MOS管到IO引脚上,推动信号线后的负载。而在输出低电平时,则会关闭与VCC之间的MOS管,转而打开IO与GND之间的MOS管,如果信号线上有电压,就会被拉进IO口里,排到GND去。

推挽状态下,只要IO口后面的MOS管在VCC电压下所能推出去的电流比信号线消耗的电流大,那么整条信号线就会处在高电平。同样地,如果MOS管能够拉完数据线上的所有电流,那么数据线就会变成低电平。

因而,推挽时无论是高电平还是低电平,都有足够的驱动能力,可以流出或流入电流。这种对称的驱动能力也使得串口这种简单粗暴的外设可以工作在较高的波特率下。

分析BUG原因

通过实验对比,可以确定CH340G这片芯片的串口线是工作在推挽模式,这也是出现BUG的前提条件之一。

出现BUG时,ESP32没有电源供应,处于没有开机的状态,此时的IO引脚在什么模式不得而知(懒得考究)。这就意味着关机的ESP32的IO脚可能和GND之间能跑电流,也可能和VCC之间能跑电流,也可能都不通。但是因为出现了这个BUG,那么基本可以认定,关机时ESP32的IO引脚和VCC之间的是可以跑电流的。

那么是哪一根信号线上在从CH340向ESP32跑电流?

首先排除CH340的RX线。这根线在高阻态,压根就没电。那么只能是CH340的TX线,工作在推挽状态,输出着串口的默认状态,即高电平。电流从CH340的TX脚沿着数据线流向来ESP32的IO口,IO口又把电流漏给了ESP32的VCC,从而测得ESP32的电源引脚上出现了不该有的电压。

当ESP32正常运转时,ESP32的RX脚会被配置到高阻态输入,从而失去驱动能力,不会把电流从IO口漏到GND去。会不会漏到VCC去?不知道,但是只要VCC电压比信号线电压高或者等于,就不会。IO口设计时就是不能过压的。

为什么不讨论ESP32的RX还是TX?

ESP32压根就没开机,对于ESP32来说,(基本上)所有IO口的结构都是一样的(除开几个只支持输入的IO)。对于不同单片机有不同的case。

为什么测得的电压不是3V3,只有1.几V?

如果达到3.3,那肯定已经开机了,既然开不了机那就是驱动能力不足,电流不够大,自然电压也拉不上去。

解决BUG

很简单,想个办法把这电流掐掉就可以了。

  1. 换CH343或者其它双电源IC
  2. 暴力加个电阻/二极管
  3. 设计个电路,阻止从CH340的TX流向ESP32的电流

CH343等双电源IC

与CH340之间最显著的区别就在于CH343这款IC除了VCC口以外还有一个VDDIO口。很多MCU也有独立的IO供电,很多IC甚至还会区分数字与模拟的不同供电。

这类IC的数字IO依赖VDDIO提供电源,而不会共享IC本身的工作电源。如果将CH343的VDDIO接到MCU的电源上,则MCU没有上电时,CH343的串口信号线上也不会有信号。

加电阻

keep in mind 加电阻的代价是扔掉推挽的驱动能力,后果是引入RC参数让信号变形,当波特率大到一定程度或者线长很长后,波形就不是相对整齐的直上直下,而是变成曲线了,这是不利于接收方判断的,因而电阻不能加的很大,而且只要加了就会限制信号线的最大传输速率

二极管

STC51的电路中常采用的方案是直接挂个二极管。

当然只挂个二极管是不行的,而且二极管的方向也讲究。

大体上是:

ESP32的RX  -|>|-  CH340的TX

看起来和信号的方向是反的,实际上确实,因为如果只这么连的话,虽然成功阻止了CH340的TX电流流向RX,但同时信号也过不去了。为了能让信号传过去,这里就有个小trick:

   3V3
    |
 10k电阻
    |
ESP32的RX  -|>|-  CH340的TX

这样一来,ESP32的RX端就有了微弱的电流源,当TX在静默状态时足以把RX拉高到高电平。而当CH340的TX输出低电平时,CH340的TX脚就会把信号线上的电流都拉过来,这时候电流方向就顺着二极管了,ESP32的RX脚电压就被拉低了。信号就传播过去了。

但是这有两个缺点:

  1. 把推挽降级成了开漏,最大数据速率肯定变差了
  2. 过了个二极管,而二极管性质里有一条是恒定的0.7V压差,导致ESP32的RX端最低电平一定比0.7V高,不利于CMOS工作

用MOS/BJT替代二极管

则是在直接使用二极管的基础上,优化了0.7V的固定压差,让RX能有可能降到更低的电压。但是依旧降级到了推挽工况,静态功耗偏高,速率受限,意义不大。

使用专门的电平转换IC

比如TXS0102这颗双路电平转换,原理就是双电源。除了BOM稍微贵了点没什么明显缺点。

1 个赞