1数据类型:
1 BOARD_INFO 设备信息
2 CAN_OBJ 数据帧对象
3 CAN_STATUS CAN通道状态
4 ERR_INFO 错误信息
5 INIT_CONFIG 设备配置参数
6 FILTER_RECORD 过滤帧配置参数
//接口函数结果【0】失败【1】成功
public enum ECANStatus:int
{
/// <summary>
/// error【0】
/// </summary>
STATUS_ERR = 0x00000,
/// <summary>
/// No error【1】
/// </summary>
STATUS_OK = 0x00001,
}
//【1】 设备信息
public struct BOARD_INFO
{
public ushort hw_Version;//【0x012d】硬件版本,V1.2D
public ushort fw_Version;//【0x0103】固件版本,v1.03
public ushort dr_Version;//【0x0100】驱动版本,v1.00
public ushort in_Version;//【0x0101】接口版本,v1.01
public ushort irq_Num; //【0x00】 保留参数。
public byte can_Num; //【0x32】 支持CAN通道数50。
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)]
public char[] str_Serial_Num;// 板卡序列号。【GC231006274】
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 40)]
public char[] str_hw_Type; // 设备名称【USB31】USB3.1
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
public ushort[] Reserved; // 保留
}
//【2】 数据帧对象
public struct CAN_OBJ
{
public uint ID;// 帧ID。 【u32】帧id,标准帧11bit,扩展帧29bit。
public uint TimeStamp; //【u32】时间值。从CAN卡上电开始计时,计时单位为0.1ms。
public byte TimeFlag; // 标志位,【1】TimeStamp值有效
public byte SendType; // 发送类型。【0】正常发送(失败有重发)【1】单次发送
public byte RemoteFlag; // 远帧标志。【0】数据帧【1】远程帧(数据段空,用于呼叫从站)。
public byte ExternFlag; // 扩展帧标志【0】标准帧(11位ID),【1】扩展帧(29位ID)。
public byte DataLen; // 单帧有效字节 DLC (<=8)约束了后面Data[8]中有效字节数。
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
public byte[] Data; // 数据包,如DataLen为3,Data[0]、Data[1]、Data[2]是有效的。
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
public byte[] Reserved; // 保留。
}
public struct VCI_CAN_OBJ
{
public UInt32 ID;// 帧ID。 【u32】帧id,标准帧11bit,扩展帧29bit。
public UInt32 TimeStamp; //【u32】时间值。从CAN卡上电开始计时,计时单位为0.1ms。
public byte TimeFlag; // 标志位,【1】TimeStamp值有效
public byte SendType; // 发送类型。【0】正常发送(失败有重发)【1】单次发送
public byte RemoteFlag; // 远帧标志。【0】数据帧【1】远程帧(数据段空,用于呼叫从站)。
public byte ExternFlag; // 扩展帧标志【0】标准帧(11位ID),【1】扩展帧(29位ID)。
public byte DataLen; // 单帧有效字节 DLC (<=8)约束了后面Data[8]中有效字节数。
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
public byte[] Data; // 数据包,如DataLen为3,Data[0]、Data[1]、Data[2]是有效的。
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
public byte[] Reserved; // 保留。
}
//【3】 CAN通道状态
public struct CAN_STATUS
{
public uchar ErrInterrupt; //中断错误记录,读操作会清除。
public uchar regMode; //CAN 模式。
public uchar regStatus; //CAN 状态。
public uchar regALCapture; //CAN 仲裁丢失。
public uchar regECCapture; //CAN 错误。
public uchar regEWLimit; //CAN 错误警告限制。
public uchar regRECounter; //CAN控制器接收错误。
public uchar regTECounter; //CAN控制器发送错误。
public int Reserved; // 保留。
}
//【4】 错误信息
public struct ERR_INFO
{
public UInt32 ErrCode; //错误码。
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
public byte[] Passive_ErrData;//消极错误【被动】
public byte ArLost_ErrData; //仲裁丢失错误
}
//【ErrCode】
// 0x0100 设备已经打开
// 0x0200 打开设备错误
// 0x0400 设备没有打开
// 0x0800 缓冲区溢出
// 0x1000 此设备不存在
// 0x2000 装载动态库失败
// 0x4000 表示为执行命令失败错误
// 0x8000 内存不足
// 0x0001 CAN控制器内部FIFO溢出
// 0x0002 CAN控制器错误报警
// 0x0004 CAN控制器消极错误【具体值见表A消极】
// 0x0008 CAN控制器仲裁丢失【具体值见表B仲裁】
// 0x0010 CAN控制器总线错误
// 0x0020 CAN接收寄存器满
// 0x0040 CAN接收寄存器溢出
// 0x0080 CAN控制器主动错误【具体值见表B仲裁】
//【5】 设备配置参数
public struct INIT_CONFIG
{
public uint AccCode; //【左对齐】帧id的bit完全匹配才接收
public uint AccMask; //【左对齐】帧id的bit【1】为失效AccCode
public uint Reserved; // 保留。
public byte Filter; // 滤帧使能。【0】不使能,【1】使能。
public byte Timing0; // 波特率 1MHz【t0=0x00,t1=0x14】
public byte Timing1; // 波特率
public byte Mode; // 工作模式。【0】正常收发【1】只收【2】环回(中继)
}
// 5kbps t0t1 0xBF,0xFF
// 10kbps t0t1 0x31,0x1C
// 20kbps t0t1 0x18,0x1C
// 40kbps t0t1 0x87,0xFF
// 50kbps t0t1 0x09,0x1C
// 80kbps t0t1 0x83,0xFF
// 100kbps t0t1 0x04,0x1C
// 125kbps t0t1 0x03,0x1C
// 200kbps t0t1 0x81,0xFA
// 250kbps t0t1 0x01,0x1C
// 400kbps t0t1 0x80,0xFA
// 500kbps t0t1 0x00,0x1C
// 666kbps t0t1 0x80,0xB6
// 800kbps t0t1 0x00,0x16
//1000kbps t0t1 0x00,0x14
//
//【6】 滤帧设置【只接收满足条件的帧】
public struct FILTER_RECORD
{
public UInt32 ExtFrame; //滤帧类型【0】只收标准帧【1】只收扩展帧
public UInt32 Start; //帧起始id
public UInt32 End; //帧结束id
}
2接口函数:
1.5.1 OpenDevice .................................打开设备
1.5.2 CloseDevice ................................关闭设备
1.5.3 InitCAN .........................................初始化CAN通道
1.5.4 ReadBoardInfo ............................读设备信息
1.5.5 ReadErrInfo .................................读错误信息
1.5.6 ReadCANStatus ...........................读设备状态
1.5.7 GetReference ..............................获取过滤帧配置参数。【PVOID *pData】
1.5.8 SetReference ..............................设置过滤帧配置参数。【VCI_FILTER_RECORD】
1.5.9 GetReceiveNum ..........................读接收缓冲区中帧数。【缓存<=10239帧】
1.5.10 ClearBuffer ................................清空CAN通道的缓冲区。【10240帧,触发丢弃】
1.5.11 StartCAN ...................................启动某一个CAN通道。
1.5.12 Transmit ....................................返回实际发送成功的帧数。
1.5.13 Receive .....................................读CAN数据帧。【单次取<=5帧】
1.5.14 ResetCAN .................................复位CAN通道。
ReadD
WriteD
ReadID
public static class Help_USB_SYGC_CAN //沈阳广成科技:GCAN分析仪
{
#region 接口函数
[DllImport("ECANVCI64.dll", EntryPoint = "OpenDevice")] //【1】打开设备
public static extern Status OpenDevice(
UInt32 DeviceType, //设备类型
UInt32 DeviceInd, //设备id
UInt32 Reserved); //保留。
[DllImport("ECANVCI64.dll", EntryPoint = "CloseDevice")] //【2】关闭设备
public static extern Status CloseDevice(
UInt32 DeviceType,
UInt32 DeviceInd);
[DllImport("ECANVCI64.dll", EntryPoint = "InitCAN")] //【3】初始化CAN通道
public static extern Status InitCAN(
UInt32 DeviceType, //设备类型
UInt32 DeviceInd, //设备id
UInt32 CANInd, //CAN通道id
ref INIT_CONFIG InitConfig);//配置参数
[DllImport("ECANVCI64.dll", EntryPoint = "ReadBoardInfo")]//【4】读设备信息
public static extern Status ReadBoardInfo(
UInt32 DeviceType,
UInt32 DeviceInd,
out BOARD_INFO Info);
[DllImport("ECANVCI64.dll", EntryPoint = "ReadErrInfo")] //【5】读错误信息
public static extern Status ReadErrInfo(
UInt32 DeviceType,
UInt32 DeviceInd,
UInt32 CANInd,
out ERR_INFO ErrInfo);//【 out CAN_ERR_INFO ReadErrInfo 】
[DllImport("ECANVCI64.dll", EntryPoint = "ReadCanStatus")]//【6】读取CAN状态
public static extern Status ReadCanStatus(
UInt32 DeviceType,
UInt32 DeviceInd,
UInt32 CANInd,
out CAN_STATUS CANStatus);
[DllImport("ECANVCI64.dll", EntryPoint = "GetReference")]//【7】读取滤帧配置参数
public static extern Status GetReference(
UInt32 DeviceType,
UInt32 DeviceInd,
UInt32 CANInd,
UInt32 RefType,
out FILTER_RECORD Data);
[DllImport("ECANVCI64.dll", EntryPoint = "SetReference")]//【8】设置滤帧配置参数
public static extern Status SetReference(
UInt32 DeviceType,
UInt32 DeviceInd,
UInt32 CANInd,
UInt32 RefType,// 【0】标准帧【1】扩展帧
ref FILTER_RECORD Data);
[DllImport("ECANVCI64.dll", EntryPoint = "GetReceiveNum")]//【9】缓冲区帧数<=10239帧
public static extern int GetReceiveNum(//缓冲区10240帧触发丢弃
UInt32 DeviceType,
UInt32 DeviceInd,
UInt32 CANInd);
[DllImport("ECANVCI64.dll", EntryPoint = "ClearBuffer")] //【10】清空缓冲区
public static extern Status ClearBuffer(
UInt32 DeviceType, //设备类型
UInt32 DeviceInd, //设备id
UInt32 CANInd); //CAN通道id
[DllImport("ECANVCI64.dll", EntryPoint = "StartCAN")] //【11】启动CAN通道
public static extern Status StartCAN(
UInt32 DeviceType,
UInt32 DeviceInd,
UInt32 CANInd);
[DllImport("ECANVCI64.dll", EntryPoint = "Transmit")] //【12】发送数据帧<=7000帧
public static extern Status Transmit(
UInt32 DeviceType,
UInt32 DeviceInd,
UInt32 CANInd,
CAN_OBJ[] Send,
UInt16 length);// 单次发送帧数
[DllImport("ECANVCI64.dll", EntryPoint = "Receive")]//【13】接收数据帧,<=5帧,返回-1故障
public static extern Status Receive(
UInt32 DeviceType,
UInt32 DeviceInd,
UInt32 CANInd,
out CAN_OBJ Receive,
UInt32 length, //单次读取帧数【封顶帧数】7为单次最多取7帧
UInt32 WaitTimeMs);//【0】不等待ms
[DllImport("ECANVCI64.dll", EntryPoint = "ResetCAN")]//【14】复位CAN通道
public static extern Status ResetCAN(
UInt32 DeviceType,
UInt32 DeviceInd,
UInt32 CANInd);
#endregion
}
3二次开发库:
广成的官方二次开发库,写的一坨屎。
大部分接口函数都有bug。【读CAN状态不能用】
【发10000帧,实际只有8000帧】【发20000帧,实际只有15000帧】
发3000帧 才 等于3000帧
【单次取帧只能小于5帧】【滤帧参数读不了】
using help;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.NetworkInformation;
using System.Runtime.InteropServices;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using static CAN_namespace.Help_USB_SYGC_CAN;
namespace CAN_namespace
{
#region 全局类型【声明】:通讯接口
/// <summary>
/// 全局类型:通讯接口
/// </summary>
public interface Iface_RTX // 开,关,收,发,轮询
{
/// <summary>
/// 连接
/// </summary>
/// <typeparam name="T">连接</typeparam>
/// <param name="a">ip地址</param>
/// <param name="b">端口</param>
/// <returns></returns>
bool connect<T>(T a, T b);// <string> "192.168.0.3","502"
/// <summary>
/// 断开
/// </summary>
/// <returns></returns>
bool Close();
/// <summary>
/// 只收
/// </summary>
/// <returns></returns>
int RXs(ref object obj);
//int RXs<T>(ref T obj);//测试
/// <summary>
/// 只发,格式148报文08123456781122334455667788
/// </summary>
/// <param name="cmd"></param>
/// <returns></returns>
bool TXs(string cmd);
/// <summary>
/// 轮询
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="cmd"></param>
/// <param name="t"></param>
/// <returns></returns>
bool sendAndReceive<T>(string cmd, ref T t);//万物皆文本
}
#endregion
public class Help_USB_SYGC_CAN : Iface_RTX // SYGC 沈阳广成科技有限公司
{//internal
//作者qq750273008 祁成 更新日期:2023.11.22
//===============================================
//[Browsable(true)] //可浏览
//[Category("自定义属性")] // 属性分栏
//[Description("属性的说明")] //
//================================================
#region 全局【数据类型】
//1申明委托》委托命令
public delegate void WT_GET_Data<T>(T ciA402);//↑ui显示发送命令
public delegate void WT_SET_Data(byte[] butes, string data);//↓下执行对象
#region CAN参数类型:全局;【设备类型,主板信息,单帧信息,配置表
//接口函数结果【0】失败【1】成功
public enum Status : int
{
/// <summary>
/// error【0】
/// </summary>
STATUS_ERR = 0x00000,
/// <summary>
/// No error【1】
/// </summary>
STATUS_OK = 0x00001,
}
/*------------兼容ZLG的数据类型---------------------------------*/
//1.设备类型
/// <summary>
/// 设备类型(单路,双路,以太网CAN)
/// </summary>
public enum DeviceType : byte //设备类型【USB_can】{单路,双路},【以太网_can】{单路,双路}
{
DEV_USBCAN = 3, // USB单路CAN
DEV_USBCAN2 = 4,// USB双路CAN
VCI_USBCAN1 = 3,
VCI_USBCAN2 = 4,// 我买的属于这个(创新科技CAN-Pro)
VCI_USBCAN2A = 4,
VCI_USBCAN_E_U = 20,// 以太网单路CAN
VCI_USBCAN_2E_U = 21// 以太网双路CAN
}
public enum RefType : byte
{
标准帧 = 0,
扩展帧 = 1
}
//【1】 设备信息
public struct BOARD_INFO
{
public ushort hw_Version;//【0x012d】硬件版本,V1.2d
public ushort fw_Version;//【0x0103】固件版本,v1.03
public ushort dr_Version;//【0x0100】驱动版本,v1.00
public ushort in_Version;//【0x0101】接口版本,v1.01
public ushort irq_Num; //【0x00】 保留参数。
public byte can_Num; //【0x32】 支持CAN通道数50。
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)]
public char[] str_Serial_Num;// 板卡序列号。【GC231006274】
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 40)]
public char[] str_hw_Type; // 设备名称【USB31】USB3.1
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
public ushort[] Reserved; // 保留
}
//【2】 数据帧对象
public struct CAN_OBJ
{
public UInt32 ID;// 帧ID。 【u32】帧id,标准帧11bit,扩展帧29bit。
public UInt32 TimeStamp; //【u32】时间值。从CAN卡上电开始计时,计时单位为0.1ms。
public byte TimeFlag; // 标志位,【1】TimeStamp值有效
public byte SendType; // 发送类型。【0】正常发送(失败有重发)【1】单次发送
public byte RemoteFlag; // 远帧标志。【0】数据帧【1】远程帧(数据段空,用于呼叫从站)。
public byte ExternFlag; // 扩展帧标志【0】标准帧(11位ID),【1】扩展帧(29位ID)。
public byte DataLen; // 单帧有效字节 DLC (<=8)约束了后面Data[8]中有效字节数。
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
public byte[] Data; // 数据包,如DataLen为3,Data[0]、Data[1]、Data[2]是有效的。
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
public byte[] Reserved; // 保留。
}
public struct VCI_CAN_OBJ
{
public UInt32 ID;// 帧ID。 【u32】帧id,标准帧11bit,扩展帧29bit。
public UInt32 TimeStamp; //【u32】时间值。从CAN卡上电开始计时,计时单位为0.1ms。
public byte TimeFlag; // 标志位,【1】TimeStamp值有效
public byte SendType; // 发送类型。【0】正常发送(失败有重发)【1】单次发送
public byte RemoteFlag; // 远帧标志。【0】数据帧【1】远程帧(数据段空,用于呼叫从站)。
public byte ExternFlag; // 扩展帧标志【0】标准帧(11位ID),【1】扩展帧(29位ID)。
public byte DataLen; // 单帧有效字节 DLC (<=8)约束了后面Data[8]中有效字节数。
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
public byte[] Data; // 数据包,如DataLen为3,Data[0]、Data[1]、Data[2]是有效的。
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
public byte[] Reserved; // 保留。
}
//【3】 CAN通道状态
public struct CAN_STATUS
{
public char ErrInterrupt; //中断错误记录,读操作会清除。
public char regMode; //CAN 模式。
public char regStatus; //CAN 状态。
public char regALCapture; //CAN 仲裁丢失。
public char regECCapture; //CAN 错误。
public char regEWLimit; //CAN 错误警告限制。
public char regRECounter; //CAN 接收错误。
public char regTECounter; //CAN 发送错误。
public int Reserved; // 保留。
}
//【4】 错误信息
public struct ERR_INFO
{
public UInt32 ErrCode; //错误码。
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
public byte[] Passive_ErrData;//消极错误【被动】
public byte ArLost_ErrData; //仲裁丢失错误
}
//【ErrCode】
// 0x0100 设备已经打开
// 0x0200 打开设备错误
// 0x0400 设备没有打开
// 0x0800 缓冲区溢出
// 0x1000 此设备不存在
// 0x2000 装载动态库失败
// 0x4000 表示为执行命令失败错误
// 0x8000 内存不足
// 0x0001 CAN控制器内部FIFO溢出
// 0x0002 CAN控制器错误报警
// 0x0004 CAN控制器消极错误【具体值见表A消极】
// 0x0008 CAN控制器仲裁丢失【具体值见表B仲裁】
// 0x0010 CAN控制器总线错误
// 0x0020 CAN接收寄存器满
// 0x0040 CAN接收寄存器溢出
// 0x0080 CAN控制器主动错误【具体值见表B仲裁】
//【5】 设备配置参数
public struct INIT_CONFIG
{
public UInt32 AccCode; //【左对齐】帧id的bit完全匹配才接收
public UInt32 AccMask; //【左对齐】帧id的bit【1】使对应AccCode的bit位失效
public UInt32 Reserved; // 保留。
public byte Filter; // 滤帧开关。【0】关,【1】开。
public byte Timing0; // 波特率 1MHz【t0=0x00,t1=0x14】
public byte Timing1; // 波特率
public byte Mode; // 工作模式。【0】正常收发【1】只收【2】环回(中继)
}
// 5kbps t0t1 0xBF,0xFF
// 10kbps t0t1 0x31,0x1C
// 20kbps t0t1 0x18,0x1C
// 40kbps t0t1 0x87,0xFF
// 50kbps t0t1 0x09,0x1C
// 80kbps t0t1 0x83,0xFF
// 100kbps t0t1 0x04,0x1C
// 125kbps t0t1 0x03,0x1C
// 200kbps t0t1 0x81,0xFA
// 250kbps t0t1 0x01,0x1C
// 400kbps t0t1 0x80,0xFA
// 500kbps t0t1 0x00,0x1C
// 666kbps t0t1 0x80,0xB6
// 800kbps t0t1 0x00,0x16
//1000kbps t0t1 0x00,0x14
//
//【6】 滤帧设置【只接收满足条件的帧】
public struct FILTER_RECORD
{
public UInt32 ExtFrame; //滤帧类型【0】只收标准帧【1】只收扩展帧
public UInt32 Start; //帧起始id
public UInt32 End; //帧结束id
}
4.定义配置CAN的数据类型
/ <summary>
/ 初始化_配置(参数表)
/ </summary>
//public struct VCI_INIT_CONFIG // 配置参数 设备【31F01031C93】v3.41
//{
// /// <summary>
// /// bit高低全部匹配,此帧才可以被接收。D31对应帧id最高位
// /// </summary>
// public UInt32 AccCode;// bit全部匹配,此帧才可以被接收。否则不能接收。(//标准帧右移21bit分析)
// // 相当于机械钥匙,凸起和凹槽必须匹配,才能开锁(接收)
// // b31对应帧id最高位,所以11bit要左移21bit(//分析标准帧时右移21bit)
// /// <summary>
// /// bit高,使AccCode对应的bit失效,D31对应帧id最高位
// /// </summary>
// public UInt32 AccMask;// 屏蔽码。使AccCode的某个bit功能失效。左对齐,bit31~bit21置1为屏蔽AccCode的bit匹配功能,
// // 相当于机械钥匙的bit销位,是否失效(bit置1为失效)
// // 。屏蔽码推荐设置为0xFFFFFFFF,即全部接收。
// public UInt32 Reserved;// 保留。
// public byte Filter; // 【1】接收所有帧。【2】只收标准帧,【3】只收扩展帧。
// public byte Timing0; //波特率参数,具体配置,请查看二次开发库函数说明书。(1Mbps):《Timing0=0x00,Timing1=0x14》
// public byte Timing1; // 0x14 //波特率参数 1MHz(T0=0x00,T1=0x14)
// public byte Mode; //模式【0】收发模式,【1】只收,【2】自测模式(环回模式)。
//}
/*------------其他数据结构描述---------------------------------*/
/// <summary>
/// T 结构体用于装载更改 CANET_UDP 与 CANET_TCP 的目标 IP 和
///端口的必要信息。此结构体在 CANETE_UDP 与 CANET_TCP 中使用。
/// </summary>
//public struct CHGDESIPANDPORT // 以太网can
//{
// [MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)]
// public byte[] szpwd;
// //更改目标 IP 和端口所需要的密码,长度小于 10,比如为“11223344”。
// [MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)]
// public byte[] szdesip;
// //所要更改的目标 IP,比如为“192.168.0.111”。
// public Int32 desport;
// //所要更改的目标端口,比如为 4000。
// public byte blisten;
// //所要更改的工作模式,0 表示正常模式,1 表示只听模式。
//}
//public struct VCI_FILTER_RECORD //滤帧配置【满足条件的才接收】
//{
// UInt32 ExtFrame;// 过滤的帧类型【1】过滤扩展帧【0】过滤标准帧。
// UInt32 Start;//起始帧ID
// UInt32 End; //结束帧ID
//}
/*------------数据结构描述完成---------------------------------*/
#endregion
#endregion
#region 字段【接口函数】
//private CancellationTokenSource cts;//线程令牌
//private ManualResetEvent resetEvent = new ManualResetEvent(true);// 暂停业务
//=====================================================
#region 接口函数
[DllImport("ECANVCI64.dll", EntryPoint = "OpenDevice")] //【1】打开设备
public static extern Status OpenDevice(
UInt32 DeviceType, //设备类型
UInt32 DeviceInd, //设备id
UInt32 Reserved); //保留。
[DllImport("ECANVCI64.dll", EntryPoint = "CloseDevice")] //【2】关闭设备
public static extern Status CloseDevice(
UInt32 DeviceType,
UInt32 DeviceInd);
[DllImport("ECANVCI64.dll", EntryPoint = "InitCAN")] //【3】初始化CAN通道
public static extern Status InitCAN(
UInt32 DeviceType, //设备类型
UInt32 DeviceInd, //设备id
UInt32 CANInd, //CAN通道id
ref INIT_CONFIG InitConfig);//配置参数
[DllImport("ECANVCI64.dll", EntryPoint = "ReadBoardInfo")]//【4】读设备信息
public static extern Status ReadBoardInfo(
UInt32 DeviceType,
UInt32 DeviceInd,
out BOARD_INFO Info);
[DllImport("ECANVCI64.dll", EntryPoint = "ReadErrInfo")] //【5】读错误信息
public static extern Status ReadErrInfo(
UInt32 DeviceType,
UInt32 DeviceInd,
UInt32 CANInd,
out ERR_INFO ErrInfo);//【 out CAN_ERR_INFO ReadErrInfo 】
[DllImport("ECANVCI64.dll", EntryPoint = "ReadCanStatus")]//【6】读取CAN状态
public static extern Status ReadCanStatus(
UInt32 DeviceType,
UInt32 DeviceInd,
UInt32 CANInd,
out CAN_STATUS CANStatus);
[DllImport("ECANVCI64.dll", EntryPoint = "GetReference")]//【7】读取滤帧配置参数
public static extern Status GetReference(
UInt32 DeviceType,
UInt32 DeviceInd,
UInt32 CANInd,
UInt32 RefType,
out FILTER_RECORD Data);
[DllImport("ECANVCI64.dll", EntryPoint = "SetReference")]//【8】设置滤帧配置参数
public static extern Status SetReference(
UInt32 DeviceType,
UInt32 DeviceInd,
UInt32 CANInd,
UInt32 RefType,// 【0】标准帧【1】扩展帧
ref FILTER_RECORD Data);
[DllImport("ECANVCI64.dll", EntryPoint = "GetReceiveNum")]//【9】缓冲区帧数<=10239帧
public static extern Int32 GetReceiveNum(//缓冲区10240帧触发丢弃
UInt32 DeviceType,
UInt32 DeviceInd,
UInt32 CANInd);
[DllImport("ECANVCI64.dll", EntryPoint = "ClearBuffer")] //【10】清空缓冲区
public static extern Status ClearBuffer(
UInt32 DeviceType, //设备类型
UInt32 DeviceInd, //设备id
UInt32 CANInd); //CAN通道id
[DllImport("ECANVCI64.dll", EntryPoint = "StartCAN")] //【11】启动CAN通道
public static extern Status StartCAN(
UInt32 DeviceType,
UInt32 DeviceInd,
UInt32 CANInd);
[DllImport("ECANVCI64.dll", EntryPoint = "Transmit")] //【12】发送数据帧<=7000帧
public static extern Int32 Transmit(//Status
UInt32 DeviceType,
UInt32 DeviceInd,
UInt32 CANInd,
CAN_OBJ[] Send,
UInt16 length);// 单次发送帧数
[DllImport("ECANVCI64.dll", EntryPoint = "Receive")]//【13】接收数据帧,<=5帧,返回-1故障
public static extern Int32 Receive(
UInt32 DeviceType,
UInt32 DeviceInd,
UInt32 CANInd,
out CAN_OBJ Receive,
UInt32 length, //单次读取帧数【封顶帧数】7为单次最多取7帧
UInt32 WaitTimeMs);//【0】不等待ms
[DllImport("ECANVCI64.dll", EntryPoint = "ResetCAN")]//【14】复位CAN通道
public static extern Status ResetCAN(
UInt32 DeviceType,
UInt32 DeviceInd,
UInt32 CANInd);
#endregion
Help_String help_String = new Help_String();//文本处理
#endregion
#region 属性
//public Iface_RTX help_rtx { get; set; }// 接口扩展
/// <summary>
/// ↑:byte包,文本
/// </summary>
//static public WT_GET_Data Wt_get;//↑event委托=》呼叫上ui层 让上层显示:发送命令
/// <summary>
/// ↓:byte包,文本
/// </summary>
static public WT_SET_Data Wt_set;//↓委托=》呼叫下位机执行
//设备类型
public UInt32 Device_USBCAN1 { get => 3; }// 硬件设备类型:// USB单路CAN
public UInt32 Device_USBCAN2 { get => 4; }// USB双路CAN
// E表示以太网
public UInt32 Device_USBCAN_E_U { get => 20; } // 以太网单路CAN
public UInt32 Device_USBCAN_2E_U { get => 21; }// 以太网双路CAN
public UInt32 CAN1 { get => 0; }// 设备CAN1通道
public UInt32 CAN2 { get => 1; }// 设备CAN2通道
public int STATUS_OK { get => 1; }//成功
public int STATUS_ERR { get => 0; }//失败
public int 标准帧 { get => 0; }//帧id【11bit】
public int 扩展帧 { get => 0; }//帧id【29bit】
//GetReceiveNum
//public Int32 get_缓冲区帧数
//{//CAN_STATUS
// get
// {
// return GetReceiveNum(4, 0, CAN2); // CAN1发,CAN2收
// }
//}
#endregion
#region 构造
//该对象包含接口,一般用于将该对象拆出接口,移植给上位机
#endregion
#region APP
//1 OpenDevice.................................打开设备
public bool Set_打开设备(UInt32 DeviceType, UInt32 DeviceInd)
{
if (OpenDevice(DeviceType, DeviceInd, 0) == Status.STATUS_OK) return true; //打开设备
else return false;
}
//2 CloseDevice................................关闭设备
public bool Set_关闭设备(UInt32 DeviceType, UInt32 DeviceInd)
{
if (CloseDevice(DeviceType, 0) == Status.STATUS_OK) return true;
return false;
}
//3 InitCan.........................................初始化CAN通道
public bool Set_初始化CAN通道(UInt32 DeviceType, UInt32 DeviceInd, UInt32 CANInd, ref INIT_CONFIG pInitConfig)
{//CAN1配置
//【设备类型,设备id,CAN通道,参数表】
if (InitCAN(DeviceType, DeviceInd, CANInd, ref pInitConfig) == Status.STATUS_OK) return true;
return false;
//===========================
//uint DevType = Device_USBCAN2;// 设备类型
//int sta = 1;//标记状态
//INIT_CONFIG pInitConfig = new INIT_CONFIG();
//pInitConfig.AccCode = 0x00; //【左对齐】帧id的bit完全匹配才接收
//pInitConfig.AccMask = 0xFFFFFFFF;//【左对齐】帧id的bit【1】使对应AccCode的bit位失效
//pInitConfig.Reserved = 0;// 保留。
//pInitConfig.Filter = 0;// 滤帧开关。【0】关,【1】开。
//pInitConfig.Timing0 = 0;// 波特率 1MHz【t0=0x00,t1=0x14】
//pInitConfig.Timing1 = 0x14;
//pInitConfig.Mode = 0;// 工作模式。【0】正常收发【1】只收【2】环回(中继)
//sta &= (int)OpenDevice(DevType, 0, 0); //打开设备
//sta &= (int)InitCAN(DevType, 0, CAN1, ref pInitConfig);//CAN1配置
//sta &= (int)InitCAN(DevType, 0, CAN2, ref pInitConfig);//CAN2配置
//sta &= (int)StartCAN(DevType, 0, CAN1);
//sta &= (int)StartCAN(DevType, 0, CAN2);
//if (sta == STATUS_OK) return true;// 成功 ==(int)Status.STATUS_OK
//return false;
}
//4 ReadBoardInfo............................读设备信息
public bool Get_设备信息(UInt32 DeviceType, UInt32 DeviceInd, out BOARD_INFO pInfo)
{
if (ReadBoardInfo(DeviceType, DeviceInd, out pInfo) == Status.STATUS_OK) return true;
else return false;
}
//5 ReadErrInfo.................................读错误信息
public bool Get_故障信息(UInt32 DeviceType, UInt32 DeviceInd, UInt32 CANInd, out ERR_INFO pErrInfo)
{//ERR_INFO //ReadErrInfo
if (ReadErrInfo(DeviceType, DeviceInd, CANInd, out pErrInfo) == Status.STATUS_OK) return true;
else return false;
}
//6 ReadCanStatus...........................读设备状态
public bool Get_CAN状态(UInt32 DeviceType, UInt32 DeviceInd, UInt32 CANInd, out CAN_STATUS pCAN_STATUS)
{ //CAN_STATUS //ReadCanStatus
if (ReadCanStatus(DeviceType, DeviceInd, CANInd, out pCAN_STATUS) == Status.STATUS_OK) return true;
else return false;
}
//7 GetReference..............................获取过滤帧配置参数。【PVOID* pData】
public bool Get_滤帧参数(UInt32 DeviceType, UInt32 DeviceInd, UInt32 CANInd, RefType RefType, out FILTER_RECORD pFILTER_RECORD)
{//【0】标准帧【1】扩展帧
if (GetReference(DeviceType, DeviceInd, CANInd, (uint)RefType, out pFILTER_RECORD) == Status.STATUS_OK) return true;
else return false;
}
//8 SetReference..............................设置过滤帧配置参数。【VCI_FILTER_RECORD】
public bool Set_滤帧参数(UInt32 DeviceType, UInt32 DeviceInd, UInt32 CANInd, RefType RefType, ref FILTER_RECORD pFILTER_RECORD)
{
if (SetReference(DeviceType, DeviceInd, CANInd, (uint)RefType, ref pFILTER_RECORD) == Status.STATUS_OK) return true; //
else return false;
}
//9 GetReceiveNum..........................读接收缓冲区中帧数。【<=10239帧】
public Int32 Get_缓冲器帧数(UInt32 DeviceType, UInt32 DeviceInd, UInt32 CANInd)
{
return GetReceiveNum(DeviceType, DeviceInd, CANInd);
}
//10 ClearBuffer................................清空CAN通道的缓冲区。
public bool Set_清空缓冲器帧数(UInt32 DeviceType, UInt32 DeviceInd, UInt32 CANInd)
{
if (ClearBuffer(DeviceType, DeviceInd, CANInd) == Status.STATUS_OK) return true;
else return false;
}
//11 StartCAN...................................启动某一个CAN通道。
public bool Set_打开CAN通道(UInt32 DeviceType, UInt32 DeviceInd, UInt32 CANInd)
{
if (StartCAN(DeviceType, DeviceInd, CANInd) == Status.STATUS_OK) return true;
return false;
}
//12 Transmit....................................返回实际发送成功的帧数。
public int Set_发送数据(UInt32 DeviceType, UInt32 DeviceInd, UInt32 CANInd, string txt)
{
CAN_OBJ[] buffer = new CAN_OBJ[10];
//public UInt32 ID;// 帧ID。 【u32】帧id,标准帧11bit,扩展帧29bit。
//public UInt32 TimeStamp; //【u32】时间值。从CAN卡上电开始计时,计时单位为0.1ms。
//public byte TimeFlag; // 标志位,【1】TimeStamp值有效
//public byte SendType; // 发送类型。【0】正常发送(失败有重发)【1】单次发送
//public byte RemoteFlag; // 远帧标志。【0】数据帧【1】远程帧(数据段空,用于呼叫从站)。
//public byte ExternFlag; // 扩展帧标志【0】标准帧(11位ID),【1】扩展帧(29位ID)。
//public byte DataLen; // 单帧有效字节 DLC (<=8)约束了后面Data[8]中有效字节数。
//[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
//public byte[] data; // 数据包,如DataLen为3,Data[0]、Data[1]、Data[2]是有效的。
//[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
//public byte[] Reserved; // 保留。
txt.Replace(" ", "");//头尾去除空白
byte[] buffercmd = help_String.StringsToHexBytes(txt);// 1 4 8
// 4
string id = txt.Substring(2, 8);// 从站地址 00000602
buffer[0].ID = Convert.ToUInt32(id, 16);//从站id
// 1
buffer[0].DataLen = buffercmd[0];//数据长度 DLC (<=8),即CAN帧Data有几个字节。约束了后面Data[8]中的有效字节。
// 8
buffer[0].data[0] = buffercmd[5];// byte8
buffer[0].data[1] = buffercmd[6];
buffer[0].data[2] = buffercmd[7];
buffer[0].data[3] = buffercmd[8];
buffer[0].data[4] = buffercmd[9];
buffer[0].data[5] = buffercmd[10];
buffer[0].data[6] = buffercmd[11];
buffer[0].data[7] = buffercmd[12];
// 上车
buffer[0].SendType = 0;//【0】正常,失败有重发 【1】只发单次,失败无重发
Int32 ret = (int)Transmit(DeviceType, DeviceInd, CANInd, buffer, 1);// 库函数(发送TXs)
return ret;
}
public int Set_发送数据(UInt32 DeviceType, UInt32 DeviceInd, UInt32 CANInd, CAN_OBJ[] Send, UInt16 length)
{
Int32 ret = Transmit(DeviceType, DeviceInd, CANInd, Send, length);// 库函数(发送TXs)
return ret;
}
//13 Receive.....................................读CAN数据帧。【<=5】
public int Get_接收数据(UInt32 DeviceType, UInt32 DeviceInd, UInt32 CANInd, out CAN_OBJ receive, UInt32 length, UInt32 WaitTimeMs)
{//【-1设备故障】
return Receive(DeviceType, DeviceInd, CANInd, out receive, length, WaitTimeMs = 0);// 等待毫秒【0不等待】
}
//14 ResetCAN.................................复位CAN通道。
public bool Set_复位CAN通道(UInt32 DeviceType, UInt32 DeviceInd, UInt32 CANInd)
{
if (ResetCAN(DeviceType, DeviceInd, CANInd) ==Status.STATUS_OK) return true;
return false;
}
//————————————————
//版权声明:本文为CSDN博主「cfqq1989」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
//原文链接:https://blog.csdn.net/cfqq1989/article/details/134510613
#endregion
#region 事件
#endregion
#region 实现接口【开,关,收,发,环回】
public bool connect<T>(T a, T b)
{
//throw new NotImplementedException();
UInt32 DeviceType = Device_USBCAN2;// 设备类型
UInt32 DeviceInd = 0;// 设备id
int sta = 1;//标记状态
INIT_CONFIG pInitConfig = new INIT_CONFIG();
pInitConfig.AccCode = 0x00; //【左对齐】帧id的bit完全匹配才接收
pInitConfig.AccMask = 0xFFFFFFFF;//【左对齐】帧id的bit【1】使对应AccCode的bit位失效
pInitConfig.Reserved = 0;// 保留。
pInitConfig.Filter = 0;// 滤帧开关。【0】关,【1】开。
pInitConfig.Timing0 = 0;// 波特率 1MHz【t0=0x00,t1=0x14】
pInitConfig.Timing1 = 0x14;
pInitConfig.Mode = 0;// 工作模式。【0】正常收发【1】只收【2】环回(中继)
#region 原屎
//if (OpenDevice(DevType, 0, 0) == ECANStatus.STATUS_OK)
//{// InitCAN
// //CAN1
// if (InitCAN(DevType, 0, CAN1, ref pInitConfig) == ECANStatus.STATUS_OK)
// {//CAN2
// if (InitCAN(DevType, 0, CAN2, ref pInitConfig) == ECANStatus.STATUS_OK)
// {
// StartCAN(DevType, 0, CAN1);
// StartCAN(DevType, 0, CAN2);
// return true; }
// }
//}
#endregion
sta &= (int)OpenDevice(DeviceType, DeviceInd, 0); //打开设备
sta &= (int)InitCAN(DeviceType, DeviceInd, CAN1, ref pInitConfig);//CAN1配置
sta &= (int)InitCAN(DeviceType, DeviceInd, CAN2, ref pInitConfig);//CAN2配置
sta &= (int)StartCAN(DeviceType, DeviceInd, CAN1);// can开启
sta &= (int)StartCAN(DeviceType, DeviceInd, CAN2);
if (sta == STATUS_OK) return true;// 成功 ==(int)Status.STATUS_OK
return false;
}
public bool Close()
{
//throw new NotImplementedException();
uint DevType = Device_USBCAN2;
if (CloseDevice(DevType, 0) == Status.STATUS_OK) return true;
return false;
}
public int RXs(ref object obj)
{
//throw new NotImplementedException();
CAN_OBJ[] cAN_OBJ = new CAN_OBJ[5];
int num = Get_接收数据(Device_USBCAN2, 0, CAN1, out cAN_OBJ[0], 5, 0);
obj = cAN_OBJ;
return num;
}
public bool TXs(string cmd)
{
//throw new NotImplementedException();
if (Set_发送数据(Device_USBCAN2, 0, CAN1, cmd) == STATUS_OK) return true;
else return false;
}
public bool sendAndReceive<T>(string cmd, ref T t)
{
throw new NotImplementedException();
}
#endregion
}
}