This commit is contained in:
2024-12-18 15:50:21 +08:00
parent 684973e6b7
commit b2c54119ea
214 changed files with 65908 additions and 8461 deletions

View File

@@ -0,0 +1,29 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace CapMachine.Wpf.CanDrive
{
/// <summary>
/// CAN Data 指令
/// </summary>
public class CanCmdData
{
/// <summary>
/// 消息名称
/// </summary>
public string? MsgName { get; set; }
/// <summary>
/// 信号名称
/// </summary>
public string? SignalName { get; set; }
/// <summary>
/// 指令值
/// </summary>
public double SignalCmdValue { get; set; }
}
}

View File

@@ -0,0 +1,57 @@
using Prism.Mvvm;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace CapMachine.Wpf.CanDrive
{
/// <summary>
/// Dbc 信息
/// </summary>
public class CanDbcModel:BindableBase
{
/// <summary>
/// 消息Id
/// </summary>
public string? MsgId { get; set; }
/// <summary>
/// 消息名称
/// </summary>
public string? MsgName { get; set; }
/// <summary>
/// 信号名称
/// </summary>
public string? SignalName { get; set; }
/// <summary>
/// 信号描述
/// </summary>
public string? SignalDesc { get; set; }
/// <summary>
/// 信号单位
/// </summary>
public string? SignalUnit { get; set; }
private string? _SignalRtValue;
/// <summary>
/// 信号实时值
/// </summary>
public string? SignalRtValue
{
get { return _SignalRtValue; }
set { _SignalRtValue = value;RaisePropertyChanged(); }
}
/// <summary>
/// 发布者
/// </summary>
public string? Publisher { get; set; }
}
}

View File

@@ -0,0 +1,37 @@
using Prism.Mvvm;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace CapMachine.Wpf.CanDrive
{
/// <summary>
/// CAN 实时数据
/// </summary>
public class CanRtData : BindableBase
{
/// <summary>
/// 消息名称
/// </summary>
public string? MsgName { get; set; }
/// <summary>
/// 信号名称
/// </summary>
public string? SignalName { get; set; }
private double _SignalRtValue;
/// <summary>
/// 信号实时值
/// </summary>
public double SignalRtValue
{
get { return _SignalRtValue; }
set { _SignalRtValue = value; RaisePropertyChanged(); }
}
}
}

View File

@@ -0,0 +1,53 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
namespace CapMachine.Wpf.CanDrive
{
public class DBCParser
{
public const Int32 DBC_PARSER_OK = 0;//没有错误
public const Int32 DBC_PARSER_FILE_OPEN = (-1);//打开文件出错
public const Int32 DBC_PARSER_FILE_FORMAT = (-2);//文件格式错误
public const Int32 DBC_PARSER_DEV_DISCONNECT = (-3);//设备未连接
public const Int32 DBC_PARSER_HANDLE_ERROR = (-4);//LDF Handle错误
public const Int32 DBC_PARSER_GET_INFO_ERROR = (-5);//获取解析后的数据出错
public const Int32 DBC_PARSER_DATA_ERROR = (-6);//数据处理错误
public const Int32 DBC_PARSER_SLAVE_NACK = (-7);//从机未响应数据
[DllImport("USB2XXX.dll")]
public static extern UInt64 DBC_ParserFile(int DevHandle, StringBuilder pDBCFileName);
[DllImport("USB2XXX.dll")]
public static extern Int32 DBC_GetMsgQuantity(UInt64 DBCHandle);
[DllImport("USB2XXX.dll")]
public static extern Int32 DBC_GetMsgName(UInt64 DBCHandle, int index, StringBuilder pMsgName);
[DllImport("USB2XXX.dll")]
public static extern Int32 DBC_GetMsgSignalQuantity(UInt64 DBCHandle, StringBuilder pMsgName);
[DllImport("USB2XXX.dll")]
public static extern Int32 DBC_GetMsgSignalName(UInt64 DBCHandle, StringBuilder pMsgName, int index, StringBuilder pSignalName);
[DllImport("USB2XXX.dll")]
public static extern Int32 DBC_GetMsgPublisher(UInt64 DBCHandle, StringBuilder pMsgName, StringBuilder pPublisher);
//设置信号值
[DllImport("USB2XXX.dll")]
public static extern Int32 DBC_SetSignalValue(UInt64 DBCHandle, StringBuilder pMsgName, StringBuilder pSignalName, double Value);
//获取信号值
[DllImport("USB2XXX.dll")]
public static extern Int32 DBC_GetSignalValue(UInt64 DBCHandle, StringBuilder pMsgName, StringBuilder pSignalName, double[] pValue);
[DllImport("USB2XXX.dll")]
public static extern Int32 DBC_GetSignalValueStr(UInt64 DBCHandle, StringBuilder pMsgName, StringBuilder pSignalName, StringBuilder pValueStr);
//将CAN消息数据填充到信号里面
[DllImport("USB2XXX.dll")]
public static extern Int32 DBC_SyncCANMsgToValue(UInt64 DBCHandle, IntPtr pCANMsg, int MsgLen);
[DllImport("USB2XXX.dll")]
public static extern Int32 DBC_SyncCANFDMsgToValue(UInt64 DBCHandle, IntPtr pCANFDMsg, int MsgLen);
//将信号数据填充到CAN消息里面
[DllImport("USB2XXX.dll")]
public static extern Int32 DBC_SyncValueToCANMsg(UInt64 DBCHandle, StringBuilder pMsgName, IntPtr pCANMsg);
[DllImport("USB2XXX.dll")]
public static extern Int32 DBC_SyncValueToCANFDMsg(UInt64 DBCHandle, StringBuilder pMsgName, IntPtr pCANFDMsg);
}
}

View File

