C#实现USB数据收发

一、技术选型对比

库名称 适用场景 优势 局限性
LibUsbDotNet 通用USB设备通信 跨平台支持,API完善 需要安装libusb驱动
HidSharp HID类设备(键盘/鼠标等) 封装简单,支持异步通信 仅限HID协议设备
Windows API 定制化USB开发 直接操作底层接口 代码复杂度高

二、核心实现方案(基于LibUsbDotNet)

1. 设备枚举与连接

using LibUsbDotNet;
using LibUsbDotNet.Main;

public class UsbService {
    private UsbDevice _device;
    private UsbEndpointReader _reader;
    private UsbEndpointWriter _writer;

    // 初始化设备
    public bool Connect(int vid, int pid) {
        var finder = new UsbDeviceFinder(vid, pid);
        _device = UsbDevice.OpenUsbDevice(finder);

        if (_device == null) return false;

        try {
            _device.Open();
            IUsbDevice wholeDevice = _device as IUsbDevice;
            if (wholeDevice != null) {
                wholeDevice.SetConfiguration(1);
                wholeDevice.ClaimInterface(0);
            }

            _reader = _device.OpenEndpointReader(ReadEndpointID.Ep01);
            _writer = _device.OpenEndpointWriter(WriteEndpointID.Ep01);
            return true;
        } catch {
            _device.Close();
            return false;
        }
    }

    // 断开连接
    public void Disconnect() {
        _reader?.Dispose();
        _writer?.Dispose();
        _device?.Close();
        UsbDevice.Exit();
    }
}

2. 数据传输实现

// 同步发送数据
public int SendData(byte[] data) {
    int bytesWritten;
    ErrorCode ec = _writer.Write(data, 1000, out bytesWritten);
    return ec == ErrorCode.None ? bytesWritten : -1;
}

// 同步接收数据
public byte[] ReceiveData() {
    byte[] buffer = new byte[1024];
    int bytesRead;
    ErrorCode ec = _reader.Read(buffer, 5000, out bytesRead);
    return ec == ErrorCode.None ? buffer.Take(bytesRead).ToArray() : null;
}

// 异步接收(推荐)
public async Task<byte[]> AsyncReceive() {
    var buffer = new byte;
    var readTask = _reader.ReadAsync(buffer, 5000);
    await readTask.ConfigureAwait(false);
    return readTask.Result.Length > 0 
        ? readTask.Result.Take(readTask.Result.Length).ToArray() 
        : null;
}

三、高级功能实现

1. 控制传输(配置设备)

public void SendControlCommand(byte requestType, byte request, ushort value, ushort index, byte[] data) {
    int transferred;
    _device.ControlTransfer(
        (LibUsbDotNet.Main.ControlTransferFlags)requestType,
        request,
        value,
        index,
        data,
        data.Length,
        out transferred,
        5000);
}

2. 批量传输(高速数据)

// 配置批量端点
public void ConfigureBulkTransfer() {
    var deviceDesc = _device.DeviceDescriptor;
    _writer = _device.OpenEndpointWriter(
        ReadEndpointID.Ep02, // 批量输入端点
        512,                 // 最大包尺寸
        EndpointDirection.In);
}

// 执行批量传输
public int BulkWrite(byte[] data) {
    int bytesWritten;
    _writer.Write(data, 1000, out bytesWritten);
    return bytesWritten;
}

四、工程实践要点

1. 设备热插拔检测

public static class UsbHotplug {
    private static UsbDeviceList _devices = new();

    public static void MonitorChanges(Action<UsbDevice> added, Action<UsbDevice> removed) {
        _devices = UsbDevice.AllDevices;
        Timer timer = new Timer(_ => {
            var current = UsbDevice.AllDevices;
            var addedDevices = current.Except(_devices).ToList();
            var removedDevices = _devices.Except(current).ToList();
            
            addedDevices.ForEach(added);
            removedDevices.ForEach(removed);
            
            _devices = current;
        }, null, 1000, 1000);
    }
}

2. 数据校验机制

// CRC16校验
public ushort CalculateCRC(byte[] data) {
    ushort crc = 0xFFFF;
    foreach (byte b in data) {
        crc ^= (ushort)(b << 8);
        for (int i = 0; i < 8; i++) {
            crc <<= 1;
            if ((crc & 0x10000) != 0) crc ^= 0x1021;
        }
    }
    return crc;
}

// 数据封装
public byte[] CreatePacket(byte[] payload) {
    ushort crc = CalculateCRC(payload);
    return new byte[] { 0xAA, 0x55 } 
        .Concat(payload)
        .Concat(BitConverter.GetBytes(crc))
        .ToArray();
}

五、调试与优化

1. 调试工具推荐

  • USBView:查看设备拓扑和端点信息
  • Wireshark+USBPcap:抓取USB通信数据包
  • Bus Hound:实时监控USB数据流量

2. 性能优化方案

// 双缓冲区技术
private byte[] _bufferA = new byte;
private byte[] _bufferB = new byte;
private bool _useBufferA = true;

// 零拷贝传输
public async Task<int> HighSpeedTransfer(byte[] data) {
    var buffer = _useBufferA ? _bufferA : _bufferB;
    Array.Copy(data, buffer, data.Length);
    _useBufferA = !_useBufferA;
    
    return await _writer.WriteAsync(buffer, 100);
}

参考代码 C# USB 发送和接收数据 www.youwenfan.com/contentcno/92801.html

六、完整项目结构

USBCommunication/
├── Libs/                # 第三方库
│   └── LibUsbDotNet.dll
├── Devices/             # 设备配置
│   └── DeviceConfig.json
├── Src/
│   ├── UsbService.cs    # 核心通信类
│   ├── ProtocolHandler.cs # 协议解析
│   └── HotplugMonitor.cs
└── Tests/               # 单元测试
    └── UsbCommunicationTests.cs

七、常见问题解决方案

  1. 访问被拒绝 以管理员身份运行程序 使用Zadig工具安装WinUSB驱动
  2. 数据丢失 增加数据包序号校验 设置合理的超时时间(建议500-2000ms)
  3. 设备识别失败 检查VID/PID是否正确 使用lsusb(Linux)或USBDeview(Windows)验证设备状态

该方案支持HID设备、CDC类设备等多种USB通信场景,可通过扩展以下功能增强系统:

  • 多设备并发:使用ConcurrentDictionary管理多个连接
  • 固件升级:实现DFU协议支持
  • 加密传输:集成AES-256加密算法
posted @ 2025-12-23 16:18  别说我的眼泪有点咸  阅读(5)  评论(0)    收藏  举报