我不确定这个问题是否在正确的 stackexchange 站点上,因为它涉及编程和硬件。管理员,请随意将其移动到另一个 stackexchange 站点。
问题如下:
我编写了一个小型应用程序 (C++ MFC),它通过串行端口 (COM 1) 读取 GPS 的输出(Garmin 输出 NMEA)。到目前为止,一切都运行良好,但对于现场测试,我们需要在没有 COM 端口的笔记本电脑上使用它。
因此,我们购买了 SABRENT USB 转串行电缆用于测试阶段。我安装了电缆的驱动程序,一切正常。但每次我们拔下/重新插入电缆或每次重新启动计算机时,GPS 都会被检测为串行鼠标。当 GPS 被检测为串行鼠标时,鼠标开始到处移动,随机单击和双击,导致严重问题。
使用我的计算机上的物理 COM 端口时从未发生过这种情况。
以下是我读过并尝试过但无效的解决方案:
- 仅在计算机启动完成后插入 USB 电缆:似乎只有当用户不拔下并重新插入 USB 电缆时,此方法才有效。由于在故障排除时插入和拔下 GPS 是很常见的事,因此无法使用此解决方案。此外,重启后插入可能不是一个稳定的解决方案,因为此 GPS 将永久安装在卡车上的计算机上,由对计算机知之甚少的技术人员使用,我不希望他们在连接 GPS 之前等待计算机重启。
- 将注册表项 SkipEnumerations 添加到导致错误的 COM 端口的注册表中:无法执行此操作,因为每次插入 USB 时都会创建一个虚拟 COM 端口,并且端口号非常随机(COM6、COM7 等)。此外,虚拟 COM 端口不在注册表中。
- 禁用检测到的串行鼠标:这是不可能的,因为当检测到鼠标时,我无法再控制我的普通鼠标,这完全是一片混乱。一旦我拔下 USB 电缆,鼠标就会从设备管理器中消失,所以为时已晚。
答案1
由于人们将使用 Google WWWW 来查找此信息,因此这里有一个稍微概括性的答案。
串行端口可以连接到许多不同的东西。它们不只是与调制解调器通信。它们还可以与鼠标或图形输入板通信。有一个完整的规范,即插即用外部 COM 设备规范,处理即插即用枚举如何在串行端口上工作。不幸的是,您的 GPS 接收器不是合适的即插即用串行设备,它发送到主机的连续数据流会混淆串行端口即插即用枚举协议。
您的 USB 适配器电缆本身可以进行即插即用自动检测。
USB 设备有多种类型,例如设备类别,它们会向主机报告。在 USB 世界观中,适配设备可能是串行端口设备类型(通讯设备类设备类别)或鼠标设备类型(人机接口设备设备类别)。已知有几种 USB↔RS-232 适配器电缆会根据检测到的连接到其 RS-232 接口的设备来决定它们向主机报告的 USB 设备类别。它们将尝试与设备通信,自动检测它是什么类型的串行设备,并相应地更改自己的设备类别。如果 GPS 接收器在它们看来像鼠标,它们会将自己报告为 USB HID 设备。
在这种情况下,您正确的第一步是将适配器电缆更换为不具有自动检测功能的电缆。您可以通过查看 Windows 设备管理器中的 USB 设备并查看它是 USB HID 还是 USB CDC 设备来查看是否发生了这种情况。
从供应商手册中我可以看到,Sabrent USB↔RS-232 适配器并没有这么智能;虽然不清楚“K”和“M”类型之间的区别,这可能是一个因素。但是,在这种情况下,你并没有脱离险境,因为有一个第二自动检测轮次:
Windows 可以进行即插即用自动检测。
当 Windows 发现它有一个串行端口时,它会尝试找出连接到端口的设备;与设备握手并确定其类型。然后它会调用适当的设备驱动程序。
这里有两个讽刺之处。首先:这意味着一个“智能”USB↔RS-232 适配器,它本身已经完成握手并确定它是 CDC 设备而不是 HID 设备,可以进行第二轮握手,就像 Windows本身尝试确定此串行端口连接到什么。第二:即使在其超级 I/O 芯片中没有 RS-232 主板逻辑连接到 I/O 连接器的机器中,Windows 串行端口设备驱动程序也会尝试检查物理连接到端口的设备。
有几种方法可以解决这个问题:
sermouse
彻底禁用驱动程序。 这是一个简单的改变其开始上课,通过直接调整注册表或使用 Windows 服务管理器,从自动变为手动。当总线驱动程序检测到连接到串行端口的鼠标时,sermouse
将调用驱动程序。如果驱动程序设置为手动,它将不会自动启动,也不会为已(错误地)自动检测到的新“鼠标”创建“鼠标”设备对象。自动检测仍将发生;设备管理器可能会报告由于驱动程序未启动而无法驱动设备。此外,端口当然会serenum
sermouse
serenum
不是被完全识别并列为通讯设备。毕竟,系统认为它是一只鼠标。- 按照微软自从 Windows NT 5 以来一直说要做的事情去做。 Microsoft 知识库文章 283063描述了这种情况,并指出微软
serenum
十年前(2001 年)就更新了其驱动程序,以包含一个旁路功能。需要在注册表中找到设备参数串行设备的特定实例的信息,并SkipEnumerations
为其添加一个值,以停止serenum
尝试枚举它。知识库文章中提供了完整的详细信息,包括在具有不同 HAL 的系统上在注册表中查找串行设备的位置。是的,这些东西是在注册表中,以及不是“虚拟”。如果您正在寻找“虚拟 COM 端口”,那么您找错了。阅读文章并按照说明操作。
- 使用 Microsoft 自 Windows NT 5.2 以来提供的工具来修复此问题。 此工具的名称略有误导性
COMDisable
,获取和使用它的说明如下Microsoft 知识库文章 819036. 它本质上执行与上述相同的注册表修改,以改变设备驱动程序的行为serenum
,而无需费力地找到设备参数在注册表中的位置。
答案2
成立本网站这可能会有用。阅读 Antipodean 的第二篇文章:
Microchip 编写的 CDC 类将处理 255 个字节 - 但您必须小心。如果您在设备完成枚举之前开始发送字符,主机(尤其是 Windows 主机)将把端口枚举为鼠标。如果发生这种情况,光标将不断跳到屏幕上,因为主机将 GPS 数据视为鼠标数据。要停止这种情况,您需要等待主机发送的字符尝试识别鼠标,并等待几秒钟后再允许传输任何数据。