@@ -0,0 +1,511 @@
using CapMachine.Wpf.Models.Tag;
using NPOI.OpenXmlFormats.Wordprocessing;
using Prism.Mvvm;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Windows.Interop;
namespace CapMachine.Wpf.CanDrive
{
/// <summary>
/// Toomoss CAN
/// </summary>
public class ToomossCanFD : BindableBase
{
/// <summary>
/// 实例化函数
/// </summary>
public ToomossCanFD()
{
}
/// <summary>
/// 开始CAN的驱动
/// </summary>
public void StartCanDrive()
{
IsExistsDllFile();
ScanDevice();
OpenDevice();
GetDeviceInfo();
GetCANConfig();
InitCAN();
}
/// <summary>
/// 开始Dbc文件写入
/// </summary>
public void StartDbc(string DbcPath)
{
DBC_Parser(DbcPath);
}
/// <summary>
/// Dbc消息集合
/// </summary>
public ObservableCollection<CanDbcModel> ListCanDbcModel { get; set; } = new ObservableCollection<CanDbcModel>();
#region
/// <summary>
/// 设备固件信息
/// </summary>
public USB_DEVICE.DEVICE_INFO DevInfo = new USB_DEVICE.DEVICE_INFO();
/// <summary>
/// CAN Config
/// </summary>
USB2CANFD.CANFD_INIT_CONFIG CANConfig = new USB2CANFD.CANFD_INIT_CONFIG();
/// <summary>
/// DBC Handle
/// </summary>
public UInt64 DBCHandle { get; set; }
/// <summary>
/// 扫描设备Handle集合
/// </summary>
public Int32[] DevHandles { get; set; } = new Int32[20];
/// <summary>
/// 扫描设备Handle
/// </summary>
public Int32 DevHandle { get; set; } = 0;
/// <summary>
/// Write CAN Index
/// </summary>
public Byte WriteCANIndex { get; set; } = 0;
/// <summary>
/// Read CAN Index
/// </summary>
public Byte ReadCANIndex { get; set; } = 1;
private bool _OpenState;
/// <summary>
/// 打开设备的状态
/// </summary>
public bool OpenState
{
get { return _OpenState; }
set { _OpenState = value; RaisePropertyChanged(); }
}
/// <summary>
/// 扫描到设备个数
/// </summary>
public Int32 DevNum { get; set; }
public Int32 ret { get; set; }
public string dllFilePath { get; set; } = "USB2XXX.dll";
/// <summary>
/// 消息值Pt
/// </summary>
public IntPtr msgPt { get; set; }
#endregion
/// <summary>
/// ******************【1】*********************
/// 是否存在Dll文件
/// </summary>
/// <returns></returns>
public bool IsExistsDllFile()
{
if (!File.Exists(dllFilePath))
{
Console.WriteLine("请先将USB2XXX.dll和libusb-1.0.dll文件复制到exe程序文件输出目录下!");
Console.WriteLine("dll文件在usb2can_lin_pwm_example/sdk/libs/windows目录下");
Console.WriteLine("程序是32位的就复制x86目录下文件程序是64位的就复制x86_64目录下文件");
return false;
}
return true;
}
/// <summary>
/// ******************【2】*********************
/// 扫描查找设备,并将每个设备的唯一设备号存放到数组中,后面的函数需要用到
/// </summary>
/// <returns></returns>
public bool ScanDevice()
{
DevNum = USB_DEVICE.USB_ScanDevice(DevHandles);
if (DevNum <= 0)
{
Console.WriteLine("No device connected!");
return false;
}
else
{
Console.WriteLine("Have {0} device connected!", DevNum);
DevHandle = DevHandles[0];//获取第一个设备的设备号
return true;
}
}
/// <summary>
/// ******************【3】*********************
/// 打开设备
/// </summary>
/// <returns></returns>
public bool OpenDevice()
{
//打开设备
OpenState = USB_DEVICE.USB_OpenDevice(DevHandle);
if (!OpenState)
{
Console.WriteLine("Open device error!");
return false;
}
else
{
Console.WriteLine("Open device success!");
return true;
}
}
/// <summary>
/// ******************【4】*********************
/// 获取设备的固件信息
/// </summary>
/// <returns></returns>
public bool GetDeviceInfo()
{
//获取固件信息
StringBuilder FuncStr = new StringBuilder(256);
OpenState = USB_DEVICE.DEV_GetDeviceInfo(DevHandle, ref DevInfo, FuncStr);
if (!OpenState)
{
Console.WriteLine("Get device infomation error!");
return false;
}
else
{
Console.WriteLine("Firmware Info:");
Console.WriteLine(" Name:" + Encoding.Default.GetString(DevInfo.FirmwareName));
Console.WriteLine(" Build Date:" + Encoding.Default.GetString(DevInfo.BuildDate));
Console.WriteLine(" Firmware Version:v{0}.{1}.{2}", (DevInfo.FirmwareVersion >> 24) & 0xFF, (DevInfo.FirmwareVersion >> 16) & 0xFF, DevInfo.FirmwareVersion & 0xFFFF);
Console.WriteLine(" Hardware Version:v{0}.{1}.{2}", (DevInfo.HardwareVersion >> 24) & 0xFF, (DevInfo.HardwareVersion >> 16) & 0xFF, DevInfo.HardwareVersion & 0xFFFF);
Console.WriteLine(" Functions:" + DevInfo.Functions.ToString("X8"));
Console.WriteLine(" Functions String:" + FuncStr);
StringBuilder DLLBuildDate = new StringBuilder(256);
USB_DEVICE.DEV_GetDllBuildTime(DLLBuildDate);
Console.WriteLine(" DLL Build Date:" + DLLBuildDate);
return true;
}
}
/// <summary>
/// ******************【5】*********************
/// 获取设备Config配置
/// </summary>
public void GetCANConfig()
{
//获取CAN波特率参数
ret = USB2CANFD.CANFD_GetCANSpeedArg(DevHandle, ref CANConfig, 500000, 2000000);
if (ret != USB2CANFD.CANFD_SUCCESS)
{
Console.WriteLine("Get CAN Speed failed!");
return;
}
else
{
Console.WriteLine("Get CAN Speed Success!");
}
}
/// <summary>
/// ******************【6】*********************
/// 初始化CAN
/// </summary>
public void InitCAN()
{
//初始化CAN
ret = USB2CANFD.CANFD_Init(DevHandle, WriteCANIndex, ref CANConfig);
if (ret != USB2CANFD.CANFD_SUCCESS)
{
Console.WriteLine("Config CAN failed!");
return;
}
else
{
Console.WriteLine("WriteCANIndex Config CAN Success!");
}
ret = USB2CANFD.CANFD_Init(DevHandle, ReadCANIndex, ref CANConfig);
if (ret != USB2CAN.CAN_SUCCESS)
{
Console.WriteLine("Config CAN failed!");
return;
}
else
{
Console.WriteLine("ReadCANIndex Config CAN Success!");
}
Console.WriteLine("");
}
/// <summary>
/// ******************【7】*********************
/// DBC解析
/// </summary>
public void DBC_Parser(string Path)
{
//解析DBC文件
DBCHandle = DBCParser.DBC_ParserFile(DevHandle, new StringBuilder(Path));
if (DBCHandle == 0)
{
Console.WriteLine("Parser DBC File error!");
return;
}
else
{
Console.WriteLine("Parser DBC File success!");
}
ListCanDbcModel.Clear();
//打印DBC里面报文和信号相关信息
int DBCMsgNum = DBCParser.DBC_GetMsgQuantity(DBCHandle);
for (int i = 0; i < DBCMsgNum; i++)
{
StringBuilder MsgName = new StringBuilder(32);
DBCParser.DBC_GetMsgName(DBCHandle, i, MsgName);
Console.WriteLine("Msg.Name = {0}", MsgName);
int DBCSigNum = DBCParser.DBC_GetMsgSignalQuantity(DBCHandle, MsgName);
StringBuilder Publisher = new StringBuilder(32);
DBCParser.DBC_GetMsgPublisher(DBCHandle, MsgName, Publisher);
Console.Write("Signals:");
for (int j = 0; j < DBCSigNum; j++)
{
StringBuilder SigName = new StringBuilder(32);
DBCParser.DBC_GetMsgSignalName(DBCHandle, MsgName, j, SigName);
Console.Write("{0} ", SigName);
//增加信息数据
ListCanDbcModel.Add(new CanDbcModel()
{
MsgName = MsgName.ToString(),
MsgId = "",
SignalName = SigName.ToString(),
SignalDesc = "",
SignalUnit = "",
SignalRtValue = "",
Publisher = Publisher.ToString()
});
}
Console.WriteLine("");
}
}
/// <summary>
/// 发送CAN数据
/// </summary>
public void SendCanMsg(List<CanCmdData> CmdData)
{
var GroupMsg = CmdData.GroupBy(x => x.MsgName);
USB2CANFD.CANFD_MSG[] CanMsg = new USB2CANFD.CANFD_MSG[GroupMsg.Count()];
for (int i = 0; i < GroupMsg.Count(); i++)
{
CanMsg[i] = new USB2CANFD.CANFD_MSG();
CanMsg[i].Data = new Byte[64];
}
IntPtr msgPt = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(USB2CANFD.CANFD_MSG)));
int Index = 0;
//循环给MSG赋值数据
foreach (var itemMsg in GroupMsg)
{
foreach (var itemSignal in itemMsg)
{
DBCParser.DBC_SetSignalValue(DBCHandle, new StringBuilder(itemMsg.Key), new StringBuilder(itemSignal.SignalName), itemSignal.SignalCmdValue);
}
DBCParser.DBC_SyncValueToCANFDMsg(DBCHandle, new StringBuilder(itemMsg.Key), msgPt);
CanMsg[Index] = (USB2CANFD.CANFD_MSG)Marshal.PtrToStructure(msgPt, typeof(USB2CANFD.CANFD_MSG));
Index++;
}
//设置信号值
//DBCParser.DBC_SetSignalValue(DBCHandle, new StringBuilder("msg_moto_speed"), new StringBuilder("moto_speed"), 2412);
//DBCParser.DBC_SetSignalValue(DBCHandle, new StringBuilder("msg_oil_pressure"), new StringBuilder("oil_pressure"), 980);
//DBCParser.DBC_SetSignalValue(DBCHandle, new StringBuilder("msg_speed_can"), new StringBuilder("speed_can"), 120);
//通过DBC写入数据后生成CanMsg
//将信号值填入CAN消息里面
//IntPtr msgPt = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(USB2CANFD.CANFD_MSG)));
//DBCParser.DBC_SyncValueToCANFDMsg(DBCHandle, new StringBuilder("msg_moto_speed"), msgPt);
//CanMsg[0] = (USB2CANFD.CANFD_MSG)Marshal.PtrToStructure(msgPt, typeof(USB2CANFD.CANFD_MSG));
//DBCParser.DBC_SyncValueToCANFDMsg(DBCHandle, new StringBuilder("msg_oil_pressure"), msgPt);
//CanMsg[1] = (USB2CANFD.CANFD_MSG)Marshal.PtrToStructure(msgPt, typeof(USB2CANFD.CANFD_MSG));
//DBCParser.DBC_SyncValueToCANFDMsg(DBCHandle, new StringBuilder("msg_speed_can"), msgPt);
//CanMsg[2] = (USB2CANFD.CANFD_MSG)Marshal.PtrToStructure(msgPt, typeof(USB2CANFD.CANFD_MSG));
//释放申请的临时缓冲区
Marshal.FreeHGlobal(msgPt);
Console.WriteLine("");
//发送CAN数据
int SendedNum = USB2CANFD.CANFD_SendMsg(DevHandle, WriteCANIndex, CanMsg, (Int32)CanMsg.Length);
if (SendedNum >= 0)
{
Console.WriteLine("Success send frames:{0}", SendedNum);
}
else
{
Console.WriteLine("Send CAN data failed! {0}", SendedNum);
}
}
/// <summary>
/// 是否循环接收数据
/// </summary>
public bool IsCycleRevice { get; set; }
/// <summary>
/// CycleRevice扫描Task
/// </summary>
private static Task CycleReviceTask { get; set; }
/// <summary>
/// 循环获取CAN消息
/// </summary>
public void StartCycleReviceCanMsg()
{
CycleReviceTask = Task.Run(async () =>
{
while (IsCycleRevice)
{
await Task.Delay(1000);
try
{
//另外一个CAN通道读取数据
USB2CANFD.CANFD_MSG[] CanMsgBuffer = new USB2CANFD.CANFD_MSG[10];
msgPt = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(USB2CANFD.CANFD_MSG)) * CanMsgBuffer.Length);
int CanNum = USB2CANFD.CANFD_GetMsg(DevHandle, ReadCANIndex, msgPt, CanMsgBuffer.Length);
if (CanNum > 0)
{
Console.WriteLine("Read CanMsgNum = {0}", CanNum);
for (int i = 0; i < CanNum; i++)
{
CanMsgBuffer[i] = (USB2CANFD.CANFD_MSG)Marshal.PtrToStructure((IntPtr)(msgPt + i * Marshal.SizeOf(typeof(USB2CANFD.CANFD_MSG))), typeof(USB2CANFD.CANFD_MSG));
Console.WriteLine("CanMsg[{0}].ID = 0x{1}", i, CanMsgBuffer[i].ID.ToString("X8"));
//Console.WriteLine("CanMsg[{0}].TimeStamp = {1}",i,CanMsgBuffer[i].TimeStamp);
Console.Write("CanMsg[{0}].Data = ", i);
for (int j = 0; j < CanMsgBuffer[i].DLC; j++)
{
Console.Write("{0} ", CanMsgBuffer[i].Data[j].ToString("X2"));
}
Console.WriteLine("");
}
}
else if (CanNum == 0)
{
Console.WriteLine("No CAN data!");
}
else
{
Console.WriteLine("Get CAN data error!");
}
Console.WriteLine("");
//将CAN消息数据填充到信号里面
DBCParser.DBC_SyncCANFDMsgToValue(DBCHandle, msgPt, CanNum);
//获取信号值并打印出来
StringBuilder ValueStr = new StringBuilder(32);
DBCParser.DBC_GetSignalValueStr(DBCHandle, new StringBuilder("TX1"), new StringBuilder("COM_current_Power"), ValueStr);
Console.WriteLine("COM_current_Power = {0}", ValueStr);
DBCParser.DBC_GetSignalValueStr(DBCHandle, new StringBuilder("TX1"), new StringBuilder("COM_Curr_dc"), ValueStr);
Console.WriteLine("COM_Curr_dc = {0}", ValueStr);
}
catch (Exception ex)
{
//LogService.Info($"时间:{DateTime.Now.ToString()}-【Meter】-{ex.Message}");
}
}
});
}
/// <summary>
/// 接受CAN消息
/// </summary>
public void ReciveCanMsg()
{
//另外一个CAN通道读取数据
USB2CANFD.CANFD_MSG[] CanMsgBuffer = new USB2CANFD.CANFD_MSG[10];
msgPt = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(USB2CANFD.CANFD_MSG)) * CanMsgBuffer.Length);
int CanNum = USB2CANFD.CANFD_GetMsg(DevHandle, ReadCANIndex, msgPt, CanMsgBuffer.Length);
if (CanNum > 0)
{
Console.WriteLine("Read CanMsgNum = {0}", CanNum);
for (int i = 0; i < CanNum; i++)
{
CanMsgBuffer[i] = (USB2CANFD.CANFD_MSG)Marshal.PtrToStructure((IntPtr)(msgPt + i * Marshal.SizeOf(typeof(USB2CANFD.CANFD_MSG))), typeof(USB2CANFD.CANFD_MSG));
Console.WriteLine("CanMsg[{0}].ID = 0x{1}", i, CanMsgBuffer[i].ID.ToString("X8"));
//Console.WriteLine("CanMsg[{0}].TimeStamp = {1}",i,CanMsgBuffer[i].TimeStamp);
Console.Write("CanMsg[{0}].Data = ", i);
for (int j = 0; j < CanMsgBuffer[i].DLC; j++)
{
Console.Write("{0} ", CanMsgBuffer[i].Data[j].ToString("X2"));
}
Console.WriteLine("");
}
}
else if (CanNum == 0)
{
Console.WriteLine("No CAN data!");
}
else
{
Console.WriteLine("Get CAN data error!");
}
Console.WriteLine("");
//将CAN消息数据填充到信号里面
DBCParser.DBC_SyncCANFDMsgToValue(DBCHandle, msgPt, CanNum);
//获取信号值并打印出来
StringBuilder ValueStr = new StringBuilder(32);
DBCParser.DBC_GetSignalValueStr(DBCHandle, new StringBuilder("msg_moto_speed"), new StringBuilder("moto_speed"), ValueStr);
Console.WriteLine("moto_speed = {0}", ValueStr);
DBCParser.DBC_GetSignalValueStr(DBCHandle, new StringBuilder("msg_oil_pressure"), new StringBuilder("oil_pressure"), ValueStr);
Console.WriteLine("oil_pressure = {0}", ValueStr);
DBCParser.DBC_GetSignalValueStr(DBCHandle, new StringBuilder("msg_speed_can"), new StringBuilder("speed_can"), ValueStr);
Console.WriteLine("speed_can = {0}", ValueStr);
}
/// <summary>
/// 关闭设备
/// </summary>
public void CloseDevice()
{
//关闭设备
USB_DEVICE.USB_CloseDevice(DevHandle);
OpenState = false;
}
}
}

