class API
{
[DllImport("controlcan.dll")]
public static extern UInt32 VCI_OpenDevice(UInt32 DeviceType, UInt32 DeviceInd, UInt32 Reserved);
[DllImport("controlcan.dll")]
public static extern UInt32 VCI_CloseDevice(UInt32 DeviceType, UInt32 DeviceInd);
[DllImport("controlcan.dll")]
public static extern UInt32 VCI_InitCAN(UInt32 DeviceType, UInt32 DeviceInd, UInt32 CANInd, ref VCI_INIT_CONFIG pInitConfig);
[DllImport("controlcan.dll")]
public static extern UInt32 VCI_ReadBoardInfo(UInt32 DeviceType, UInt32 DeviceInd, ref VCI_BOARD_INFO pInfo);
[DllImport("controlcan.dll")]
public static extern UInt32 VCI_GetReceiveNum(UInt32 DeviceType, UInt32 DeviceInd, UInt32 CANInd);
[DllImport("controlcan.dll")]
public static extern UInt32 VCI_ClearBuffer(UInt32 DeviceType, UInt32 DeviceInd, UInt32 CANInd);
[DllImport("controlcan.dll")]
public static extern UInt32 VCI_StartCAN(UInt32 DeviceType, UInt32 DeviceInd, UInt32 CANInd);
[DllImport("controlcan.dll")]
public static extern UInt32 VCI_ResetCAN(UInt32 DeviceType, UInt32 DeviceInd, UInt32 CANInd);
[DllImport("controlcan.dll")]
public static extern UInt32 VCI_Transmit(UInt32 DeviceType, UInt32 DeviceInd, UInt32 CANInd, ref VCI_CAN_OBJ pSend, UInt32 Len);
[DllImport("controlcan.dll")]
public static extern UInt32 VCI_Receive(UInt32 DeviceType, UInt32 DeviceInd, UInt32 CANInd, ref VCI_CAN_OBJ pReceive, UInt32 Len, Int32 WaitTime);
[DllImport("controlcan.dll")]
public static extern UInt32 VCI_ConnectDevice(UInt32 DevType, UInt32 DevIndex);
[DllImport("controlcan.dll")]
public static extern UInt32 VCI_UsbDeviceReset(UInt32 DevType, UInt32 DevIndex, UInt32 Reserved);
[DllImport("controlcan.dll")]
public static extern UInt32 VCI_FindUsbDevice(ref VCI_BOARD_INFO1 pInfo);
[DllImport("controlcan.dll")]
public static extern UInt32 VCI_FindUsbDevice2(ref VCI_BOARD_INFO pInfo);
}
2.C# 与C++对应的数据模型
//1.ZLGCAN系列接口卡信息的数据类型。
public struct VCI_BOARD_INFO
{
public UInt16 hw_Version;
public UInt16 fw_Version;
public UInt16 dr_Version;
public UInt16 in_Version;
public UInt16 irq_Num;
public byte can_Num;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)]
public byte[] str_Serial_Num;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 40)]
public byte[] str_hw_Type;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
public byte[] Reserved;
}
/
//2.定义CAN信息帧的数据类型。
unsafe public struct VCI_CAN_OBJ //使用不安全代码
{
public uint ID;
public uint TimeStamp; //时间标识
public byte TimeFlag; //是否使用时间标识
public byte SendType; //发送标志。保留,未用
public byte RemoteFlag; //是否是远程帧
public byte ExternFlag; //是否是扩展帧
public byte DataLen; //数据长度
public fixed byte Data[8]; //数据
public fixed byte Reserved[3];//保留位
}
//3.定义初始化CAN的数据类型
public struct VCI_INIT_CONFIG
{
public UInt32 AccCode;
public UInt32 AccMask;
public UInt32 Reserved;
public byte Filter; //0或1接收所有帧。2标准帧滤波,3是扩展帧滤波。
public byte Timing0; //波特率参数,具体配置,请查看二次开发库函数说明书。
public byte Timing1;
public byte Mode; //模式,0表示正常模式,1表示只听模式,2自测模式
}
//4.USB-CAN总线适配器板卡信息的数据类型1,该类型为VCI_FindUsbDevice函数的返回参数。
public struct VCI_BOARD_INFO1
{
public UInt16 hw_Version;
public UInt16 fw_Version;
public UInt16 dr_Version;
public UInt16 in_Version;
public UInt16 irq_Num;
public byte can_Num;
public byte Reserved;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)] public byte[] str_Serial_Num;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
public byte[] str_hw_Type;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
public byte[] str_Usb_Serial;
}
public struct CHGDESIPANDPORT
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)]
public byte[] szpwd;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)]
public byte[] szdesip;
public Int32 desport;
public void Init()
{
szpwd = new byte[10];
szdesip = new byte[20];
}
}
public enum DevType
{
DEV_USBCAN = 3,
DEV_USBCAN2 = 4
}
public class Data
{
public static Dictionary Bitrate = new Dictionary()
{
{10000, new byte[]{0x31,0x1C}},
{20000, new byte[]{0x18,0x1C}},
{40000, new byte[]{0x87,0xFF}},
{50000, new byte[]{0x09,0x1C}},
{80000, new byte[]{0x83,0xFF}},
{100000, new byte[]{0x04,0x1C}},
{125000, new byte[]{0x03,0x1C}},
{200000, new byte[]{0x81,0xFA}},
{250000, new byte[]{0x01,0x1C}},
{400000, new byte[]{0x80,0xFA}},
{500000, new byte[]{0x00,0x1C}},
{666000, new byte[]{0x80,0xB6}},
{800000, new byte[]{0x00,0x16}},
{1000000, new byte[]{0x00,0x14}},
{33330, new byte[]{0x09,0x6F}},
{66660, new byte[]{0x04,0x6F}},
{83330, new byte[]{0x03,0x6F}},
};
}
3. C#动态库实现
///4.使用/// 珠海创芯科技CAN总线分析仪 /// public class CAN_zhcxgd : InterfaceCAN { private readonly object lock_send = new object(); private VCI_CAN_OBJ[] _vCI_CAN_OBJs = new VCI_CAN_OBJ[2500]; private DevType _devType = DevType.DEV_USBCAN2; private uint _devIndex = 0; private int _bitrate; public byte[] Bitrate { get => Data.Bitrate[_bitrate]; } public uint int_DevType { get => (uint)_devType; } public uint ChannelCount { get => _devType == DevType.DEV_USBCAN ? (uint)1 : (uint)2; } public void SetParameters(int devIndex, int bitrate, params object[] parms) { _devIndex = (uint)devIndex; _bitrate = bitrate; } public bool Close() { var result = API.VCI_CloseDevice(int_DevType, _devIndex); return result == 1; } public bool Open() { var result = API.VCI_OpenDevice(int_DevType, _devIndex, 0) == 1; if (!result) return false; result = Start(Bitrate); if (!result) return false; return true; } public bool Send(FrameData frameData) { lock (lock_send) { VCI_CAN_OBJ vCI_CAN_OBJ = new VCI_CAN_OBJ(); vCI_CAN_OBJ.RemoteFlag = frameData.RemoteFlag; vCI_CAN_OBJ.ExternFlag = frameData.ExternFlag; vCI_CAN_OBJ.ID = (uint)frameData.Id; vCI_CAN_OBJ.DataLen = frameData.DataLen; WriteUnsafeData(ref vCI_CAN_OBJ, frameData.Data); var result = API.VCI_Transmit(int_DevType, _devIndex, (uint)frameData.ChannelId, ref vCI_CAN_OBJ, 1); return result == 1; } } public ListReceive() { List frameDatas = new List (); for (int i = 0; i < ChannelCount; i++) { frameDatas.AddRange(Receive((uint)i)); } return frameDatas; } private List Receive(uint channelId) { var result = API.VCI_Receive(int_DevType, _devIndex, channelId, ref _vCI_CAN_OBJs[0], 2500, 100); if (result < 0) return null; List receiveDatas = new List (); for (int i = 0; i < result; i++) { FrameData receiveData = new FrameData(); receiveData.ChannelId = (int)channelId; receiveData.Id = (int)_vCI_CAN_OBJs[i].ID; receiveData.DataLen = _vCI_CAN_OBJs[i].DataLen; receiveData.Data = ReadUnsafeData(ref _vCI_CAN_OBJs[i]); receiveData.TimeStamp = (long)_vCI_CAN_OBJs[i].TimeStamp; receiveData.RemoteFlag = _vCI_CAN_OBJs[i].RemoteFlag; receiveData.ExternFlag = _vCI_CAN_OBJs[i].ExternFlag; receiveData.SendType = _vCI_CAN_OBJs[i].SendType; receiveData.TimeFlag = _vCI_CAN_OBJs[i].TimeFlag; unsafe { receiveData.Reserved = new byte[3]; receiveData.Reserved[0] = _vCI_CAN_OBJs[i].Reserved[0]; receiveData.Reserved[1] = _vCI_CAN_OBJs[i].Reserved[1]; receiveData.Reserved[2] = _vCI_CAN_OBJs[i].Reserved[2]; } receiveDatas.Add(receiveData); } return receiveDatas; } unsafe private void WriteUnsafeData(ref VCI_CAN_OBJ data, byte[] buffer) { fixed (byte* ptr = data.Data) for (int i = 0; i < buffer.Length; i++) { ptr[i] = buffer[i]; } } unsafe private byte[] ReadUnsafeData(ref VCI_CAN_OBJ data) { var buffer = new byte[data.DataLen]; fixed (byte* ptr = data.Data) for (int index = 0; index < data.DataLen; index++) { buffer[index] = ptr[index]; } return buffer; } /// /// 启动CAN /// /// ///private bool Start(byte[] bitrate) { for (uint i = 0; i < ChannelCount; i++) { if (!Init(i, bitrate)) return false; if (!Start(i)) return false; } return true; } private bool Init(uint channelNum, byte[] bitrate) { VCI_INIT_CONFIG config = new VCI_INIT_CONFIG(); config.AccCode = Convert.ToUInt32("0x00000000", 16); config.AccMask = Convert.ToUInt32("0xFFFFFFFF", 16); config.Timing0 = bitrate[0]; config.Timing1 = bitrate[1]; config.Filter = 1; config.Mode = 0; var result = API.VCI_InitCAN(int_DevType, _devIndex, channelNum, ref config); return result == 1; } private bool Start(uint channelNum) { var result = API.VCI_StartCAN(int_DevType, _devIndex, channelNum); return result == 1; } }
static void Main(string[] args)
{
CAN_zhcxgd cAN_Zhcxgd = new CAN_zhcxgd();
cAN_Zhcxgd.SetParameters(0, 100000);
cAN_Zhcxgd.Open();
cAN_Zhcxgd.Send(new FrameData() { ChannelId = 0, Id = 1, Data = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 }, DataLen = 8 });
List frameDatas = cAN_Zhcxgd.Receive();
foreach (FrameData frameData in frameDatas)
{
//做点什么
}
}
5.源码以及CANPlus.cs(自用dll)
源码
暑期编程PK赛 得CSDN机械键盘等精美礼品!


