SetupComm,SetCommState,SetCommTimeouts因USB设备而失败

时间:2013-12-12 18:59:14

标签: windows serial-port usb createfile

我正在打开USB设备:

enter image description here

使用CreateFile进行通信:

HANDLE hUsb = CreateFile("\\.\LCLD9",
      GENERIC_READ | GENERIC_WRITE, 
      0, 
      null, 
      OPEN_EXISTING, 
      FILE_FLAG_OVERLAPPED, 
      0);

呼叫成功(即hUsb不等于INVALID_HANDLE_VALUE)。但是,现在是时候做我们对每个串口做的事了:

每次调用GetLastError代码 1 。 E.g:

SetupComm(hUsb, 1024, 1024);

为什么在使用“USB”串行设备时配置串行设备的操作失败,但在使用“虚拟COM端口”时工作? USB设备不支持这样的波特率,缓冲区,流量控制和超时吗?

如果这是通用串行设备的限制/功能,我如何检测句柄是指“Universial Serial Device”,而不是“COMM Port”?例如,用户是指定使用哪个端口的用户:

  • \。\ COM5
  • \。\ LCLD9

与通用串行总线串行设备通信时失败的其他串行功能:

  • GetCommModemStatus(错误代码1)
  • ReadFile(错误代码为6)
  • PurgeComm(错误代码为6)
  • WriteFile(错误代码为6)

这引出了一个更大的问题,一旦用CreateFile打开USB设备后如何与USB设备进行通信?

2 个答案:

答案 0 :(得分:4)

不,USB设备不使用这些东西。如果您的设备是实际的USB到RS232(或其他慢速串行),那么您应该打开它所关联的COM端口。让驱动程序处理发送数据的工作。

USB通信与COM端口不同。您可以将其视为外部PCI总线,而不是简单的发送 - 无论您想要的数据线。

答案 1 :(得分:2)

事实证明,我不需要对Comm做任何事情,因为它不是COM端口。我WriteFile失败的原因是因为我试图写信给\\.\LCLD9而不是\\.\LCLD9\

尾随反斜杠很关键;即使CreateFile双向都能获得成功。

void WriteToDisplay(String s)
{
   //Open the display
   var hLineDisplay = CreateFile("\\.\LCLD9\", GENERIC_WRITE, 0, nil, OPEN_EXISTING, 0, 0);

   //Write the command
   DWORD bytesWritten;
   WriteFile(hLineDisplay, s, s.Length, ref bytesWritten, nil);

   FileClose(hLineDisplay);
}

任何人使用Logic Controls LD9000 USB线显示器,以上就是你如何写显示器。

在对其.NET Line Display驱动程序进行逆向工程后,我还会提到您使用的端口名称,例如:

  • \\.\LCLD9\
  • \\.\LCPD6\
  • \\.\LCPD3\

可以从使用Windows安装程序API返回的完整devicePath中推断出来。例如,我的极点显示器的完整设备路径是:

\\?\USB#VID_0FA8&PID_A090#6&DF2EE03&0&1#{A5DCBF10-6530-11D2-901F-00C04FB951ED}
                 \______/
                    |
                ProductID

规则是检查产品ID的设备路径。在我的情况下PID_A090表示它将以文件\\.\LCLD9\的形式提供。其他产品ID及其关联的文件路径:

Contains  DeviceName (trailing backslash is not optional)
========  ===============================================
PID_A030  \\.\LCPD3\
PID_A060  \\.\LCPD6\
PID_A090  \\.\LCLD9\
  

注意:任何代码都会发布到公共域中。无需归属。