View File

@@ -0,0 +1,147 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
namespace CapMachine.Wpf.CanDrive
{
public class USB2CANFD
{
//1.CANFD信息帧的数据类型定义
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
public struct CANFD_MSG
{
public UInt32 ID; //报文ID,bit[30]-RTR,bit[31]-IDE,bit[28..0]-ID
public Byte DLC; //数据字节长度,可设置为-0,1,2,3,4,5,6,7,8,12,16,20,24,32,48,64
public Byte Flags; //bit[0]-BRS,bit[1]-ESI,bit[2]-FDF,bit[6..5]-Channel,bit[7]-RXD
public Byte __Res0; //保留
public Byte TimeStampHigh;//时间戳高位
public UInt32 TimeStamp;//帧接收或者发送时的时间戳单位为10us
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 64, ArraySubType = UnmanagedType.I1)]
public Byte[] Data; //报文的数据。
};
//2.CANFD初始化配置数据类型定义
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
public struct CANFD_INIT_CONFIG
{
public Byte Mode; //0-正常模式1-自发自收模式
public Byte ISOCRCEnable;//0-禁止ISO CRC,1-使能ISO CRC
public Byte RetrySend;//0-禁止重发1-无限制重发
public Byte ResEnable;//0-不接入内部120欧终端电阻1-接入内部120欧终端电阻
//波特率参数可以用TCANLINPro软件里面的波特率计算工具计算
//仲裁段波特率参数,波特率=40M/NBT_BRP*(1+NBT_SEG1+NBT_SEG2)
public Byte NBT_BRP;
public Byte NBT_SEG1;
public Byte NBT_SEG2;
public Byte NBT_SJW;
//数据段波特率参数,波特率=40M/DBT_BRP*(1+DBT_SEG1+DBT_SEG2)
public Byte DBT_BRP;
public Byte DBT_SEG1;
public Byte DBT_SEG2;
public Byte DBT_SJW;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8, ArraySubType = UnmanagedType.I1)]
public Byte[] __Res0;//保留
};
//3.CANFD诊断帧信息结构体定义
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
public struct CANFD_DIAGNOSTIC
{
public Byte NREC;//标称比特率接收错误计数
public Byte NTEC;//标称比特率发送错误计数
public Byte DREC;//数据比特率接收错误计数
public Byte DTEC;//数据比特率发送错误计数
public UInt16 ErrorFreeMsgCount;//无错误帧计数
public UInt16 Flags;//参考诊断标志定义
};
//4.CANFD总线错误信息结构体定义
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
public struct CANFD_BUS_ERROR
{
public Byte TEC;//发送错误计数
public Byte REC;//接收错误计数
public Byte Flags;//参考总线错误标志定义
public Byte __Res0;
};
//5.CAN 滤波器设置数据类型定义
public struct CANFD_FILTER_CONFIG
{
public Byte Enable; //使能该过滤器1-使能0-禁止
public Byte Index; //过滤器索引号取值范围为0到31
public Byte __Res0;
public Byte __Res1;
public UInt32 ID_Accept; //验收码ID,bit[28..0]为有效ID位bit[31]为IDE
public UInt32 ID_Mask; //屏蔽码对应bit位若为1则需要对比对应验收码bit位相同才接收
};
//函数返回错误代码定义
public const Int32 CANFD_SUCCESS = (0); //函数执行成功
public const Int32 CANFD_ERR_NOT_SUPPORT = (-1); //适配器不支持该函数
public const Int32 CANFD_ERR_USB_WRITE_FAIL = (-2); //USB写数据失败
public const Int32 CANFD_ERR_USB_READ_FAIL = (-3); //USB读数据失败
public const Int32 CANFD_ERR_CMD_FAIL = (-4); //命令执行失败
//CANFD_MSG.ID定义
public const Int32 CANFD_MSG_FLAG_RTR = (1 << 30);
public const Int32 CANFD_MSG_FLAG_IDE = (1 << 31);
public const Int32 CANFD_MSG_FLAG_ID_MASK = (0x1FFFFFFF);
//CANFD_MSG.Flags定义
public const Int32 CANFD_MSG_FLAG_BRS = (1 << 0);
public const Int32 CANFD_MSG_FLAG_ESI = (1 << 1);
public const Int32 CANFD_MSG_FLAG_FDF = (1 << 2);
public const Int32 CANFD_MSG_FLAG_RXD = (1 << 7);
//CANFD_DIAGNOSTIC.Flags定义
public const Int32 CANFD_DIAGNOSTIC_FLAG_NBIT0_ERR = (0x0001);//在发送报文或应答位、主动错误标志或过载标志期间器件要发送显性电平逻辑值为0的数据或标识符位但监视的总线值为隐性。
public const Int32 CANFD_DIAGNOSTIC_FLAG_NBIT1_ERR = (0x0002);//在发送报文仲裁字段除外期间器件要发送隐性电平逻辑值为1的位但监视到的总线值为显性。
public const Int32 CANFD_DIAGNOSTIC_FLAG_NACK_ERR = (0x0004);//发送报文未应答。
public const Int32 CANFD_DIAGNOSTIC_FLAG_NFORM_ERR = (0x0008);//接收报文的固定格式部分格式错误。
public const Int32 CANFD_DIAGNOSTIC_FLAG_NSTUFF_ERR = (0x0010);//在接收报文的一部分中序列中包含了5个以上相等位而报文中不允许出现这种序列。
public const Int32 CANFD_DIAGNOSTIC_FLAG_NCRC_ERR = (0x0020);//接收的报文的CRC校验和不正确。输入报文的CRC与通过接收到的数据计算得到的CRC不匹配。
public const Int32 CANFD_DIAGNOSTIC_FLAG_TXBO_ERR = (0x0080);//器件进入离线状态(且自动恢复)。
public const Int32 CANFD_DIAGNOSTIC_FLAG_DBIT0_ERR = (0x0100);//见NBIT0_ERR
public const Int32 CANFD_DIAGNOSTIC_FLAG_DBIT1_ERR = (0x0200);//见NBIT1_ERR
public const Int32 CANFD_DIAGNOSTIC_FLAG_DFORM_ERR = (0x0800);//见NFORM_ERR
public const Int32 CANFD_DIAGNOSTIC_FLAG_DSTUFF_ERR = (0x1000);//见NSTUFF_ERR
public const Int32 CANFD_DIAGNOSTIC_FLAG_DCRC_ERR = (0x2000);//见NCRC_ERR
public const Int32 CANFD_DIAGNOSTIC_FLAG_ESI_ERR = (0x4000);//接收的CAN FD报文的ESI标志置1
public const Int32 CANFD_DIAGNOSTIC_FLAG_DLC_MISMATCH = (0x8000);//DLC不匹配,在发送或接收期间指定的DLC大于FIFO元素的PLSIZE
//CANFD_BUS_ERROR.Flags定义
public const Int32 CANFD_BUS_ERROR_FLAG_TX_RX_WARNING = (0x01);
public const Int32 CANFD_BUS_ERROR_FLAG_RX_WARNING = (0x02);
public const Int32 CANFD_BUS_ERROR_FLAG_TX_WARNING = (0x04);
public const Int32 CANFD_BUS_ERROR_FLAG_RX_BUS_PASSIVE = (0x08);
public const Int32 CANFD_BUS_ERROR_FLAG_TX_BUS_PASSIVE = (0x10);
public const Int32 CANFD_BUS_ERROR_FLAG_TX_BUS_OFF = (0x20);
//USB2CANFD相关函数定义
[DllImport("USB2XXX.dll")]
public static extern Int32 CANFD_GetCANSpeedArg(Int32 DevHandle, ref CANFD_INIT_CONFIG pCanConfig, UInt32 SpeedBpsNBT, UInt32 SpeedBpsDBT);
[DllImport("USB2XXX.dll")]
public static extern Int32 CANFD_Init(Int32 DevHandle, Byte CANIndex, ref CANFD_INIT_CONFIG pCanConfig);
[DllImport("USB2XXX.dll")]
public static extern Int32 CANFD_StartGetMsg(Int32 DevHandle, Byte CANIndex);
[DllImport("USB2XXX.dll")]
public static extern Int32 CANFD_StopGetMsg(Int32 DevHandle, Byte CANIndex);
[DllImport("USB2XXX.dll")]
public static extern Int32 CANFD_SendMsg(Int32 DevHandle, Byte CANIndex, CANFD_MSG[] pCanSendMsg, Int32 SendMsgNum);
[DllImport("USB2XXX.dll")]
public static extern Int32 CANFD_GetMsg(Int32 DevHandle, Byte CANIndex, IntPtr pCanGetMsg, Int32 BufferSize);
[DllImport("USB2XXX.dll")]
public static extern Int32 CANFD_SetFilter(Int32 DevHandle, Byte CANIndex, ref CANFD_FILTER_CONFIG pCanFilter, Byte Len);
[DllImport("USB2XXX.dll")]
public static extern Int32 CANFD_GetDiagnostic(Int32 DevHandle, Byte CANIndex, ref CANFD_DIAGNOSTIC pCanDiagnostic);
[DllImport("USB2XXX.dll")]
public static extern Int32 CANFD_GetBusError(Int32 DevHandle, Byte CANIndex, ref CANFD_BUS_ERROR pCanBusError);
[DllImport("USB2XXX.dll")]
public static extern Int32 CANFD_Stop(Int32 DevHandle, Byte CANIndex);
[DllImport("USB2XXX.dll")]
public static extern Int32 CANFD_SetSchedule(Int32 DevHandle, Byte CANIndex, CANFD_MSG[] pCanMsgTab, Byte[] pMsgNum, UInt16[] pSendTimes, Byte MsgTabNum);
[DllImport("USB2XXX.dll")]
public static extern Int32 CANFD_StartSchedule(Int32 DevHandle, Byte CANIndex, Byte MsgTabIndex, Byte TimePrecMs, Byte OrderSend);
[DllImport("USB2XXX.dll")]
public static extern Int32 CANFD_StopSchedule(Int32 DevHandle, Byte CANIndex);
[DllImport("USB2XXX.dll")]
public static extern Int32 CANFD_SetRelay(Int32 DevHandle, Byte RelayState);
}
}

