You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

339 lines
15 KiB
C#

using CompressorXN_Common;
using CompressorXN_Log;
using CompressorXN_Model.Enums;
using System;
using System.Runtime.InteropServices;
using System.Threading;
using thinger.DataConvertLib;
using USB2XXX;
namespace CompressorXN_Communication.TuMos
{
public class TMSCANHelper : BaseTMS
{
private static Int32 SendMsgNum = 0;
private static Int32 ret = 0;
private static Thread CANSendMsgThread = null;
//private static Thread CANSenAdditionalMsgThread = null;
private static Thread CANReadMsgThread = null;
/// <summary>
/// 启动线程
/// </summary>
public static void CAN_StartTask()
{
//清空接收缓冲区数据
ret = USB2CAN.CAN_ClearMsg(DevHandle, ReadCANIndex);
if (ret != USB2CAN.CAN_SUCCESS)
{
Console.WriteLine("Clear Message Failed!");
return;
}
else
{
Console.WriteLine("Clear Message Success!");
}
//启动CAN接收数据
ret = USB2CAN.CAN_StartGetMsg(DevHandle, ReadCANIndex);
if (ret != USB2CAN.CAN_SUCCESS)
{
Console.WriteLine("Start CAN failed!");
return;
}
else
{
Console.WriteLine("Start CAN Success!");
}
if (CANReadMsgThread == null)
{
CANReadMsgThread = new Thread(new ThreadStart(ReadCanMsgThread));
CANReadMsgThread.Start();
}
if (CANSendMsgThread == null)
{
CANSendMsgThread = new Thread(new ThreadStart(SendCanMsgThread));
CANSendMsgThread.Start();
}
GlobalVar.CAN_ReadMsgFlag = true;
GlobalVar.CAN_SendMsgFlag = true;
// CANSendMsgThread = new Thread(new ThreadStart(SendCanMsgThread));
//// CANSenAdditionalMsgThread = new Thread(new ThreadStart(SendAdditionalCanMsg));
// CANReadMsgThread = new Thread(new ThreadStart(ReadCanMsgThread));
// //清空接收缓冲区数据
// ret = USB2CAN.CAN_ClearMsg(DevHandle, ReadCANIndex);
// if (ret != USB2CAN.CAN_SUCCESS)
// {
// Console.WriteLine("Clear Message Failed!");
// return;
// }
// else
// {
// Console.WriteLine("Clear Message Success!");
// }
// //启动CAN接收数据
// ret = USB2CAN.CAN_StartGetMsg(DevHandle, ReadCANIndex);
// if (ret != USB2CAN.CAN_SUCCESS)
// {
// Console.WriteLine("Start CAN failed!");
// return;
// }
// else
// {
// Console.WriteLine("Start CAN Success!");
// }
// //启动接收数据线程
// GlobalVar.CAN_ReadMsgFlag = true;
// CANReadMsgThread.Start();
// //CANSenAdditionalMsgThread.Start();
// //启动发送数据线程
// GlobalVar.CAN_SendMsgFlag = true;
// CANSendMsgThread.Start();
}
/// <summary>
/// 停止线程
/// </summary>
public static void CAN_StopTask()
{
GlobalVar.CAN_SendMsgFlag = false;
}
/// <summary>
/// 发送CAN数据
/// </summary>
public static void SendCanMsgThread()
{
while (true)
{
if (!GlobalVar.CAN_SendMsgFlag)
{
Thread.Sleep(10);
continue;
}
USB2CAN.CAN_MSG[] CanMsg = new USB2CAN.CAN_MSG[1];
CanMsg[0] = new USB2CAN.CAN_MSG
{
ExternFlag = GlobalVar.agreementMsgVM.FrameType == "EXTEND" ? (byte)1 : (byte)0, //bit[0] - 是否是扩展帧,bit[7] - 当前帧为错误帧
RemoteFlag = 0,//bit[0]-是否是远程帧,bit[6..5]-当前帧通道号bit[7]-发送帧标志
ID = Convert.ToUInt32(GlobalVar.agreementMsgVM.SendId, 16),//报文ID
DataLen = (byte)(GlobalVar.agreementMsgVM.FrameLen & 0xFF)//数据长度(<=8)即Data中有效数据长度
};
switch (GlobalVar.stepEnum)
{
case StepEnum.idling:
string idlingHex = GlobalVar.agreementMsgVM.IdlingHex;
if (!string.IsNullOrEmpty(idlingHex))
{
CanMsg[0].Data = ByteArrayLib.GetByteArrayFromHexString(idlingHex);
}
break;
case StepEnum.speed1:
string speed1Hex = GlobalVar.agreementMsgVM.Speed1Hex;
if (!string.IsNullOrEmpty(speed1Hex))
{
Console.WriteLine($"{DateTime.Now.ToString("mm:ss fff")}speed1Hex=={speed1Hex}");
CanMsg[0].Data = ByteArrayLib.GetByteArrayFromHexString(speed1Hex);
}
break;
case StepEnum.speed2:
string speed2Hex = GlobalVar.agreementMsgVM.Speed2Hex;
if (!string.IsNullOrEmpty(speed2Hex))
{
Console.WriteLine($"{DateTime.Now.ToString("mm:ss fff")}speed2Hex=={speed2Hex}");
CanMsg[0].Data = ByteArrayLib.GetByteArrayFromHexString(speed2Hex);
}
break;
case StepEnum.speed3:
string speed3Hex = GlobalVar.agreementMsgVM.Speed3Hex;
if (!string.IsNullOrEmpty(speed3Hex))
{
Console.WriteLine($"{DateTime.Now.ToString("mm:ss fff")}speed3Hex=={speed3Hex}");
CanMsg[0].Data = ByteArrayLib.GetByteArrayFromHexString(speed3Hex);
}
break;
case StepEnum.endolead:
string endoleadHex = GlobalVar.agreementMsgVM.EndoleadHex;
if (string.IsNullOrEmpty(endoleadHex))
{
CanMsg[0].Data = ByteArrayLib.GetByteArrayFromHexString(endoleadHex);
}
break;
case StepEnum.singleDriver:
string singleDriverHex = GlobalVar.agreementMsgVM.SingleDriverHex;
if (!string.IsNullOrEmpty(singleDriverHex))
{
CanMsg[0].Data = ByteArrayLib.GetByteArrayFromHexString(singleDriverHex);
}
break;
}
int SendedNum = USB2CAN.CAN_SendMsg(DevHandle, WriteCANIndex, CanMsg, (UInt32)CanMsg.Length);
if (SendedNum >= 0)
{
SendMsgNum += SendedNum;
Console.WriteLine($"{DateTime.Now.ToString("mm:ss fff")}Success send frames:{SendMsgNum}");
}
else
{
Console.WriteLine("Send CAN data failed!");
break;
}
//附加报文
if (!string.IsNullOrEmpty(GlobalVar.agreementMsgVM.SendAdditionalRules.AdditionalSendId))
{
Thread.Sleep(GlobalVar.agreementMsgVM.SendAdditionalRules.AdditionalPeriod);
USB2CAN.CAN_MSG[] additionalCanMsg = new USB2CAN.CAN_MSG[1];
additionalCanMsg[0] = new USB2CAN.CAN_MSG
{
ExternFlag = GlobalVar.agreementMsgVM.FrameType == "EXTEND" ? (byte)1 : (byte)0, //bit[0] - 是否是扩展帧,bit[7] - 当前帧为错误帧
RemoteFlag = 0,//bit[0]-是否是远程帧,bit[6..5]-当前帧通道号bit[7]-发送帧标志
ID = Convert.ToUInt32(GlobalVar.agreementMsgVM.SendAdditionalRules.AdditionalSendId, 16),//报文ID
DataLen = 8,//数据长度(<=8)即Data中有效数据长度
Data = ByteArrayLib.GetByteArrayFromHexString(GlobalVar.agreementMsgVM.SendAdditionalRules.AdditionalContent)
};
SendedNum = USB2CAN.CAN_SendMsg(DevHandle, WriteCANIndex, additionalCanMsg, (UInt32)additionalCanMsg.Length);
if (SendedNum >= 0)
{
SendMsgNum += SendedNum;
Console.WriteLine("Success send frames:{0}", SendMsgNum);
}
else
{
Console.WriteLine("Send CAN data failed!");
break;
}
}
//Thread.Sleep(45);
Thread.Sleep(GlobalVar.agreementMsgVM.SendPeriod);
}
}
/// <summary>
/// 发送附加报文
/// </summary>
public static void SendAdditionalCanMsg()
{
while (GlobalVar.CAN_SendMsgFlag)
{
//附加报文
if (!string.IsNullOrEmpty(GlobalVar.agreementMsgVM.SendAdditionalRules.AdditionalSendId))
{
USB2CAN.CAN_MSG[] additionalCanMsg = new USB2CAN.CAN_MSG[1];
additionalCanMsg[0] = new USB2CAN.CAN_MSG
{
ExternFlag = GlobalVar.agreementMsgVM.FrameType == "EXTEND" ? (byte)1 : (byte)0, //bit[0] - 是否是扩展帧,bit[7] - 当前帧为错误帧
RemoteFlag = 0,//bit[0]-是否是远程帧,bit[6..5]-当前帧通道号bit[7]-发送帧标志
ID = Convert.ToUInt32(GlobalVar.agreementMsgVM.SendAdditionalRules.AdditionalSendId, 16),//报文ID
DataLen = 8,//数据长度(<=8)即Data中有效数据长度
Data = ByteArrayLib.GetByteArrayFromHexString(GlobalVar.agreementMsgVM.SendAdditionalRules.AdditionalContent)
};
int SendedNum = USB2CAN.CAN_SendMsg(DevHandle, WriteCANIndex, additionalCanMsg, (UInt32)additionalCanMsg.Length);
if (SendedNum >= 0)
{
SendMsgNum += SendedNum;
Console.WriteLine("Success send additional frames:{0}", SendMsgNum);
}
else
{
Console.WriteLine("Send CAN additional data failed!");
break;
}
}
Thread.Sleep(GlobalVar.agreementMsgVM.SendAdditionalRules.AdditionalPeriod);
}
}
/// <summary>
/// 接收CAN数据
/// </summary>
public static void ReadCanMsgThread()
{
while (true)
{
if (!GlobalVar.CAN_ReadMsgFlag)
{
Thread.Sleep(10);
continue;
}
USB2CAN.CAN_MSG[] CanMsgBuffer = new USB2CAN.CAN_MSG[1024];
//申请数据缓冲区
IntPtr pt = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(USB2CAN.CAN_MSG)) * CanMsgBuffer.Length);
int CanNum = USB2CAN.CAN_GetMsgWithSize(DevHandle, ReadCANIndex, pt, CanMsgBuffer.Length);
if (CanNum > 0)
{
for (int i = 0; i < CanNum; i++)
{
//从缓冲区中获取数据
CanMsgBuffer[i] = (USB2CAN.CAN_MSG)Marshal.PtrToStructure((IntPtr)((UInt32)pt + i * Marshal.SizeOf(typeof(USB2CAN.CAN_MSG))), typeof(USB2CAN.CAN_MSG));
//判断获取的是不是目标报文
if (CanMsgBuffer[i].ID == Convert.ToUInt32(GlobalVar.agreementMsgVM.ReciveId, 16) && CanMsgBuffer[i].DataLen == 8)
{
//如果信号值不为空,要过滤信号值
if (!string.IsNullOrEmpty(GlobalVar.agreementMsgVM.ReciveSignalVal))
{
Console.WriteLine("接收目标报文");
if (Convert.ToUInt32(GlobalVar.agreementMsgVM.ReciveSignalVal, 16) == CanMsgBuffer[i].Data[0])
{
//记录日志
//LogHelper.Error(null,$"CanMsgBuffer[{i}].ID={CanMsgBuffer[i].ID}CanMsgBuffer[{i}].Data=" + StringLib.GetHexStringFromByteArray(CanMsgBuffer[i].Data));
GetCANReciveValHelper.GetReciveVal(CanMsgBuffer[i].Data);//从接收报文中解析实际值
}
}
else
{
GetCANReciveValHelper.GetReciveVal(CanMsgBuffer[i].Data);//从接收报文中解析实际值
}
}
}
}
else if (CanNum < 0)
{
Console.WriteLine("Get CAN data error!");
LogHelper.Error(null, "Get CAN data error!");
break;
}
//释放数据缓冲区,必须释放,否则程序运行一段时间后会报内存不足
Marshal.FreeHGlobal(pt);
//Thread.Sleep(GlobalVar.agreementMsgVM.RecivePeriod);
Thread.Sleep(50);
}
}
/// <summary>
/// 获取CAN总状态
/// </summary>
private static void GetCanStatus()
{
USB2CAN.CAN_STATUS CANStatus = new USB2CAN.CAN_STATUS();
ret = USB2CAN.CAN_GetStatus(DevHandle, WriteCANIndex, ref CANStatus);
if (ret == USB2CAN.CAN_SUCCESS)
{
Console.WriteLine("TSR = {0:X8}", CANStatus.TSR);
Console.WriteLine("ESR = {0:X8}", CANStatus.ESR);
Console.WriteLine("CAN控制器接收错误计数 = {0}", CANStatus.RECounter);
Console.WriteLine("CAN控制器发送错误计数 = {0}", CANStatus.TECounter);
Console.WriteLine("最后的错误代码 = {0}", CANStatus.LECode);
}
else
{
Console.WriteLine("Get CAN status error!\n");
}
}
}
}