ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

自制USB转4-20mA/±10V隔离模块:从电路设计到PCB实战全解析

自制USB转4-20mA/±10V隔离模块:从电路设计到PCB实战全解析 说起来你可能不信桌上这个装进小铁盒里的模块是我用一颗不到三块钱的GP8630N芯片搭起来的USB插电脑另一头输出4-20mA或者±10V中间还有完整的电气隔离。自打做了这个USB转4-20mA/±10V隔离模块之后现场调试PLC模拟量输入、给变送器做模拟信号源、校验仪表我再没跟人借过信号发生器。市面上一个成品的USB转模拟量隔离模块动辄两三百而我自己打样做下来所有物料加起来也就15块出头PCB文件也是用嘉立创EDA画完直接下单的。这个项目很适合三类人看一是经常跑现场的自动化工程师包里需要随时能掏出一个小信号源二是电子爱好者想练手USB协议、UART、隔离电源、运放电路这些基本功三是刚入门PCB设计的新手想找一个不算复杂但完整度很高的板子来画一画、打一打。接下来我把整个设计思路、电路原理、固件协议、PCB布局和调试踩坑完整记录下来照着做你也能复现。1. 整体方案设计与选型思路1.1 系统架构这个模块的核心链路不复杂USB进去经过GP8630N转成UART信号UART通过数字隔离跨到模拟侧模拟侧一颗单片机解析协议输出两路PWMPWM经RC二阶低通滤波变成平滑的直流电压之后一路通过V/I转换电路输出4-20mA电流另一路通过运放差分放大输出±10V电压。电源侧也必须隔离USB的5V只给GP8630N和光耦输入侧用模拟侧由外部24V电源供电两块地之间完全断开。选择GP8630N作为USB转串口芯片是先把所有方案列出来对比之后做的决定。市面上常见的USB转UART芯片无非CH340、CP2102、FT232RNLGP8630N和FT231X兼容驱动直接用FTDI VCPWindows、Linux、macOS都不折腾。成本上它只要两块多钱比FT232R便宜一大截CH340虽然更便宜但驱动体验和稳定性在工业场景下还是差一点。这个方案的灵魂就在“低成本但可靠性不能太差”所以芯片选型基本是一颗一颗抠过来的。1.2 为什么用隔离而且是数字隔离做现场仪器仪表的人应该都有过这种经历USB线插着电脑输出端去接一个现场仪表结果仪表地、传感器地和电脑USB地之间电位不一致轻则信号跳变重则USB口直接烧掉。我第一版为了省事USB地和模拟地直连结果一次调试时把笔记本南桥附近一个供电烧了从那以后凡是接现场的USB转模拟量设备我坚决隔离。隔离点放在UART信号层面原因很简单4-20mA和±10V模拟输出需要高精度在模拟侧做隔离更复杂成本也高而UART是数字信号用两片高速光耦就能干净利落地跨过隔离沟。光耦必须选高速型普通PC817、EL357这种几微秒级别的速度跑115200波特率会很吃紧波形拉垮到一定程度直接乱码。我实际用的是6N13710Mbps的速率余量很大一颗一块二左右两颗就能搞定收发双向隔离。电源隔离部分我没有用隔离DC-DC模块而是把模拟侧的供电完全独立出来外部24V进来经过线性稳压给模拟电路供电。这样做有几个好处第一省掉了B0505S这类隔离电源模块的成本一个模块就五六块钱直接吃掉接近一半预算第二外部24V本身是工业现场的常备电源24V进来稳压成±15V给运放电源质量比USB端取电再隔离好太多。其实用B0505S做一个完全USB自供电的隔离版也是可行的就是把模拟侧功耗压到一两瓦以内后级再用电荷泵做负压这个变体我后面有时间会再出一版。2. USB转串口核心电路GP8630N最小系统2.1 芯片特性与外围电路GP8630N这颗芯片可以看作是FT231X的国产pin-to-pin兼容替代方案内部集成了USB收发器和USB CDC控制逻辑系统把它识别为一个标准串口设备不需要写任何USB固件MCU侧只面对一个普通的UART接口就行。典型电路和FT231X基本一致D/D-分别接USB座的DP/DMTXD/RXD交叉连到下游单片机VCC接3.3V或5V都可以芯片内置LDO外围基本就是几个去耦电容。部分版本是否外接晶振要以下单时的数据手册为准我手头这颗是内置振荡器版本电路可以做到非常精简。我在实际画的原理图里GP8630N周围放了这几样东西VCC处一个10uF钽电容加一个0.1uF陶瓷电容USB D/D-线上各加一个27pF到地的小电容做EMI抑制D/D-走线尽量靠近USB座选Type-C母座CC1和CC2分别通过5.1k电阻下拉到地让USB主机正确识别为设备。另外还加了一颗ESD防护器件型号是USBLC6-2虽然这块小板不是量产产品但USB口经常热插拔这个保护非常值得。芯片的TXD和RXD并不是直接接到外面去而是先接到光耦。PC发送数据时GP8630N的TXD引脚输出高电平点亮光耦输入端的LED光耦输出侧导通把模拟侧MCU的RXD拉低这样就实现了一次电平跨隔离传输。反向路径完全对称MCU的TXD经过另一颗光耦传回GP8630N的RXD。需要特别注意的是光耦输入侧要串电阻限流6N137的输入LED工作电流一般在10mA左右5V供电下串一个330Ω的电阻比较合适输出侧上拉电阻取4.7k保证电平跳变速度。2.2 驱动安装与虚拟串口配置GP8630N由于兼容FT231XWindows下如果系统不能自动识别装一个FTDI VCP驱动就好。安装完之后设备管理器里会出现“USB Serial Port (COMx)”波特率设置范围很宽从300到3Mbps都能跑但在这个模块里因为光耦传输我实际统一用115200。这个波特率下6N137毫无压力如果非要跑更高光耦的传输延迟就成了瓶颈波形占空比会失真想要高波特率还是换数字隔离器更靠谱。驱动层面有两点要提醒第一尽量用官方新版驱动老版本驱动在Windows 10/11上容易遇到“设备已识别但串口打不开”的问题卸载后换个版本基本能解第二如果电脑上同时插过多个FTDI方案的设备串口号可能会乱跳这时候在设备管理器里把“USB Serial Port”的端口号手动固定成一个不常用的号比如COM9能省掉很多后续麻烦。Linux系统不用装驱动插上之后会识别为/dev/ttyUSB0直接用pyserial打开即可这个模块做跨平台工具很顺。3. 隔离方案与模拟侧电源架构3.1 信号隔离电路细节信号隔离这里我用了两颗6N137一颗管PC到MCU方向一颗管MCU回PC方向。很多DIY作者图省事只隔离了PC发往MCU的方向MCU的回复直接拉回USB侧这就留下了隐患一旦模拟侧异常电位串到MCU的TXD引脚还是会通过IO路径倒灌到USB侧。两边都隔离虽然多花一块两毛钱但隔离才是彻底的。光耦两侧的供电要严格分开输入侧用USB的5V输出侧用模拟侧的5V。PCB布局上两颗光耦正好骑在隔离槽的正上方光耦本体跨越隔离带引脚分列两侧这样既保证了信号通路最短也让爬电距离有保障。隔离槽的宽度我开到了2mm槽内不铺铜、不走线机械强度上只要不是使劲掰正常使用完全没问题。光耦输出侧的上拉电阻要接到模拟侧的5V不要一不小心接成USB侧5V否则隔离就形同虚设了。还有一个细节6N137输出是集电极开路上拉电阻选4.7k还是10k取决于信号速率和功耗。115200波特率下4.7k上拉能保证tr/tf都在几十纳秒量级配合光耦的高速响应波形非常干净。如果上拉电阻太大上升沿会变缓长距离传输时可能出现误码。3.2 模拟侧电源生成24V转±15V整个模拟侧需要三路电压MCU和光耦输出侧用的5V运放用的15V以及差分放大用的-15V。24V工业电源进来之后分成两路一路经过78L05输出稳定的5V给STC8单片机、光耦输出侧、TL431基准供电另一路经过7815和7915分别得到15V和-15V给运放。可能有人会问运放用±12V不行吗为什么非要±15V这里有个很实际的原因LM358这类普通运放不是轨到轨输出正输出摆幅通常比正电源低1.5V到2V负输出也比负电源高一点。如果运放电源只有±12V要输出10V时看似能用但带上负载之后实际摆幅还会再掉经常出现“指令发到10V输出实测只有9.7V”的尴尬情况。电源做到±15V之后LM358输出±10V的余量就有5V左右线性度也更好。如果后续换成GS8552这类轨到轨运放电源回到±12V也完全可行成本还能再压一压。线性稳压的发热问题要算一下。24V输入降到15V压差9V模拟电路总电流算上运放和分压电阻大概30到50mA单颗7815上的功耗不到0.5W板子上的铜皮面积足够应付实测跑半小时温升不大。要是后续增加输出驱动能力线性稳压就不合适了得换DC-DC降压模块这就不在15元成本控制的范围内了。4. 模拟输出电路4-20mA与±10V4.1 4-20mA恒流输出电路4-20mA输出的本质是一个压控恒流源单片机输出的PWM经过滤波后得到一个直流电压Vset这个电压送进运放U1A的同相输入端运放的反相输入端接采样电阻R8的上端运放输出驱动NPN三极管Q1的基极。负反馈的结果是让R8两端的电压稳定等于Vset所以流过R8的电流就是Vset/R8这个电流也基本等于流过负载的电流从而实现恒流输出。这个电路里最重要的元件就是采样电阻R8。它决定整个电流输出的精度必须用低温漂、高精度的电阻。我选了100Ω、0.1%精度、25ppm温漂的2512封装电阻20mA满量程下功耗是0.04W余量很足。Vset的范围是0.4V到2.0V对应输出4mA到20mA也就是单片机PWM滤波后的电压只需要在这个区间内调节即可。三极管Q1的选型也要注意推荐用D882或者SS8050这类中等功率管集电极电流能到1A以上饱和压降小。负载回路里外部24V正极接负载电阻一端负载另一端接模块的IOUT端电流从IOUT进入Q1集电极从发射极经R8回到模拟地。这是典型的三线制恒流输出结构模块本身不提供回路电源而是通过外部的24V电源驱动负载。这种结构的优势是能兼容绝大多数PLC模拟量输入模块负载范围也宽。4.2 ±10V电压输出电路±10V输出和4-20mA输出走的是同一个PWM滤波源准确说是用另一路PWM独立生成一个0到5V的控制电压经过运放差动放大之后得到-10V到10V。核心公式是Vout (Vdac - 2.5V) × 4当Vdac等于0V时输出-10VVdac等于2.5V时输出0VVdac等于5V时输出10V。这样一圈映射下来12位分辨率下的电压输出精度理论值大约是4.9mV对仪表调试来说已经够用。电路实现上用了标准差分放大器同相输入端经10k电阻接Vdac再经40k电阻接地反相输入端经10k电阻接2.5V基准40k反馈电阻接输出。增益就是40k/10k等于4。这里的2.5V基准我用TL431稳压精度很高成本两毛钱强烈推荐别用电阻分压凑2.5V温漂和负载调整率都会拖累整机精度。Vdac从PWM滤波网络出来后输出阻抗有二三十千欧直接进差分放大器会导致同相输入端的电阻分压比被源阻抗破坏增益就不是准确的四倍。解决方法是在差分放大器前面加一级电压跟随器用运放U1B做缓冲这样Vdac的源阻抗对后面完全没影响。我用的两颗LM358共四个运放U1A做电流环U1B做PWM缓冲U2A做±10V差分放大U2B做2.5V基准缓冲一颗都没浪费。±10V输出端我串了一个100Ω的保护电阻防止外部意外短路把运放干烧。这个输出的负载能力有限运放输出级一般只能提供20mA不到的电流所以这个模块适合接PLC模拟量输入这类高阻抗负载不适合直接驱动小功率执行器。你要是想让模块能带得动更大负载就得在后面加扩流电路那就是另一个故事了。4.3 PWM滤波参数与软件校准PWM滤波是最容易被忽视精度的地方。单片机的PWM频率配置到93.75kHz12位分辨率也就是0到4095对应0到5V理想情况下每位分辨率约1.22mV。但PWM输出是方波后面必须接低通滤波器把高频分量滤掉。我用了两级RC每级R取10k、C取1uF两级串联截止频率大约16Hz。在这个截止频率下93.75kHz的PWM纹波经过两级衰减之后实测残余纹波只有零点几毫伏对4-20mA的电流精度影响可以忽略。不过两级RC的代价是响应变慢从指令发出到电压稳定实际需要大约百毫秒级别。如果是做缓慢调节和手动设定这个速度完全无感如果希望响应更快可以把R减小到4.7k、C减到0.47uF截止频率提高到大约36Hz纹波会稍微大一点但在可接受范围内。PWM滤波的RC参数就是这样纹波和响应速度是一对矛盾按你的实际场景取舍。软件校准是低成本模块能达到好精度的关键。由于PWM占空比、电容漏电、运放偏置电压等因素实测输出和理论值之间总会有几个毫伏到几十毫伏的偏差。我在固件里做了两点校准上位机发一个低值比如4mA记录实测值再发一个高值比如20mA记录实测值然后算出斜率和零点存到单片机的EEPROM里以后每次输出都套用这个校准公式。工程上这招叫软件误差修正比堆硬件精度划算一百倍。5. 固件协议与上位机5.1 通信协议设计固件要做的核心事情就是收串口帧、解析命令、更新PWM占空比。我设计了一个非常简短的帧格式六个字节帧头0xAA 0x55功能码0x10为4-20mA输出0x11为±10V输出0x12为同时设置数据高字节、数据低字节数据范围0到65535线性映射到对应量程校验帧头加功能码加数据的累加和取低8位这个帧格式的好处是直观好调写上位机时特别好排查问题。如果你希望模块接入Modbus系统后续可以在这个固件基础上加一个Modbus RTU从机模式功能码06写单个寄存器就行硬件不用动纯固件升级。刚开始做时还是建议用自定义帧逻辑简单容易调通。5.2 固件主流程单片机用的是STC8G1K08SOP8封装8个引脚刚好够用VCC、GND、串口RXD、串口TXD、两路PWM输出、复位一颗芯片就把所有逻辑吃下了。STC8G内置高精度IRC时钟不需要外部晶振复位电路也可以极简非常适合这种小板子。主程序逻辑很简单串口中断收字节通过状态机拼帧完整收到六个字节后校验校验通过则根据功能码更新电流PWM或电压PWM的占空比寄存器。PWM配置成固定频率93.75kHz改变的是比较值。电流输出映射关系要单独算4mA对应PWM占空比约8%20mA对应40%中间线性电压输出则是0到100%的占空比直接映射-10V到10V。这里要注意MCU的PWM分辨率。STC8G1K08的PWM是15位寄存器但我限定在12位使用也就是最大比较值4096这样代码里所有映射关系都是整数运算不会有浮点精度问题速度也快。单片机开启看门狗防止工业环境下的干扰导致程序跑飞。5.3 Python上位机快速实现调试阶段最舒服的上位机就是Python加pyserial几十行就能搞定。下面这个脚本是我实际在用的一小段设置4-20mA输出时直接调用set_ma()函数设置电压输出时调用set_voltage()。import serial ser serial.Serial(COM3, 115200, timeout0.2) def send_frame(func, val): frame bytes([0xAA, 0x55, func, val 8, val 0xFF]) cs sum(frame) 0xFF ser.write(frame bytes([cs])) def set_ma(ma): # 4mA - 0, 20mA - 65535 val int((ma - 4.0) / 16.0 * 65535) val max(0, min(65535, val)) send_frame(0x10, val) def set_voltage(volt): # -10V - 0, 10V - 65535 val int((volt 10.0) / 20.0 * 65535) val max(0, min(65535, val)) send_frame(0x11, val) if __name__ __main__: set_ma(7.5) # 输出7.5mA set_voltage(3.2) # 输出3.2V如果你不喜欢写代码用任意一个串口助手也能手动发帧。模块刚上电默认输出4mA和0V这个默认状态是安全的。我建议上位机里加一个“输出使能”概念比如帧头换成0xA5 0x5A表示有效避免串口误码导致输出突变。实际调PLC或者仪表时输出突然跳变是很吓人的。6. PCB设计与成本控制6.1 嘉立创EDA画板要点整个板子我用嘉立创EDA画完下单打样双面1.6mm板厚走线间距按常规10mil全板无特殊阻抗要求最便宜的五元打样档位完全足够。画板子时有几个点特别想强调全是实际踩过的坑第一个是隔离槽要画到位。模拟地和USB地之间必须物理开槽槽宽2mm槽的起点和终点分别延伸到板边这样爬电距离才真正被拉开了。如果不放心还可以在槽内增加几个1mm宽的凹槽形成弯折路径爬电距离会进一步增加。两个地之间绝对不能有大面积铜皮重叠否则高频干扰和漏电流都过不去。第二个是USB差分线的处理。D和D-两根线尽量等长、靠近线宽20mil左右走线下方保持完整的参考地平面。虽然主机端对USB全速设备的走线要求不像高速设备那么苛刻但走线过长或者绕大圈会导致信号品质明显下降甚至出现只能插某些电脑、插某些电脑就识别不到的怪问题。第三个是模拟部分的走线。采样电阻R8的电流走线和电压反馈走线要分开直接从电阻两端飞线到运放输入绝对不能让大电流流过运放输入端附近的地。这就是常说的开尔文连接法虽然板子小但遵守这个规则对4-20mA的精度帮助很大。PWM滤波电容的地要单独接到模拟地的主汇合点不要和4-20mA输出回路的强电流地混在一起否则会产生地弹噪声。6.2 BOM成本清单下面是这块板子的物料清单和大概单价总成本算下来13元左右加上PCB摊薄之后刚好15元出头的量级。如果你手里有旧板拆机料成本还能更低。位号物料封装/规格单价(元)U1GP8630NUSB转UART, 兼容FT231X2.5U2/U36N137高速光耦2.4U4STC8G1K08SOP8单片机1.3U5/U6LM358SOP8双运放0.7U7TL4312.5V基准0.2U8/U97815/791515V/负15V稳压1.1U1078L055V稳压0.3J1Type-C母座16P0.5J2/J35.08端子2P/3P0.8阻容电阻电容各型号若干2.0PCB双面板10片摊薄0.5看到这个成本可能会有人怀疑东西靠不靠谱。实际上决定可靠性的不是元器件单价而是设计时有没有把每个关键参数算清楚。GP8630N本身在两三块这个价位段的USB转串口里算很稳的6N137也是经典工业级料运放LM358虽然老但在这个应用里性能绰绰有余。只要布局布线合理、电源去耦到位这块板子跑现场完全能胜任。7. 调试实录与常见问题排查7.1 我的调试顺序一块带隔离的板子调不通的时候最难排查的是“不知道问题在隔离的哪一侧”所以我按下面的顺序逐步焊接、逐步验证每一级都确认没问题了才继续下一级。第一步只焊USB侧和GP8630N不插光耦先用USB线连电脑确认设备管理器里能正常出现COM口。第二步焊上两颗光耦和模拟侧MCUMCU先跑一个最简单的串口回环程序也就是收到什么字节就原样发回什么字节上位机用串口助手发数据能收到回显说明UART隔离链路是通的。第三步让MCU输出固定占空比的PWM用万用表测RC滤波后的直流电压确认和理论值一致。第四步焊上所有模拟输出电路外接24V电源先测4-20mA再测±10V最后做两点校准。这个流程看着啰嗦但能帮你把故障范围快速缩小。我见过很多人一上来就把所有元件焊齐了结果通电不对满板子找问题找一晚上。分阶段调试每步都留观测点效率高得多。7.2 常见问题速查表现象可能原因解决思路电脑无法识别USB设备D/D-接反GP8630N供电异常驱动未装量芯片VCC对地电压D/D-对地电压应为3.3V左右重装FTDI VCP驱动串口能打开但发送无反应TXD/RXD接反光耦方向装反MCU没跑起来用示波器量光耦输入侧和输出侧波形分段定位核对MCU电源和复位4-20mA输出为0外部24V没接负载回路断开Q1击穿运放供电异常量Q1集电极电压量R8两端电压按电压法快速判断4-20mA输出值整体偏小采样电阻R8精度不够Vset偏低PWM占空比映射错误换0.1%采样电阻万用表直接量R8上端电压是否等于理论Vset4-20mA输出跳动PWM纹波过大RC滤波电容漏电接地点不干净示波器看滤波后纹波C值加到2.2uF检查强电地是否回流到弱电地±10V输出正电压上不去运放不是轨到轨电源电压不足负载拉低输出正电源加到15V换轨到轨运放检查负载阻抗是否太小±10V输出存在振荡差分放大器相位裕度不足输出线缆电容太大输出端接100Ω隔离电阻在反馈电阻上并联10pF小电容模块发热明显7815/7915压差大负载接近短路24V降到15V本来就有压差损耗降低负载电流或换DC-DC这些坑我基本都踩过一遍。最典型的是一次4-20mA输出总是比设定值偏小0.2mA左右排查半天发现是采样电阻买错了精度换了一颗0.1%的电阻后立刻恢复正常。还有一次±10V输出在9.6V就上不去了折腾一圈发现是运放电源用了±12V换±15V后完美解决。这类问题如果能在设计阶段就规避掉调试时会省下大量时间。8. 低成本隔离模块的后续扩展方向板子做完之后我其实又做了几个小改动一是把USB Type-C座换成MicroUSB座成本还能再降两毛但Type-C线材更通用最终还是留了Type-C。二是把4-20mA和±10V输出改成可配置的跳线方式让一个端子可以输出4-20mA或者0-10V这样现场灵活性更好电路上只需要改运放反馈电阻的组合PCB预留0欧电阻位即可。三是考虑加一路24V输入通过隔离DC-DC给USB侧回馈供电这样模块可以脱离电脑独立工作变成一个纯手持式信号源使用场景会更大。当然这种改法会增加成本和体积还需要重新画一版PCB。这个模块从最开始的构思到第一版能正常工作大约用了两个周末。成本很低所有资料都在我手里需要的朋友可以留言找我要工程文件。个人体会是做这种小工具最有价值的部分不是省下来的那几百块钱而是把USB协议、UART隔离、恒流源、运放放大、PCB布局这些知识串在一起踩过的每一个坑都变成了实实在在的经验。下次再遇到类似需求你心里就会有底很多。
返回列表