一、开发环境配置
1. 驱动与库文件
下载官方驱动包(含
ControlCAN.dll和controlcan.h)将动态库文件放置于项目输出目录
NuGet引用:
<PackageReference Include="System.Management" Version="8.0.0" /> <PackageReference Include="SharpUSB" Version="1.2.0" />
2. 设备权限配置(Linux)
# 赋予USB设备访问权限
sudo chmod 777 /dev/bus/usb/001/*
二、核心代码实现
1. 设备管理类(DeviceManager.cs)
using System;
using System.Runtime.InteropServices;
public class DeviceManager : IDisposable
{
[DllImport("ControlCAN.dll", CharSet = CharSet.Auto)]
private static extern int VCI_OpenDevice(int deviceType, int deviceIndex, int reserved);
[DllImport("ControlCAN.dll")]
private static extern int VCI_InitCAN(int deviceType, int deviceIndex, int canIndex, ref VCI_INIT_CONFIG config);
private int _deviceHandle;
public bool Connect(int deviceType = 4, int deviceIndex = 0, int canIndex = 0)
{
_deviceHandle = VCI_OpenDevice(deviceType, deviceIndex, 0);
if (_deviceHandle != 1) return false;
VCI_INIT_CONFIG config = new VCI_INIT_CONFIG
{
AccCode = 0,
AccMask = 0xFFFFFFFF,
Filter = 1,
Mode = 0,
Timing0 = 0x00,
Timing1 = 0x1C // 1Mbps波特率
};
return VCI_InitCAN(deviceType, deviceIndex, canIndex, ref config) == 1;
}
public void Disconnect()
{
VCI_CloseDevice(4, 0);
_deviceHandle = 0;
}
public struct VCI_INIT_CONFIG
{
public int AccCode;
public int AccMask;
public int Filter;
public int Mode;
public int Timing0;
public int Timing1;
}
}
三、数据通信模块
1. 接收线程实现
public class CanReceiver
{
private readonly DeviceManager _manager;
private Thread _receiveThread;
private bool _isRunning;
public event EventHandler<CanFrame> FrameReceived;
public CanReceiver(DeviceManager manager)
{
_manager = manager;
}
public void Start()
{
_receiveThread = new Thread(ReceiveLoop);
_receiveThread.Start();
}
private void ReceiveLoop()
{
const int bufferSize = 5000;
VCI_CAN_OBJ[] buffer = new VCI_CAN_OBJ[bufferSize];
while (_isRunning)
{
int count = VCI_Receive(4, 0, 0, buffer, bufferSize, 1000);
if (count > 0)
{
for (int i = 0; i < count; i++)
{
var frame = new CanFrame
{
ID = buffer[i].ID,
Data = BitConverter.GetBytes(buffer[i].Data[0] << 24 | buffer[i].Data[1] << 16 |
buffer[i].Data[2] << 8 | buffer[i].Data[3])
};
FrameReceived?.Invoke(this, frame);
}
}
}
}
public void Stop()
{
_isRunning = false;
_receiveThread.Join();
}
}
public struct CanFrame
{
public uint ID;
public byte[] Data;
}
四、高级功能实现
1. 数据发送
public bool SendFrame(CanFrame frame)
{
VCI_CAN_OBJ sendObj = new VCI_CAN_OBJ
{
ID = frame.ID,
SendType = 0,
RemoteFlag = 0,
ExternFlag = 0,
DataLen = (byte)frame.Data.Length,
Data = BitConverter.GetBytes(BitConverter.ToUInt32(frame.Data, 0))
};
return VCI_Transmit(4, 0, 0, ref sendObj, 1) == 1;
}
2. 错误处理
public string GetLastError()
{
VCI_ERR_INFO errInfo = new VCI_ERR_INFO();
VCI_ReadErrInfo(4, 0, 0, ref errInfo);
return $"错误码: 0x{errInfo.ErrCode:X4}, 错误信息: {errInfo.ErrInfo}";
}
五、跨平台适配方案
1. Linux环境配置
// 使用SharpUSB替代Windows API
public class LinuxCanDevice : IDisposable
{
private UsbDeviceHandle _handle;
public bool Connect(string vendorId = "0403", string productId = "6001")
{
_handle = Usb.OpenDevice(vendorId, productId);
if (_handle == null) return false;
// 配置CAN参数
byte[] config = {
0x01, 0x02, 0x03, 0x04 };
_handle.Write(config);
return true;
}
}
六、性能优化
双缓冲机制
private CircularBuffer _buffer = new CircularBuffer(1024); // 数据接收 _buffer.Write(buffer, count);异步处理
public async Task ProcessDataAsync() { await Task.Run(() => { while (_isRunning) { var frame = _buffer.Read(); // 处理数据 } }); }硬件加速
// 启用DMA传输 VCI_SetTransferMode(4, 0, 0, VCI_TRANSFER_MODE.DMA);
七、调试与测试工具
1. 数据监控器
public class CanMonitor : Form
{
private DataGridView _dataGridView;
public void UpdateData(CanFrame frame)
{
_dataGridView.Invoke((MethodInvoker)delegate {
_dataGridView.Rows.Add(frame.ID.ToString("X8"),
BitConverter.ToString(frame.Data));
});
}
}
2. 流量统计
public class TrafficStats
{
private long _rxCount;
private long _txCount;
public void IncrementRx() => Interlocked.Increment(ref _rxCount);
public void IncrementTx() => Interlocked.Increment(ref _txCount);
public string GetStats() =>
$"接收: {_rxCount}帧 | 发送: {_txCount}帧";
}
八、部署与维护
安装包制作
<!-- WiX安装配置 --> <Component Id="CanDriver" Guid="*"> <File Id="ControlCAN" Name="ControlCAN.dll" Source="lib\ControlCAN.dll"/> <RegistryValue Root="HKLM" Key="Software\ZLG\USBCAN" Name="InstallDir" Value="[INSTALLDIR]"/> </Component>自动更新
public class AutoUpdater { public void CheckUpdate() { var version = File.ReadAllText("version.txt"); if (version != LatestVersion) { // 执行更新流程 } } }
参考代码 基于周立功USB 转CAN设备开发 www.youwenfan.com/contentali/112018.html
九、扩展应用场景
工业自动化监控
// PLC数据采集 public class PlcInterface { public void ReadRegister(int address) { SendFrame(new CanFrame { ID = 0x100, Data = BitConverter.GetBytes(address) }); } }汽车诊断系统
public class DiagnosticTool { public DiagnosticResponse ReadDTC() { SendFrame(new CanFrame { ID = 0x7DF, Data = new byte[] { 0x03,0x01,0x00} }); return WaitForResponse(0x7E8); } }