View File

@@ -0,0 +1,143 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
namespace CapMachine.Wpf.CanDrive
{
public class USB2CAN
{
//1.CAN信息帧的数据类型定义
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct CAN_MSG
{
public UInt32 ID; //报文ID。
public UInt32 TimeStamp; //接收到信息帧时的时间标识从CAN 控制器初始化开始计时。
public Byte RemoteFlag; //bit[0]-是否是远程帧,bit[6..5]-当前帧通道号bit[7]-发送帧标志
public Byte ExternFlag; //是否是扩展帧
public Byte DataLen; //数据长度(<=8)即Data 的长度。
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8, ArraySubType = UnmanagedType.I1)]
public Byte[] Data; //报文的数据。
public Byte TimeStampHigh; //时间戳高位
};
//2.初始化CAN的数据类型定义
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct CAN_INIT_CONFIG
{
//CAN波特率 = 100MHz/(CAN_BRP)/(CAN_SJW+CAN_BS1+CAN_BS2)
public UInt32 CAN_BRP; //取值范围1~1024
public Byte CAN_SJW; //取值范围1~4
public Byte CAN_BS1; //取值范围1~16
public Byte CAN_BS2; //取值范围1~8
public Byte CAN_Mode; //CAN工作模式0-正常模式1-环回模式2-静默模式3-静默环回模式
public Byte CAN_ABOM; //自动离线管理0-禁止1-使能
public Byte CAN_NART; //报文重发管理0-使能报文重传1-禁止报文重传
public Byte CAN_RFLM; //FIFO锁定管理0-新报文覆盖旧报文1-丢弃新报文
public Byte CAN_TXFP; //发送优先级管理0-标识符决定1-发送请求顺序决定
};
//3.CAN 滤波器设置数据类型定义
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct CAN_FILTER_CONFIG
{
public Byte Enable; //使能该过滤器1-使能0-禁止
public Byte FilterIndex; //过滤器索引号取值范围为0到13
public Byte FilterMode; //过滤器模式0-屏蔽位模式1-标识符列表模式
public Byte ExtFrame; //过滤的帧类型标志为1 代表要过滤的为扩展帧为0 代表要过滤的为标准帧。
public UInt32 ID_Std_Ext; //验收码ID
public UInt32 ID_IDE; //验收码IDE
public UInt32 ID_RTR; //验收码RTR
public UInt32 MASK_Std_Ext; //屏蔽码ID该项只有在过滤器模式为屏蔽位模式时有用
public UInt32 MASK_IDE; //屏蔽码IDE该项只有在过滤器模式为屏蔽位模式时有用
public UInt32 MASK_RTR; //屏蔽码RTR该项只有在过滤器模式为屏蔽位模式时有用
};
//4.CAN总线状态数据类型定义
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct CAN_STATUS
{
public UInt32 TSR; //发送状态寄存器
public UInt32 ESR; //错误状态寄存器
public Byte RECounter; //CAN 控制器接收错误寄存器。
public Byte TECounter; //CAN 控制器发送错误寄存器。
public Byte LECode; //最后的错误代码
};
//5.定义CAN Bootloader命令列表
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct CBL_CMD_LIST
{
//Bootloader相关命令
public Byte Erase; //擦出APP储存扇区数据
public Byte WriteInfo; //设置多字节写数据相关参数(写起始地址,数据量)
public Byte Write; //以多字节形式写数据
public Byte Check; //检测节点是否在线,同时返回固件信息
public Byte SetBaudRate; //设置节点波特率
public Byte Excute; //执行固件
//节点返回状态
public Byte CmdSuccess; //命令执行成功
public Byte CmdFaild; //命令执行失败
};
public const UInt32 CAN_BL_BOOT = 0x55555555;
public const UInt32 CAN_BL_APP = 0xAAAAAAAA;
//6.函数返回错误代码定义
public const Int32 CAN_SUCCESS = (0); //函数执行成功
public const Int32 CAN_ERR_NOT_SUPPORT = (-1); //适配器不支持该函数
public const Int32 CAN_ERR_USB_WRITE_FAIL = (-2); //USB写数据失败
public const Int32 CAN_ERR_USB_READ_FAIL = (-3); //USB读数据失败
public const Int32 CAN_ERR_CMD_FAIL = (-4); //命令执行失败
public const Int32 CAN_BL_ERR_CONFIG = (-20); //配置设备错误
public const Int32 CAN_BL_ERR_SEND = (-21); //发送数据出错
public const Int32 CAN_BL_ERR_TIME_OUT = (-22); //超时错误
public const Int32 CAN_BL_ERR_CMD = (-23); //执行命令失败
//USB2CAN相关函数定义
[DllImport("USB2XXX.dll")]
public static extern Int32 CAN_GetCANSpeedArg(Int32 DevHandle, ref CAN_INIT_CONFIG pCanConfig, UInt32 SpeedBps);
[DllImport("USB2XXX.dll")]
public static extern Int32 CAN_Init(Int32 DevHandle, Byte CANIndex, ref CAN_INIT_CONFIG pCanConfig);
[DllImport("USB2XXX.dll")]
public static extern Int32 CAN_Filter_Init(Int32 DevHandle, Byte CANIndex, ref CAN_FILTER_CONFIG pFilterConfig);
[DllImport("USB2XXX.dll")]
public static extern Int32 CAN_StartGetMsg(Int32 DevHandle, Byte CANIndex);
[DllImport("USB2XXX.dll")]
public static extern Int32 CAN_StopGetMsg(Int32 DevHandle, Byte CANIndex);
[DllImport("USB2XXX.dll")]
public static extern Int32 CAN_SendMsg(Int32 DevHandle, Byte CANIndex, CAN_MSG[] pCanSendMsg, UInt32 SendMsgNum);
[DllImport("USB2XXX.dll")]
public static extern Int32 CAN_GetMsg(Int32 DevHandle, Byte CANIndex, IntPtr pCanGetMsg);
[DllImport("USB2XXX.dll")]
public static extern Int32 CAN_GetMsgWithSize(Int32 DevHandle, Byte CANIndex, IntPtr pCanGetMsg, Int32 BufferSize);
[DllImport("USB2XXX.dll")]
public static extern Int32 CAN_ClearMsg(Int32 DevHandle, Byte CANIndex);
[DllImport("USB2XXX.dll")]
public static extern Int32 CAN_GetStatus(Int32 DevHandle, Byte CANIndex, ref CAN_STATUS pCANStatus);
[DllImport("USB2XXX.dll")]
public static extern Int32 CAN_SetSchedule(Int32 DevHandle, Byte CANIndex, CAN_MSG[] pCanMsgTab, Byte[] pMsgNum, UInt16[] pSendTimes, Byte MsgTabNum);
[DllImport("USB2XXX.dll")]
public static extern Int32 CAN_StartSchedule(Int32 DevHandle, Byte CANIndex, Byte MsgTabIndex, Byte TimePrecMs, Byte OrderSend);
[DllImport("USB2XXX.dll")]
public static extern Int32 CAN_StopSchedule(Int32 DevHandle, Byte CANIndex);
[DllImport("USB2XXX.dll")]
public static extern Int32 CAN_SetRelay(Int32 DevHandle, Byte RelayState);
//CAN Bootloader相关函数
[DllImport("USB2XXX.dll")]
public static extern Int32 CAN_BL_Init(Int32 DevHandle, Int32 CANIndex, ref CAN_INIT_CONFIG pInitConfig, ref CBL_CMD_LIST pCmdList);
[DllImport("USB2XXX.dll")]
public static extern Int32 CAN_BL_NodeCheck(Int32 DevHandle, Int32 CANIndex, UInt16 NodeAddr, UInt32[] pVersion, UInt32[] pType, UInt32 TimeOut);
[DllImport("USB2XXX.dll")]
public static extern Int32 CAN_BL_Erase(Int32 DevHandle, Int32 CANIndex, UInt16 NodeAddr, UInt32 FlashSize, UInt32 TimeOut);
[DllImport("USB2XXX.dll")]
public static extern Int32 CAN_BL_Write(Int32 DevHandle, Int32 CANIndex, UInt16 NodeAddr, UInt32 AddrOffset, Byte[] pData, UInt32 DataNum, UInt32 TimeOut);
[DllImport("USB2XXX.dll")]
public static extern Int32 CAN_BL_Excute(Int32 DevHandle, Int32 CANIndex, UInt16 NodeAddr, UInt32 Type);
[DllImport("USB2XXX.dll")]
public static extern Int32 CAN_BL_SetNewBaudRate(Int32 DevHandle, Int32 CANIndex, UInt16 NodeAddr, ref CAN_INIT_CONFIG pInitConfig, UInt32 NewBaudRate, UInt32 TimeOut);
}
}

