1. 虚拟串口到底虚拟了什么
很多人第一次接触"虚拟串口"这个词,会下意识以为它是一个硬件设备,插上就能用。实际上它是一对逻辑上互连的串口端点——A端和B端在系统里各自表现为一个独立的COM口,A端发出去的数据会原封不动地从B端出来,B端写进去的数据也会立刻出现在A端的接收缓冲区里。整个过程中间没有真实的电平翻转,没有TXD/RXD引脚,也没有任何物理连线。
这个特性决定了它的适用场景。调试嵌入式设备时,手头的主控板可能只有一块,但上位机软件需要同时连接两个串口做数据转发测试;开发串口通信程序时,需要在不接任何外部设备的情况下模拟对方发来的数据;还有一类更常见的需求,是让两个只支持串口通信的软件互相说话,比如某款数据采集软件只认COM口,而数据源是另一个程序。这些情况下如果硬要用真实串口加杜邦线对接,不仅麻烦,还容易因为电平不匹配烧坏设备。
需要先说清楚一个概念边界。虚拟串口和"USB转串口"完全是两码事。USB转串口是用芯片(常见的有CH340、CP2102、FT232这几种)把USB协议转成TTL串口电平,另一端接的是真实的外部设备;虚拟串口则是在操作系统内核里创建一对软件端点,全程不涉及任何电气信号。你打开设备管理器,虚拟串口通常会显示在"端口(COM和LPT)"下面,名字里一般带"Virtual"字样,而USB转串口设备则会显示成"USB-SERIAL CH340 (COM3)"这类格式。
还有一个容易混淆的点是"虚拟串口驱动"这个说法。广义上,任何在系统里注册出一对COM口的软件组件都算,但实际落地时有两条技术路线:一条是安装内核态的虚拟串口驱动(如经典的工具软件自带的那种),由驱动在系统底层创建端口对;另一条是利用蓝牙SPP协议或者某些USB设备驱动框架,在连接建立后动态生成COM口。本文主要讲第一条路线,因为它最通用、最不依赖硬件、也最适合新手第一次上手。
注意:虚拟串口只负责数据搬运,不负责协议解析。它不会帮你校验CRC,不会自动分包,也不会改变波特率——两端设置的波特率如果不一样,数据照样会错,只不过虚拟串口本身不会报错。
从使用者角度看,它的价值可以归结为一句话:把"需要两根线和一个真设备"变成"需要一次安装和两次点击"。理解了这一点,后面所有的安装步骤和参数设置才有意义,否则很容易陷入"我明明装了为什么还是不通"的困惑。
2. 驱动安装前必须确认的三件事
动手装之前,有三件事如果没确认,后面大概率要返工。这三件事跟工具本身没关系,跟你的系统环境强相关。
2.1 系统位数与驱动包是否匹配
这条听起来像废话,但实际踩坑的人不少。虚拟串口驱动是内核态组件,64位系统装32位驱动,安装程序可能不报错,设备管理器里也能看到端口,但一旦有程序打开这个COM口就会蓝屏或者直接卡死。判断方法很简单:右键"此电脑"选属性,看"系统类型"写的是x64还是x86。现在的机器基本都是x64,但如果你在老旧的工控机或者虚拟机里操作,务必先看一眼。
驱动包的获取渠道也要留意。市面上有几家厂商提供这类工具,版本号相差很大,有些旧版本在新系统上安装会失败,报"数字签名无法验证"或者"安装程序被策略阻止"。遇到这种情况不要急着关掉系统的驱动签名强制(那个开关关起来麻烦、恢复起来更麻烦),先换一个较新的安装包试试,通常能解决。
2.2 端口占用情况和COM号段冲突
安装之前先打开设备管理器,展开"端口(COM和LPT)"看一眼现有端口。这一步的目的是摸清楚两个信息:当前已经占用了哪些COM号,以及有没有别的虚拟串口工具在运行。
COM号是有限的,虽然理论上可以到256,但实际常用区间是COM1到COM20左右,很多老软件只认COM1到COM9。如果你的虚拟串口工具默认生成的是COM10以上,某些上位机软件会打不开。安装程序一般允许你手动指定起始端口号,选一个低位段的空闲号,比如COM5、COM6,能省掉后面改端口的麻烦。
另外,如果机器上已经装了其他虚拟串口工具,两个工具的驱动可能互相抢端口,导致一方的端口在重启后消失。这种情况不算罕见,处理方式是只保留一个工具,或者在两个工具里把端口号段明确错开。
2.3 权限与安装方式
在普通用户账户下运行安装程序,可能装到一半提示"需要提升权限"然后中断,留下半装状态——注册表里写了东西,驱动文件却没复制到位,最后表现为设备管理器里有个带黄色感叹号的未知设备。稳妥做法是右键安装包,选"以管理员身份运行"。
如果是在有安全管控策略的环境里(比如由统一策略管理的办公电脑),驱动安装可能被直接拦截。这种情况不建议自己找办法绕过,走正规的软件申请流程更省事,也不会有后续隐患。
| 检查项 | 怎么查 | 不达标的表现 |
|---|---|---|
| 系统位数 | 此电脑属性看系统类型 | 打开端口即蓝屏或卡死 |
| COM号占用 | 设备管理器端口列表 | 端口冲突、软件打不开 |
| 安装权限 | 右键看是否有管理员选项 | 装到一半中断、黄色感叹号 |
| 已有虚拟串口工具 | 端口名是否带Virtual字样 | 重启后端口消失 |
表格里最后一项容易被忽略。有些工具默认创建端口对之后,端口名就是"COM5"和"COM6",不带任何标识,和真实串口混在一起,排查问题时很难分辨。建议在工具设置里勾选"端口名加前缀",或者自己在笔记里记清楚哪两个号是虚拟的。
3. 图解驱动安装全流程
这一节把安装过程拆成可对照的步骤,每一步说清楚界面上大概会看到什么、点哪里、为什么这么点。不同工具的界面细节有差异,但流程骨架基本一致。
3.1 安装向导的前三个界面
双击安装包后,第一个界面通常是欢迎页,只有一个"下一步"按钮。这里没什么可犹豫的,但有一个细节值得看一眼:界面角落或标题栏附近往往有一行版本号,记下它,后面如果出问题,查资料时能对上号。
第二个界面一般是许可协议,需要勾选"我接受"才能继续。有些安装包会在这里附带"同时安装某某组件"的选项,默认是勾上的,如果你只需要虚拟串口功能,可以把附加组件取消掉,减少潜在的冲突面。
第三个界面是安装路径和开始菜单文件夹。路径建议保持默认,因为内核驱动安装完成后,系统会在特定目录里注册文件,改路径虽然一般也能成功,但出问题时排查会更麻烦——你不知道驱动文件到底落在哪里。开始菜单文件夹的名字也无所谓,用默认的即可。
点下"安装"按钮之后,会看到一个进度条或者滚动日志。这个阶段是真正往系统里写文件、注册驱动服务的阶段,耗时从十几秒到一两分钟不等。如果进度条卡在某个位置超过三分钟不动,不要急着强杀进程,先等一等,因为驱动安装涉及系统数据库更新,慢一些是正常的。
3.2 安装中弹出的驱动签名确认
这个弹窗是新手最容易慌的地方。界面大致是"Windows 无法验证此驱动程序软件的发布者",下面有三个按钮。正确的做法是点"仍然安装此驱动程序软件",然后等系统提示安装成功。
为什么会出现这个提示?因为这类虚拟串口驱动通常不带商业代码签名证书,系统出于保护机制会拦一下。这不等于驱动有问题,只是缺少一个"官方盖章"。但要注意区分:如果提示的措辞是"此驱动程序已被阻止加载"并且没有"仍然安装"的选项,那说明驱动被系统的强制策略拦死了,这时候继续点也没用,需要换版本或者走正规流程,不要尝试去修改系统安全设置。
安装完成后,向导最后一个界面通常有个"完成"按钮,有的工具还会附带勾选项,比如"立即启动配置工具"、"查看帮助文档"。建议把"启动配置工具"勾上,直接进入下一步创建端口对。
3.3 创建第一对虚拟串口
打开工具的图形界面,主区域一般是一个列表,展示当前已存在的端口对,空白则表示还没有创建过。界面上会有一个"添加"或"Add Pair"按钮。
点击之后,工具会自动选两个空闲的COM号,填在A端和B端的输入框里。这里就是前面 2.2 说的关键点:如果自动选的是COM12和COM13,而你的上位机软件只认COM1到COM9,就手动改成COM5和COM6(前提是这两个号空闲)。
确认之后点"创建"或者"OK",列表里会出现一行新记录,格式大致是"COM5 <-> COM6"。此时打开设备管理器,在"端口(COM和LPT)"下面应该能看到这两个端口,名字里带虚拟串口工具的标识。
到这一步,端口对就已经可用了,不需要重启电脑。某些老版本工具会提示重启,那是因为它们用的是老式驱动加载方式,新版本基本都是即插即用。如果工具提示重启,重启一次也无妨,更保险。
3.4 用两个终端软件做第一次握手验证
端口创建完不等于配置成功,必须做一次实际收发验证。最简单的办法是打开两个串口终端软件(PuTTY、SecureCRT、各种串口助手都行),一个连COM5,一个连COM6,参数设成一样:波特率9600、8位数据位、无校验、1位停止位、无流控。
两边都打开之后,在COM5的窗口里敲几个字符,比如输入"hello",如果COM6那个窗口立刻显示"hello",说明整条链路通了。反过来再试一次,从COM6往COM5发。
这里有几个典型现象和对应的原因:
- 两边都能打开但发数据没反应:多半是波特率或者流控不一致,尤其是流控,一方开了RTS/CTS,另一方没开,数据会被卡住。
- 一个端口能打开,另一个提示"拒绝访问":那个端口号正被别的程序占用,去任务管理器或者用端口占用查询工具查一下是哪个进程。
- 发数据后终端软件卡死几秒:流控设置问题,把流控全部改成"无"再试。
提示:验证时两个终端的回车换行处理方式最好设成一致,否则你会看到对方多出一个空行或者多出一堆乱码,误以为通信有问题,其实只是换行符解释不同。
4. 参数怎么配才不出错
虚拟串口本身对波特率不敏感——数据在内存里搬运,不存在时钟同步问题。但两端软件对流参数的解析是各自独立的,参数不匹配照样出问题。这一节把几个关键参数讲透。
4.1 波特率与数据格式的匹配逻辑
虽然虚拟串口不校验波特率,但两端终端软件打开端口时会各自向驱动提交一份参数配置。某些实现里,如果两端波特率差异过大,驱动可能会拒绝其中一端的打开请求,或者在其中一端读数据时返回错误。稳妥做法是两端设置成完全相同的值。
数据位、校验位、停止位这三项更要一致。举个例子,一端设成8N1(8数据位、无校验、1停止位),另一端设成8E1(偶校验),那么带校验的那一端会把数据的一位当成校验位剥掉,接收到的字节就和发送的不一样了。这类问题最坑的地方在于它不报错,只是数据"看起来有点不对",如果没有对照原始数据,很难发现。
| 参数 | 常用值 | 不一致时的表现 |
|---|---|---|
| 波特率 | 9600 / 115200 | 打开失败或读取报错 |
| 数据位 | 8 | 字节错位、内容乱码 |
| 校验位 | None | 接收字节值改变 |
| 停止位 | 1 | 边界帧解析错误 |
| 流控 | None | 发送卡住、终端假死 |
流控这一项特别值得单独说。虚拟串口没有真实的调制解调器控制线,所以硬件流控(RTS/CTS)在虚拟串口上通常是"看起来能用但行为不确定"的状态。实测下来最稳的是全部关掉流控,即软件流控和硬件流控都设为无。如果你对接的上位机软件强制要求开流控,那就得在虚拟串口工具的设置里确认它是否模拟了控制线状态,有些工具支持,有些不支持。
4.2 端口缓冲区与超时设置
很多串口终端软件里有"读超时"和"缓冲区大小"这类高级选项,默认值往往是1000毫秒和4096字节。虚拟串口下,如果对端发送的数据量比较大,而接收端软件的超时设得太短,可能会出现"读到了半包"的现象——比如对端发了1000字节,你只收到512字节,剩下的要等下一次读。
这不是虚拟串口的缺陷,是串口通信的固有特性:串口是字节流,没有消息边界。接收方必须自己根据协议判断一帧到哪里结束。所以在做验证时,如果看到数据被分成了几段,先别怀疑驱动,检查一下是不是自己的读取逻辑没有做粘包处理。
缓冲区大小则关系到突发数据的处理能力。如果对端会短时间发送大量数据(比如几百KB的日志),缓冲区设得太小会导致数据丢失。经验值是:普通命令行交互用默认值够了,传文件或者传大段数据时,把接收缓冲区调到64KB以上。
4.3 端口号固化与重启保持
虚拟串口工具一般有"记忆端口号"的选项。勾上之后,即使工具重启,端口对还是原来的COM5和COM6,不会变。这个选项建议一直开着,因为很多上位机软件把COM口写死在配置文件里,端口号一变就连不上,得重新配。
还有一种情况:工具卸载重装后,端口号可能被系统重新分配。这是因为系统会把已分配的COM号记录在注册表里,卸载时如果没有清理干净,新装的工具可能跳过这些号。遇到这种情况,可以在设备管理器里把隐藏的设备显示出来,手动卸载残留的端口记录,再重新创建。
5. 装完不通时的排查链路
这一步是整篇文章最实用的部分。虚拟串口装完之后连不通,原因就那么几类,按下面的顺序排查,基本能在十分钟内定位。
5.1 从设备管理器向下逐层确认
第一层看设备管理器。"端口(COM和LPT)"下面有没有那两个COM口?没有的话,说明驱动没装成功或者端口对没创建,回去看第 3 节。有的话,端口名前面有没有黄色感叹号?有感叹号说明驱动加载失败,右键看属性里的错误代码,代码10一般是资源冲突,代码52是签名问题,代码31是驱动无法加载——不同代码对应不同处理方式,不要盲目重装。
第二层看端口是否可打开。打开一个终端软件,选COM5,点连接。如果提示"拒绝访问",说明端口被占用,去查进程;如果提示"找不到端口",说明端口号选错了或者端口已消失。
第三层看数据流向。一端发送,另一端有没有收到。收不到的话,先确认是不是两个软件都成功打开了各自的端口——有些软件界面显示"已连接"但实际端口打开失败,图标状态不可信,要看日志。
这个逐层确认的顺序不能颠倒。很多人一上来就怀疑驱动有问题去重装,实际上问题可能只是端口号被占用,重装三遍也没用。
5.2 端口被占用的定位方法
"拒绝访问"这个错误几乎全部是端口占用引起的。定位方法:打开任务管理器,在"详细信息"标签页里找不到直接线索,需要用命令行工具。在管理员权限的命令行里执行端口查询,能看到哪个进程ID占着哪个端口。找到进程ID之后,在任务管理器里按PID排序,就能对上是哪个程序。
常见的占用者有几类:上次没正常退出的串口软件(进程还在后台挂着)、某些设备的配套工具(比如调试器软件会常驻打开串口)、还有一些同步软件会在后台扫描所有串口。定位到之后结束进程即可,如果结束不了,重启一次是最干脆的解法。
顺带提一个隐蔽情况:有些软件打开端口后不释放,即使窗口已经关了,句柄还挂着。这种只能靠结束进程解决,所以在排查前,先把所有可能碰串口的软件全部关掉,能排除一大半干扰。
5.3 数据能发不能收的三种典型原因
第一种,对端软件没有真正在读取。串口是流式的,如果接收端程序打开了端口但没有调用读取接口,数据会堆在驱动缓冲区里,看起来就是"发了没反应"。验证方法:在对端软件里确认有没有接收数据的日志或者计数。
第二种,参数不一致导致数据被丢弃。前面 4.1 讲过,校验位或数据位不同,字节会被错误解析。表现是收到乱码或者收到长度为0。
第三种,流控导致的阻塞。一端开了硬件流控,虚拟串口没有真实的控制线来应答,发送方会一直等 CTS 信号,表现为发送卡住。把流控全关掉,立刻就能通。
注意:排查时一次只改一个变量。同时改波特率又改流控,即使通了也不知道是哪个起的作用,下次遇到同样问题还是不会。
6. 几个容易忽略的使用细节
装好能用只是起点,长期用下来还有几个细节会反复影响体验,这里一并说清楚。
端口对的两端不要同时被同一个程序打开。有些程序支持"打开所有串口"做扫描,它会把你的一对虚拟端口都占了,导致你的终端软件打不开。遇到这种情况,在程序设置里关掉自动扫描功能。
虚拟串口不能替代真实串口的时序验证。如果项目里涉及严格的时序要求(比如某个设备要求指令发出后 10 微秒内必须收到响应),虚拟串口完全测不出来,因为数据在内存里传递几乎没有延迟,这个测试结果没有参考价值。这类场景必须用真实硬件。
断电重启和休眠唤醒之后要复查端口。笔记本合盖休眠再打开,偶尔会出现虚拟端口消失的情况,重新打开工具界面就能恢复,不需要重装。但如果频繁发生,可能是工具的驱动版本和系统电源管理有兼容问题,换版本试试。
多对端口同时使用时注意资源。一个工具里创建十几对虚拟串口是允许的,但每对端口都会占用系统资源,同时活跃的端口对太多时,可能出现数据延迟。实测下来,同时活跃的端口对控制在十对以内比较稳,超过这个数量就要考虑是不是该用其他通信方式(比如本地回环网络)替代。
备份你的端口配置。工具里创建的端口对信息通常存在配置文件或者注册表里。如果机器要重装系统,先把这份配置导出来,或者至少把端口号对应关系记下来,重装后照着重建,比重新摸索省事得多。
7. 我踩过的两个坑
先说第一个。早些年我在一台工控机上给客户配虚拟串口,装完之后设备管理器里能看到端口,终端软件也能打开,但一发送数据,接收端就显示乱码。折腾了半天,最后发现原因是两个终端软件一个用的是"8位数据位"另一个是"7位数据位"。7位模式下,最高位被吃掉了,所有 ASCII 之外的字节全部变形。这个错误之所以难发现,是因为在纯英文短句测试时,7位和8位看起来完全一样,只有发二进制数据或者中文才暴露。从那以后我养成了一个习惯:验证串口链路时,一定要发一段包含非 ASCII 字符或者十六进制字节的测试数据,不能只用 "hello" 这种纯字母。
第二个坑跟端口号的记忆有关。有次部署环境,我把虚拟串口配成 COM5 和 COM6,测试通过之后就去忙别的了。第二天客户反馈说不通,我远程连上去一看,端口变成了 COM7 和 COM8。原因是客户中途插拔过一次 USB 设备,系统重新枚举时把号段让出去了。虚拟串口工具虽然开了"记忆端口号",但它记忆的是相对顺序,不是绝对号。解决办法是在工具设置里找"端口号固定"或者类似选项,有的版本需要手动把端口号写在配置文件里。如果工具确实不支持固定,那就得在上位机软件那边改成扫描式连接,或者每次开机后人工确认端口号。
这两个坑的共同点是:问题都不在虚拟串口本身,而在使用它的软件配置和系统环境上。所以排查思路应该是先往外看——看终端软件的参数、看系统的端口占用、看有没有别的程序插一脚,而不是一上来就怀疑驱动有问题。
8. 对接真实设备时的桥接思路
最后一节聊一个延伸场景:虚拟串口的一头连上位机,另一头需要接真实设备。这种情况下虚拟串口本身解决不了问题,需要做桥接——把虚拟端口收到的数据转发到真实串口,反过来也一样。
实现方式有两类。一类是工具软件自带桥接功能,在端口对创建时选择"一端虚拟、一端物理",直接指定物理串口的号码,工具内部做双向转发。这种方式最省事,缺点是转发的时机和缓冲策略由工具决定,遇到高频数据时可能出现延迟累积。
另一类是写一个小程序自己做转发,用两个串口库分别打开虚拟端口和物理端口,起两个线程各读各写。这种方式灵活,可以在转发过程中加日志、加过滤、加统计,调试复杂协议时非常有用。写的时候注意一个细节:物理串口那一侧的读取超时不能设得太短,虚拟端口侧则可以设短一些,因为虚拟端口读不到数据时通常是真没数据,而物理端口读不到可能是设备还没响应。
桥接场景下最常遇到的问题是把转发线程写成阻塞式,一个方向卡住另一个方向也停了。正确做法是两个方向独立线程,且每个线程的读写都要带超时,不能无限等待。这套东西并不复杂,代码量通常一百行以内,但它是把虚拟串口从"玩具"变成"调试工具"的关键一步——你可以一边假装成设备给上位机发数据,一边把真实设备的数据同时接进来做对比,这种能力在实际联调时非常省时间。
我在实际使用中的体会是,虚拟串口最大的价值不在于"省了两根线",而在于它把串口调试从"必须凑齐硬件"变成了"随时可以搭环境"。理解了它的边界——不做协议解析、不保证时序、不模拟电气特性——用起来就不会有错误的期待,出问题时也知道该往哪个方向查。装好之后把端口号记牢、把参数统一、把验证做足,剩下的就是纯粹的软件调试工作,比接线可靠得多。