如何在不了解USB协议的情况下使用C#通过USB电缆发送数据

时间:2016-02-02 20:05:38

标签: c# serialization

如何使用C#通过USB连接发送低速串行数据?我不想学习USB通信的复杂性,并且希望使用.NET附带的通信库(如串行COM端口)。

2 个答案:

答案 0 :(得分:2)

对于USB设备制造商而言,尝试这种方法的方法是使用USB HID类驱动程序 - 当设备连接到主机时,它会通过USB通道将自身标识为支持通用USB HID的设备。当计算机看到该设备和那些标识时,它会立即启动通用USB HID驱动程序的实例并将其附加到该端点。驱动程序公开了一个简单的文件句柄接口,允许您读取和写入设备的原始字节。

用户登陆程序使用HID API枚举所有HID设备,按照供应商ID和产品ID字段过滤枚举设备,以查找所需的特定设备。接下来,您可以获得设备驱动程序的用户界面的Windows Object Manager'路径'。在该路径上调用CreateFile以打开驱动程序的文件句柄,然后读取和写入您的内容。您读写的内容只是发送到设备的字节流。

您需要实现此相关的API:

  • HidD_GetHidGuid
  • SetupDiGetClassDevs
  • SetupDiEnumDeviceInterfaces
  • SetupDiGetDeviceInterfaceDetail
  • 的CreateFile
  • HidD_GetAttributes
  • HidD_GetPreparsedData
  • HidD_FreePreparsedData
  • HidP_GetCaps
  • HidD_GetSerialNumberString
  • HidD _... etc

互联网上有几个可用的项目 - DS4Windows项目,因为DualShock4蓝牙控制器作为香草USB HID设备连接。看看他们的来源:https://github.com/Jays2Kings/DS4Windows,特别是他们的HidDevices.EnumerateDevices方法:

    private static IEnumerable<DeviceInfo> EnumerateDevices()
    {
        var devices = new List<DeviceInfo>();
        var hidClass = HidClassGuid;
        var deviceInfoSet = NativeMethods.SetupDiGetClassDevs(ref hidClass, null, 0, NativeMethods.DIGCF_PRESENT | NativeMethods.DIGCF_DEVICEINTERFACE);

        if (deviceInfoSet.ToInt64() != NativeMethods.INVALID_HANDLE_VALUE)
        {
            var deviceInfoData = CreateDeviceInfoData();
            var deviceIndex = 0;

            while (NativeMethods.SetupDiEnumDeviceInfo(deviceInfoSet, deviceIndex, ref deviceInfoData))
            {
                deviceIndex += 1;

                var deviceInterfaceData = new NativeMethods.SP_DEVICE_INTERFACE_DATA();
                deviceInterfaceData.cbSize = Marshal.SizeOf(deviceInterfaceData);
                var deviceInterfaceIndex = 0;

                while (NativeMethods.SetupDiEnumDeviceInterfaces(deviceInfoSet, ref deviceInfoData, ref hidClass, deviceInterfaceIndex, ref deviceInterfaceData))
                {
                    deviceInterfaceIndex++;
                    var devicePath = GetDevicePath(deviceInfoSet, deviceInterfaceData);
                    var description = GetBusReportedDeviceDescription(deviceInfoSet, ref deviceInfoData) ?? 
                                      GetDeviceDescription(deviceInfoSet, ref deviceInfoData);
                    devices.Add(new DeviceInfo { Path = devicePath, Description = description });
                }
            }
            NativeMethods.SetupDiDestroyDeviceInfoList(deviceInfoSet);
        }
        return devices;
    }

答案 1 :(得分:0)

如果您要与之通话的设备有RS232连接,则需要转换器。规格不一样,无法将USB电缆连接到RS232端口。