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

本文关键字:USB 通过 数据 不了解 协议 情况下 | 更新日期: 2023-09-27 18:33:06

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

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

对于 USB

设备制造商,执行此操作的可靠方法是使用 USB HID 类驱动程序 - 当设备连接到主机时,它会通过 USB 通道将自身标识为支持通用 USB HID 的设备。当计算机看到该设备和这些标识时,它会立即启动通用 USB HID 驱动程序的实例,并将其附加到该终结点。驱动程序公开一个简单的文件句柄接口,允许你读取和写入原始字节到设备。

用户土地程序使用 HID API 枚举所有 HID 设备,按供应商 ID 和产品 ID 字段筛选枚举的设备,以查找所需的特定设备。接下来,可以获取设备驱动程序的用户地接口的 Windows 对象管理器"路径"。在该路径上调用CreateFile以打开驱动程序的文件句柄,然后读取和写入你的心。您读取和写入的内容只是发送到设备的字节流。

实现此目的所需的相关 API:

  • HidD_GetHidGuid
  • SetupDiGetClassDevs
  • 设置设备接口
  • SetupDiGetDeviceInterfaceDetail
  • 创建文件
  • HidD_GetAttributes
  • HidD_GetPreparsedData
  • HidD_FreePreparsedData
  • HidP_GetCaps
  • HidD_GetSerialNumberString
  • HidD_...等

互联网上有几个项目可以做到这一点 - 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;
    }

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