菜鸟硬件学习笔记(一)
转眼间毕业一年了,在职场也工作了一年半,由于在校期间并没有系统性的学习过嵌入式硬件,只是按照学校课程要求简单的学习了一下数电以及模电,实际上对于这些理论并没有一个实践过程,最后学了之后不了了之。实习时,连电容的特性是啥都不知道了,更别说动手搭建一个电路。害,纯纯一个小白。好在公司大佬很多,也愿意给我学习的机会。但是有个问题就是我总是学了又忘,上个月刚踩过的坑,过一两个月又踩了,好了伤疤忘了疼说的大概就是我吧,所以决定打算将我踩过的坑一点点记录下来,不然白踩了,说了那么多,下面开始进入正题。
三种RS-485通讯电路
前段时间,公司需要我设计一款产品,这个产品功能很简单,就是一个4G模块加上一个485电路,这个产品主要就是给485设备联网用的。功能很简单,但是需要过国标二EFT和ESD测试,因为我从没测过EFT和ESD,所以在设计时并没有什么概念,不知道哪些地方需要加静电防护,导致重新改了一版PCB(关于EFT和ESD的测试细节后面有空再写一篇笔记记录,这次记录的是改了第二版PCB之后出现的485问题),最后这个版本通过了国标三的EFT和国标二的ESD,但是!!!静电通过之后给到QA妹子那边测试之后发现485通讯时电压不太对劲。
RS-485通讯电路
做过硬件的应该都知道,一般大家设计的485电路应该类似于上图这样,用MCU的一个IO去控制ENABLE,RO接MCU的RX,DI接MCU的TX,在MCU要发送时将ENABLE拉高就可以发送,此时RO为高阻态(注意!!!),当发送完成之后将ENABLE拉低,此时485就只能接收。按理说,只需引出4G模组的一个IO加上一个三极管(4G模组IO为1.8V)来控制ENABLE的高低电平就没问题,但是软件开发的同事改了一版固件给我之后,我用示波器看到的波形是这样的!
蓝色为DI,黄色为ENABLE,没错,就是4G模组在发送前将ENABLE拉高,打算发完一包数据再拉低时,在开始发送的时候ENABLE就自己拉低了,当时看到这个现象我和软件开发的同事都懵了,两个人直呼:不可能!!!当然,他的不可能是他的固件不可能出错,我的不可能是我的示波器不会出错,于是他又改了一版固件给我,结果还是这样,最后找到模组原厂支持,这个问题也没能解决,好像说是多线程问题。最后无奈我改了原理图用了一键收发切换电路,原理图大概如下
RS-485硬件自收发切换电路
这里需要解释一下这个485收发自动切换的原理
485芯片采用GM3085E芯片,电路使用NPN三极管切换收发。控制原理是:MCU的UART的TX和RX引脚需要连上拉电阻(TX和RX在没有通信时均是高电平),防止刚上电TX和RX引脚电平不稳定引起收到扰乱数据。A上拉电阻B下拉电阻,终端并联120欧姆电阻,TV1、TV2、TV3为三个防雷防浪涌的TVS管。
接收: 默认没有数据时,UART_TX为高电平,三极管导通,GM3085E芯片RE低电平使能,RO接收数据使能,此时从485AB口收到什么数据就会通过RO通道传到MCU,完成数据接收过程。
发送: 当发送数据时,UART_TX会有一个下拉的电平,表示开始发送数据,此时三极管截止,DE为高电平发送使能。当发送数据‘0’时,由于DI口连接地,此时数据‘0’就会传输到AB口 A-B<0,传输‘0’,完成了低电平的传输。当发送‘1’时,此时三极管导通,按理说RO使能,此时由于还处在发送数据中,这种状态下GM3085E处于高阻态,此时的状态通过A上拉B下拉电阻决定,此时A-B>0传输‘1’,完成高电平的传输。
PS: 此时有人肯定也会有疑惑,发送数据‘1’,三极管导通RE低电平有效应该是接收使能,为什么芯片会是高阻状态?
因为UART发送数据会有一定的格式,数据均以“位”为最小单位进行传输。在收发数据之前,UART之间要约定好数据的传输速率(即每位所占据的时间,其倒数为波特率)、数据的传输格式(有多少数据位、是否有校验位、奇校验还是偶校验、是否有停止位)。 平时数据线处于“空闲状态”(1状态)。当发送数据时,TX由‘1’变为‘0’维持1位的时间,这样收方检测开始位后,再等待1.5位时间就开始一位一位的进行数据传输。意思是说,已经确定好发送状态,电路发送‘1’此时RE有效,接收有效但有由于它处于发送阶段,此时芯片会处于高阻状态。
上面原理摘取自 electrocrazy 的CSDN 博客 ,全文地址请点击:链接
由于模组和485IC的电平并不一样,这里用到了电平转换电路,需注意的是,上面的电平转换设计的有问题,这也是我今天要记录的一个点!
如图所示,VCC_485是4V,而VDD_EXT是1.8V,此时三极管会出现集电极正偏,导致RX电平异常,后面我飞线将VCC_485换成VDD_EXT,RX电平就正常了,这部分错误主要是因为对三极管掌握不够导致的。
如果你以为只有这个错误那就你就错了,作为挖坑小能手怎么可能只踩一次坑,没飞线之前我还用示波器测了模组TX和GM3085E RO的电平。
黄色为模组TX发送出去的波形,蓝色是GM3085E RO收到的波形,上面这图是没飞线之前测的,实际飞线之后蓝色波形下降沿更低了。家人们,见鬼了,自产自销。如你所见,模组发出去什么,同一时间RX就会收到什么,按理来说RO应该一直为高电平才对,我百思不得骑姐,经过了一段时间的排查我发现了原因,还记得我上文说过,当GM3085E处于发送状态时,RO为高阻态,因为我的RO没有加上拉电阻,所以RO相当于被基极上拉了
因为三极管有0.7的压降,所以4V减去0.7的压降之后会变成3.3V左右,这个时候就会出现RO被拉低的现象,解决办法是在RO那一端加个上拉电阻。
RO除了拉低的异常之外,通过波形可以看出还有个很长很窄的一个的拉低现象,这个应该是485电路三极管开关较慢产生的,这部分没有去深究,因为这个自动切换收发电路有个问题就是没办法支持波特率太高的场景,当波特率太高了,Q2会开关不及时,导致数据错乱,而我们产品需要支持的波特率是达到115200,这明显是不符合需求的,后面经过大佬的传授,我Get了一个新的485自动切换收发电路。
RS-485延时自收发电路
这个自收发电路的好处在于它在发送过程中,485_DE并不会跟着一直改变,而且波特率也没有限高,理论上只要485芯片支持多高,他就可以多高,这个电路主要在于限低,至于为什么限低,我们分析一下就清楚了。
这个电路主要器件是R3和C46,通过调整这两个值可以实现不同的延时,具体公式为:
t
=
R
C
∗
l
n
(
V
1
−
V
0
V
1
−
V
t
)
t=RC*ln(\frac{V~1~-V~0~}{V~1~-V~t~})
t=RC∗ln(V 1 −V t V 1 −V 0 )
其中V1为电源电压,V0为电容初始时刻电压,Vt为t时刻电容电压。在这个电路里,V1=4V,V0=0V,Vt=1.5V。延时大概2.4S。
接收: 默认没有数据时,UART_TX为高电平,DI为高电平,Q2A导通,C46充电,大概2.4ms后充电完成,此时Q20导通,485_DE为低电平,RO接收数据使能,此时从485AB口收到什么数据就会通过RO通道传到MCU,完成数据接收过程。
发送: 当发送数据时,UART_TX会有一个下拉的电平,表示开始发送数据,此时Q2A截止,Q2B导通,C46充的电通过Q2B释放掉,Q20截止,485_DE为高电平,DE为高电平发送使能。当发送数据‘0’时,Q2B处于导通状态,C46没有充电,此时Q20一直处于截止状态,DE一直为发送使能,此时数据‘0’就会传输到AB口 A-B<0,传输‘0’,完成了低电平的传输。当发送‘1’时,此时Q2A导通,Q2B截止,C46开始充电,因为C46充满需要2.4ms,所以我们需保证当UART_TX每一个比特都为‘1’时,电容还没有充满,以波特率4800来说,若通讯双方用的4800波特率,数据位为8,则每一个字节都为‘1’时发送的时间为(1/4800)*8=0.00166…,也就是说,就算串口发送‘11111111’,此时电容也不会充满电,而开始发送下一位时,因为串口每一个字节发送前都有一个低电平的开始位,所以到下一个字节发送时,C46的电会被释放掉,重新充电,当波特率高于4800时更不用担心了,因为发送的时间只会更短,更不可能把电容充满,所以这就是我前文说的为什么这个电路限低而不限高,如果需更低波特率,则需要调整C46的值,使它充满电需要更多时间。此时Q20一直处于截止状态,DE一直为发送使能,此A-B>0传输‘1’,完成高电平的传输。
当我用4800波特率来发送数据01 03 FF FF FF FF 44 5e 时,此时的波形如上图,黄色为DI,蓝色为485_DE,因为Q20的导通电压为0.8V-1.5V,1.5V完全导通,而我算延时的时候Vt时按1.5V算的,所以当电容充到0.8V以上时,Q20已经慢慢导通了,只不过不是完全导通,所以出现了上图中蓝色线有一个下降的波形,但这并不会影响到485的一个发送模式。
需注意的是,需关注TX和RX之间的间隔,485_DE需在2TX和RX之间。
总结
1. 若IO口够用,建议用IO去控制485的一个收发使能。
2. 若IO不够用,同时波特率在9600或以下的话采用硬件自收发切换电路,比延时自收发电路省几毛钱成本。
3. 若对成本没太高要求,IO不够用,且波特率很高的情况则可以采用延时自收发电路。