View File

@@ -0,0 +1,140 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
namespace CapMachine.Wpf.CanDrive
{
public class USB_DEVICE
{
//定义电压输出值
public const Byte POWER_LEVEL_NONE = 0; //不输出
public const Byte POWER_LEVEL_1V8 = 1; //输出1.8V
public const Byte POWER_LEVEL_2V5 = 2; //输出2.5V
public const Byte POWER_LEVEL_3V3 = 3; //输出3.3V
public const Byte POWER_LEVEL_5V0 = 4; //输出5.0V
//设备信息定义
public struct DEVICE_INFO
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
public Byte[] FirmwareName; //固件名称字符串
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
public Byte[] BuildDate; //固件编译时间字符串
public UInt32 HardwareVersion;//硬件版本号
public UInt32 FirmwareVersion;//固件版本号
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
public UInt32[] SerialNumber; //适配器序列号
public UInt32 Functions; //适配器当前具备的功能
}
//方法定义
/**
* @brief 初始化USB设备并扫描设备连接数必须调用
* @param pDevHandle 每个设备的设备号存储地址
* @retval 扫描到的设备数量
*/
[DllImport("USB2XXX.dll")]
public static extern Int32 USB_ScanDevice(Int32[] pDevHandle);
/**
* @brief 打开设备,必须调用
* @param DevHandle 设备索引号
* @retval 打开设备的状态
*/
[DllImport("USB2XXX.dll")]
public static extern bool USB_OpenDevice(Int32 DevHandle);
/**
* @brief 关闭设备
* @param DevHandle 设备索引号
* @retval 关闭设备的状态
*/
[DllImport("USB2XXX.dll")]
public static extern bool USB_CloseDevice(Int32 DevHandle);
/**
* @brief 复位设备程序复位后需要重新调用USB_ScanDeviceUSB_OpenDevice函数
* @param DevHandle 设备索引号
* @retval 复位设备的状态
*/
[DllImport("USB2XXX.dll")]
public static extern bool USB_ResetDevice(Int32 DevHandle);
/**
* @brief 检测到USB断开连接后重新连接设备
* @param DevHandle 设备号
* @retval 重连状态
*/
[DllImport("USB2XXX.dll")]
public static extern bool USB_RetryConnect(Int32 DevHandle);
/**
* @brief 获取设备信息,比如设备名称,固件版本号,设备序号,设备功能说明字符串等
* @param DevHandle 设备索引号
* @param pDevInfo 设备信息存储结构体指针
* @param pFunctionStr 设备功能说明字符串
* @retval 获取设备信息的状态
*/
[DllImport("USB2XXX.dll")]
public static extern bool DEV_GetDeviceInfo(Int32 DevHandle, ref DEVICE_INFO pDevInfo, StringBuilder pFunctionStr);
/**
* @brief 擦出用户区数据
* @param DevHandle 设备索引号
* @retval 用户区数据擦出状态
*/
[DllImport("USB2XXX.dll")]
public static extern bool DEV_EraseUserData(Int32 DevHandle);
/**
* @brief 向用户区域写入用户自定义数据,写入数据之前需要调用擦出函数将数据擦出
* @param DevHandle 设备索引号
* @param OffsetAddr 数据写入偏移地址起始地址为0x00用户区总容量为0x10000字节也就是64KBye
* @param pWriteData 用户数据缓冲区首地址
* @param DataLen 待写入的数据字节数
* @retval 写入用户自定义数据状态
*/
[DllImport("USB2XXX.dll")]
public static extern bool DEV_WriteUserData(Int32 DevHandle, Int32 OffsetAddr, byte[] pWriteData, Int32 DataLen);
/**
* @brief 从用户自定义数据区读出数据
* @param DevHandle 设备索引号
* @param OffsetAddr 数据写入偏移地址起始地址为0x00用户区总容量为0x10000字节也就是64KBye
* @param pReadData 用户数据缓冲区首地址
* @param DataLen 待读出的数据字节数
* @retval 读出用户自定义数据的状态
*/
[DllImport("USB2XXX.dll")]
public static extern bool DEV_ReadUserData(Int32 DevHandle, Int32 OffsetAddr, byte[] pReadData, Int32 DataLen);
/**
* @brief 设置可变电压输出引脚输出电压值
* @param DevHandle 设备索引号
* @param PowerLevel 输出电压值
* @retval 设置输出电压状态
*/
[DllImport("USB2XXX.dll")]
public static extern bool DEV_SetPowerLevel(Int32 DevHandle, byte PowerLevel);
/**
* @brief 或者CAN或者LIN的时间戳原始值
* @param DevHandle 设备索引号
* @param pTimestamp 时间戳指针
* @retval 获取时间戳状态
*/
[DllImport("USB2XXX.dll")]
public static extern bool DEV_GetTimestamp(Int32 DevHandle, byte BusType, Int32[] pTimestamp);
/**
* @brief 复位CAN/LIN时间戳需要在初始化CAN/LIN之后调用
* @param DevHandle 设备索引号
* @retval 复位时间戳状态
*/
[DllImport("USB2XXX.dll")]
public static extern bool DEV_ResetTimestamp(Int32 DevHandle);
/**
* @brief 获取dll编译日期
* @param pDateTime 输出DLL编译日期字符串
* @retval 获取dll编译日期字符串
*/
[DllImport("USB2XXX.dll")]
public static extern bool DEV_GetDllBuildTime(StringBuilder pDateTime);
}
}