添加项目文件。

This commit is contained in:
2025-02-28 22:23:13 +08:00
parent d4ad2fe2de
commit 547a1b3bf6
416 changed files with 72830 additions and 0 deletions

View File

@@ -0,0 +1,314 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace OrpaonEMS.App.CANDrive
{
/// <summary>
/// 液冷AC数据解析
/// CAN 解析解析数据
/// 协议数据执行Motorola LSB格式数据类型= Unsigned
///协议内基于CAN2.0B的扩展帧。
///CAN 2.0B的29bit扩展ID帧标识符进行的分段定义
/// </summary>
public class ACCANParsData
{
public static Msg_0x18008040 msg_0X18008040 { get; set; } = new Msg_0x18008040();
public static Msg_0x18018040 msg_0X18018040 { get; set; } = new Msg_0x18018040();
/// <summary>
/// 获取0x18008040
/// </summary>
/// <returns></returns>
public static void Load_0x18008040_Msg(CAN_FRAME_INFO srData)
{
msg_0X18008040.WorkState = (int)GetMotorolaSignalValue(srData.data, 0, 8, 1, 0);
msg_0X18008040.OutTemp = GetMotorolaSignalValue(srData.data, 8, 8, 1, -40);
msg_0X18008040.InTemp = GetMotorolaSignalValue(srData.data, 16, 8, 1, -40);
msg_0X18008040.SysEnvTemp = GetMotorolaSignalValue(srData.data, 24, 8, 1, -40);
msg_0X18008040.InPress = GetMotorolaSignalValue(srData.data, 32, 8, 0.1, 0);
msg_0X18008040.OutPress = GetMotorolaSignalValue(srData.data, 40, 8, 0.1, 0);
msg_0X18008040.InverterErrCode = (int)GetMotorolaSignalValue(srData.data, 48, 8, 1, 0);
msg_0X18008040.ErrCode = (int)GetMotorolaSignalValue(srData.data, 56, 6, 1, 0);
msg_0X18008040.ErrLevel = (int)GetMotorolaSignalValue(srData.data, 62, 2, 1, 0);
}
/// <summary>
/// 获取0x18018040
/// </summary>
/// <returns></returns>
public static void Load_0x18018040_Msg(CAN_FRAME_INFO srData)
{
msg_0X18018040.CompressorState = (int)GetMotorolaSignalValue(srData.data, 0, 1, 1, 0);
msg_0X18018040.CompressorHeatStripState = (int)GetMotorolaSignalValue(srData.data, 1, 1, 1, 0);
msg_0X18018040.EleHeatState = (int)GetMotorolaSignalValue(srData.data, 2, 1, 1, 0);
msg_0X18018040.WaterPumpState = (int)GetMotorolaSignalValue(srData.data, 3, 1, 1, 0);
msg_0X18018040.FanState1 = (int)GetMotorolaSignalValue(srData.data, 4, 1, 1, 0);
msg_0X18018040.FanState2 = (int)GetMotorolaSignalValue(srData.data, 5, 1, 1, 0);
msg_0X18018040.FanState3 = (int)GetMotorolaSignalValue(srData.data, 6, 1, 1, 0);
msg_0X18018040.CompressorSpeed = GetMotorolaSignalValue(srData.data, 8, 8, 100, 0);
msg_0X18018040.PumpSpeed = GetMotorolaSignalValue(srData.data, 16, 8, 100, 0);
}
///// <summary>
///// 获取交流 电流 电压 测量 值
///// </summary>
///// <returns></returns>
//public static void Load_AC_Sense_Msg(AC_Sense_Msg aC_Sense_Msg, VCI_CAN_OBJ srData)
//{
// aC_Sense_Msg.A_Vol = GetIntelSignalValue(srData.Data, 0, 10, 1, -512);
// aC_Sense_Msg.B_Vol = GetIntelSignalValue(srData.Data, 10, 10, 1, -512);
// aC_Sense_Msg.C_Vol = GetIntelSignalValue(srData.Data, 20, 10, 1, -512);
// aC_Sense_Msg.A_Cur = GetIntelSignalValue(srData.Data, 30, 10, 1, -512);
// aC_Sense_Msg.B_Cur = GetIntelSignalValue(srData.Data, 40, 10, 1, -512);
// aC_Sense_Msg.C_Cur = GetIntelSignalValue(srData.Data, 50, 10, 1, -512);
//}
///// <summary>
///// 获取 直流 电流 电压 和交直流 交直流 功率 测量 值
///// </summary>
///// <returns></returns>
//public static void Load_DC_Power_Sense_Msg(DC_Power_Sense_Msg value, VCI_CAN_OBJ srData)
//{
// value.Vbus_Ave = GetIntelSignalValue(srData.Data, 0, 11, 1, 0);
// value.Ibat_Ave = GetIntelSignalValue(srData.Data, 11, 10, 1, -512);
// value.PwrAC = GetIntelSignalValue(srData.Data, 21, 19, 1, -256000);
// value.PwrDC = GetIntelSignalValue(srData.Data, 40, 19, 1, -256000);
//}
///// <summary>
///// 获取 状态 帧
///// </summary>
///// <returns></returns>
//public static void Load_State_Sense_Msg(State_Sense_Msg value, VCI_CAN_OBJ srData)
//{
// //冷却液进口温度测量值
// value.Coolant_Tin_Sense = GetIntelSignalValue(srData.Data, 0, 8, 1, -64);
// value.Coolant_Tout_Sense = GetIntelSignalValue(srData.Data, 8, 8, 1, -64);
// value.IGBT_Tmax_Sense = GetIntelSignalValue(srData.Data, 16, 8, 1, -64);
// value.Vac_Freq_Sense = GetIntelSignalValue(srData.Data, 24, 8, 0.25, 0);
// value.DrvCtrlModel = GetIntelSignalValue(srData.Data, 32, 4, 1, 0);
// switch (value.DrvCtrlModel)
// {
// case 0:
// value.DrvCtrlModel_State = PCSDriveCtrlMode.NotActive;
// break;
// case 1:
// value.DrvCtrlModel_State = PCSDriveCtrlMode.Init;
// break;
// case 2:
// value.DrvCtrlModel_State = PCSDriveCtrlMode.PreCharge;
// break;
// case 3:
// value.DrvCtrlModel_State = PCSDriveCtrlMode.Standby;
// break;
// case 5:
// value.DrvCtrlModel_State = PCSDriveCtrlMode.GridDisChg;
// break;
// case 8:
// value.DrvCtrlModel_State = PCSDriveCtrlMode.Failure;
// break;
// default:
// break;
// }
// value.GateDrvModel = GetIntelSignalValue(srData.Data, 36, 2, 1, 0);
// switch (value.GateDrvModel)
// {
// case 0:
// value.GateDrvModel_State = PCSGateDriveMode.Freewheel;
// break;
// case 1:
// value.GateDrvModel_State = PCSGateDriveMode.ShortCircuit;
// break;
// case 2:
// value.GateDrvModel_State = PCSGateDriveMode.PWNRun;
// break;
// default:
// break;
// }
// value.flgTColantDerat = GetIntelSignalValue(srData.Data, 38, 1, 1, 0);
// switch (value.flgTColantDerat)
// {
// case 0:
// value.flgTColantDerat_State = PCSFlgColantDeratModel.Off;
// break;
// case 1:
// value.flgTColantDerat_State = PCSFlgColantDeratModel.On;
// break;
// default:
// break;
// }
// value.Runcrnd = GetIntelSignalValue(srData.Data, 39, 1, 1, 0);
// switch (value.Runcrnd)
// {
// case 0:
// value.Runcrnd_State = PCSRuncmdModel.Stop;
// break;
// case 1:
// value.Runcrnd_State = PCSRuncmdModel.Run;
// break;
// default:
// break;
// }
//}
//public static void Load_Fault_T_F_Sense_Msg(Fault_T_F_Sense_Msg value, VCI_CAN_OBJ srData)
//{
// value.HW_Fault = GetIntelSignalValue(srData.Data, 0, 16, 1, 0);
// value.Env_Fault = GetIntelSignalValue(srData.Data, 16, 32, 1, 0);
//}
/// <summary>
/// 当前发送的Intel的数据
/// </summary>
private byte[] CurrentSendIntelSignal { get; set; } = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
/// <summary>
/// intel格式CAN报文 转 数值
/// </summary>
/// <param name="data">CAN报文</param>
/// <param name="startBit">信号起始bit</param>
/// <param name="bitLength">信号总长度</param>
/// <param name="factor">精度值</param>
/// <param name="offset">偏移值</param>
/// <returns>数值</returns>
public static double GetIntelSignalValue(byte[] data, int startBit, int bitLength, double factor, double offset)
{
ulong canSignalValue = 0;
for (int i = data.Length - 1; i >= 0; i--)
{
canSignalValue += (ulong)data[i] << i * 8;
}
int x = startBit / 8;
int y = startBit % 8;
int rightMoveCount = x * 8 + y;
canSignalValue >>= rightMoveCount;
canSignalValue = canSignalValue & ulong.MaxValue >> 64 - bitLength;
double values = canSignalValue * factor + offset;
return values;
}
/// <summary>
/// 数值 转 intel格式CAN报文
/// </summary>
/// <param name="values">物理信号值</param>
/// <param name="startBit">信号起始bit</param>
/// <param name="bitLength">信号总长度</param>
/// <param name="factor">精度值</param>
/// <param name="offset">偏移值</param>
/// <returns>intel格式CAN报文</returns>
public static byte[] ValueToIntelSignal(double values, int startBit, int bitLength, double factor, double offset)
{
byte[] IntelSignal = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
ulong data = Convert.ToUInt64((values - offset) / factor);
int dataLength = bitLength / 8 + (bitLength / 4) % 2;
int IntelSignal_pos = startBit / 8;
for (int Count = 0; Count < dataLength; Count++, IntelSignal_pos++)
{
ulong lowBit = (data >> (8 * Count)) & 0xFF; // 将数据移至低8位并取出
IntelSignal[IntelSignal_pos] = Convert.ToByte(lowBit);
}
return IntelSignal;
}
/// <summary>
/// 数值 转 intel格式CAN报文
/// </summary>
/// <param name="values">物理信号值</param>
/// <param name="startBit">信号起始bit</param>
/// <param name="bitLength">信号总长度</param>
/// <param name="factor">精度值</param>
/// <param name="offset">偏移值</param>
/// <returns>intel格式CAN报文</returns>
public static byte[] ValueToIntelSignal(byte[] IntelSignal, double values, int startBit, int bitLength, double factor, double offset)
{
//byte[] IntelSignal = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
ulong data = Convert.ToUInt64((values - offset) / factor);
int dataLength = bitLength / 8 + (bitLength / 4) % 2;
int IntelSignal_pos = startBit / 8;
for (int Count = 0; Count < dataLength; Count++, IntelSignal_pos++)
{
ulong lowBit = (data >> (8 * Count)) & 0xFF; // 将数据移至低8位并取出
IntelSignal[IntelSignal_pos] = Convert.ToByte(lowBit);
}
return IntelSignal;
}
/// <summary>
/// Motorola格式CAN报文 转 数值
/// </summary>
/// <param name="data">CAN报文</param>
/// <param name="startBit">信号起始bit</param>
/// <param name="bitLength">信号总长度</param>
/// <param name="factor">精度值</param>
/// <param name="offset">偏移值</param>
/// <returns>物理信号值</returns>
public static double GetMotorolaSignalValue(byte[] data, int startBit, int bitLength, double factor, double offset)
{
ulong canSignalValue = 0;
for (int i = data.Length - 1, j = 0; i >= 0; i--, j++)
{
canSignalValue += (ulong)data[j] << i * 8;
}
int x = startBit / 8;
int y = startBit % 8;
int z = x * 8 + bitLength - y;
int rightMoveCount = data.Length * 8 - z;
canSignalValue >>= rightMoveCount;
canSignalValue = canSignalValue & ulong.MaxValue >> 64 - bitLength;
double values = canSignalValue * factor + offset;
return values;
}
/// <summary>
/// 数值 转 Motorola格式CAN报文
/// </summary>
/// <param name="MotorolaSignal">CAN报文</param>
/// <param name="values">物理信号值</param>
/// <param name="startBit">信号起始bit</param>
/// <param name="bitLength">信号总长度</param>
/// <param name="factor">精度值</param>
/// <param name="offset">偏移值</param>
/// <returns>Motorola格式CAN报文</returns>
public static byte[] ValueToMotorolaSignal_Part(byte[] MotorolaSignal, double values, int startBit, int bitLength, double factor, double offset)
{
// = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
ulong data = Convert.ToUInt64((values - offset) / factor);
int dataLength = bitLength / 8 + (bitLength / 4) % 2;
int str_length = data.ToString().Length;
int MotorolaSignal_pos = startBit / 8;
data = str_length % 2 != 0 ? data << 4 : data;
for (int Count = dataLength - 1; Count >= 0; Count--, MotorolaSignal_pos++)
{
ulong newBit = (data >> (8 * Count)) & 0xFF;
ulong newBit2 = ((newBit << 4) & 0xF0) + ((newBit >> 4) & 0x0F);
ulong Bit = (data > 0x0F & bitLength > 8) ? newBit2 : newBit;
MotorolaSignal[MotorolaSignal_pos] = Convert.ToByte(Bit);
}
return MotorolaSignal;
}
}
}

View File

@@ -0,0 +1,33 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace OrpaonEMS.App.CANDrive
{
public class BinaryValue
{
/// <summary>
/// 实例化函数
/// </summary>
/// <param name="index"></param>
/// <param name="value"></param>
public BinaryValue(ushort index, bool value)
{
Index = index;
Value = value;
}
/// <summary>
/// 序号
/// </summary>
public ushort Index { get; set; }
/// <summary>
/// 二进制数据
/// </summary>
public bool Value { get; set; }
}
}

View File

@@ -0,0 +1,955 @@
using ImTools;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace OrpaonEMS.App.CANDrive
{
/// <summary>
/// CAN驱动
/// EMUC-B202-W1_CAN_API_V2.2.0_Win
/// EMUC-B202-W1_CAN 有两个CAN口目前工控机接出来的是CAN2口那么调用和使用的时候使用CAN2口在一些函数使用的过程中
/// 需要同时指定两个口的参数,那么另一个不适用的随便设置
/// </summary>
public class CAN
{
const string LibName = @"C:\\CAN_inno\\EMUC-B202-W1_CAN_API_V2.2.0_Win\\2.0B_Lib_v2.2.0\\64\\lib_emuc2_64.dll";
/* load .dll */
[DllImport(LibName, CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
public static extern int EMUCOpenDevice(int com_port);
[DllImport(LibName, CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
public static extern int EMUCCloseDevice(int com_port);
/// <summary>
/// Get firmware and library version
/// </summary>
/// <param name="com_port"></param>
/// <param name="ver_info"></param>
/// <returns></returns>
[DllImport(LibName, CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
public static extern int EMUCShowVer(int com_port, ref VER_INFO ver_info);
[DllImport(LibName, CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
public static extern int EMUCResetCAN(int com_port);
[DllImport(LibName, CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
public static extern int EMUCClearFilter(int com_port, int CAN_port);
/// <summary>
/// Set CAN port to active/inactive. Default is inactive.
/// </summary>
/// <param name="com_port"></param>
/// <param name="CAN1_sts"></param>
/// <param name="CAN2_sts"></param>
/// <returns></returns>
[DllImport(LibName, CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
public static extern int EMUCInitCAN(int com_port, int CAN1_sts, int CAN2_sts);
[DllImport(LibName, CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
public static extern int EMUCSetBaudRate(int com_port, int CAN1_baud, int CAN2_baud);
[DllImport(LibName, CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
public static extern int EMUCSetMode(int com_port, int CAN1_mode, int CAN2_mode);
[DllImport(LibName, CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
public static extern int EMUCSetFilter(int com_port, ref FILTER_INFO filter_info);
[DllImport(LibName, CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
public static extern int EMUCSetErrorType(int com_port, int err_type);
/// <summary>
/// Set CAN acceptance filter
/// </summary>
/// <param name="com_port"></param>
/// <param name="cfg_info"></param>
/// <returns></returns>
[DllImport(LibName, CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
public static extern int EMUCGetCfg(int com_port, ref CFG_INFO cfg_info);
[DllImport(LibName, CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
public static extern int EMUCExpCfg(int com_port, [MarshalAs(UnmanagedType.LPStr)] string file_name);
[DllImport(LibName, CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
public static extern int EMUCImpCfg(int com_port, [MarshalAs(UnmanagedType.LPStr)] string file_name);
[DllImport(LibName, CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
public static extern int EMUCSend(int com_port, ref CAN_FRAME_INFO can_frame_info);
[DllImport(LibName, CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
public static extern int EMUCReceive(int com_port, ref CAN_FRAME_INFO can_frame_info);
[DllImport(LibName, CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
public static extern int EMUCReceiveNonblockCS(int com_port, uint cnt, uint interval, [Out] CAN_FRAME_INFO[] can_frame_info);
/// <summary>
/// 实例化函数
/// </summary>
public CAN()
{
}
/// <summary>
/// Can连接
/// </summary>
/// <returns></returns>
public static bool ConnectionCan(BaudRate ConBaudRate)
{
int i;
int j;
//返回值
int rtn;
//获取Com口给Global
Global.com_port = FindEmucDev();
if (Global.com_port >= 0)
{
Console.WriteLine("EMUC open device (COM {0}) successfully !\n", Global.com_port + 1);
/* ----- EMUCInitCAN() ----- */
rtn = EMUCInitCAN(Global.com_port, CANStatus.EMUC_INACTIVE.GetHashCode(), CANStatus.EMUC_INACTIVE.GetHashCode());
if (rtn == 0)
Console.WriteLine("EMUC initial CAN successfully !\n");
else
Console.WriteLine("EMUC initial CAN failed !\n");
/* ----- EMUCShowVer() ----- */
rtn = EMUCShowVer(Global.com_port, ref Global.ver_info);
if (rtn == 0)
{
Console.WriteLine("EMUC show version successfully !");
Console.WriteLine("FW ver: {0}", Global.ver_info.fw);
Console.WriteLine("LIB ver: {0}", Global.ver_info.api);
Console.WriteLine("Model: {0}\n", Global.ver_info.model);
}
else
Console.WriteLine("EMUC show version failed !\n");
/* ----- EMUCResetCAN() ----- */
rtn = EMUCResetCAN(Global.com_port);
if (rtn == 0)
Console.WriteLine("EMUC reset CAN successfully !\n");
else
Console.WriteLine("EMUC reset CAN failed !\n");
/* ----- EMUCClearFilter() ----- */
Global.CAN_port = CANPort.EMUC_CAN_2.GetHashCode();
rtn = EMUCClearFilter(Global.com_port, Global.CAN_port);
if (rtn == 0)
Console.WriteLine("EMUC clear filter successfully !\n");
else
Console.WriteLine("EMUC clear filter failed !\n");
/* ----- EMUCSetBaudRate() ----- */
rtn = EMUCSetBaudRate(Global.com_port, ConBaudRate.GetHashCode(), ConBaudRate.GetHashCode());
if (rtn == 0)
Console.WriteLine("EMUC set baud rate successfully !\n");
else
Console.WriteLine("EMUC set baud rate failed !\n");
/* ----- EMUCSetErrorType() ----- */
rtn = EMUCSetErrorType(Global.com_port, ErrType.EMUC_DIS_ALL.GetHashCode());
if (rtn == 0)
Console.WriteLine("EMUC set error type successfully !\n");
else
Console.WriteLine("EMUC set error type failed !\n");
/* ----- EMUCSetMode() ----- */
rtn = EMUCSetMode(Global.com_port, CANMode.EMUC_NORMAL.GetHashCode(), CANMode.EMUC_NORMAL.GetHashCode());
if (rtn == 0)
Console.WriteLine("EMUC set mode successfully !\n");
else
Console.WriteLine("EMUC set mode failed !\n");
/* ----- CAN1的设置 EMUCSetFilter() ----- */
Global.filter_info.CAN_port = CANPort.EMUC_CAN_1.GetHashCode();
Global.filter_info.flt_type = IDType.EMUC_SID.GetHashCode();
Global.filter_info.flt_id = 0x0000ABCD;
Global.filter_info.mask = 0x1FFFFFFF;
rtn = EMUCSetFilter(Global.com_port, ref Global.filter_info);
if (rtn == 0)
Console.WriteLine("EMUC set CAN 1 filter successfully !\n");
else
Console.WriteLine("EMUC set CAN 1 filter failed !\n");
/* ----- CAN2的设置 EMUCSetFilter() ----- */
Global.filter_info.CAN_port = CANPort.EMUC_CAN_2.GetHashCode();
Global.filter_info.flt_type = IDType.EMUC_SID.GetHashCode();
Global.filter_info.flt_id = 0x00000000;
Global.filter_info.mask = 0x00000000;
rtn = EMUCSetFilter(Global.com_port, ref Global.filter_info);
if (rtn == 0)
Console.WriteLine("EMUC set CAN 2 filter successfully !\n");
else
Console.WriteLine("EMUC set CAN 2 filter failed !\n");
/* ----- EMUCGetCfg() ----- */
/* ----- 获取配置信息----- */
rtn = EMUCGetCfg(Global.com_port, ref Global.cfg_info);
if (rtn == 0)
{
Console.WriteLine("EMUC get config. successfully !");
for (i = 0; i < Global.CAN_NUM; i++)
{
Console.WriteLine("CAN {0}:", i + 1);
Console.WriteLine("baud rate = {0}", Global.cfg_info.baud[i]);
Console.WriteLine("mode = {0}", Global.cfg_info.mode[i]);
Console.WriteLine("filter type = {0}", Global.cfg_info.flt_type[i]);
Console.WriteLine("filter id = {0:X8}", Global.cfg_info.flt_id[i]);
Console.WriteLine("filter mask = {0:X8}\n", Global.cfg_info.flt_mask[i]);
}
Console.WriteLine("error set = {0}\n", Global.cfg_info.err_set);
}
else
Console.WriteLine("EMUC get config. failed !\n");
/* Send & Receive must initial CAN to EMUC_ACTIVE */
/*---------------------------------------------------------------------------*/
//EMUCClearFilter(Global.com_port, CANPort.EMUC_CAN_1.GetHashCode()); /* not necessary */
//EMUCClearFilter(Global.com_port, CANPort.EMUC_CAN_2.GetHashCode()); /* not necessary */
rtn = EMUCInitCAN(Global.com_port, CANStatus.EMUC_ACTIVE.GetHashCode(), CANStatus.EMUC_ACTIVE.GetHashCode());
if (rtn == 0)
{
return true;
}
else
{
return false;
}
}
else Console.WriteLine("No EMUC device !\n"); return false;
}
/// <summary>
/// 发送数据
/// </summary>
public static bool SendData(uint id, byte[] data)
{
//int i;
/* ----- EMUCSend ----- */
Global.frame_send.CAN_port = CANPort.EMUC_CAN_2.GetHashCode();//默认使用CAN2口
Global.frame_send.id_type = IDType.EMUC_EID.GetHashCode();//默认使用标准帧
Global.frame_send.rtr = RTRSelect.EMUC_DIS_RTR.GetHashCode();//默认使用数据帧,不是远程数据帧
Global.frame_send.dlc = 8;//默认数据长度为8
//Global.frame_send.id = 0x00000011;
Global.frame_send.id = id;
//Global.frame_send.data = Global.data_send;
Global.frame_send.data = data;
//Console.WriteLine("EMUC send started !");
//for (i = 0; i < Global.data_send_cnt; i++)
//{
// Thread.Sleep(1);
if (EMUCSend(Global.com_port, ref Global.frame_send) == 0)
{
//Console.WriteLine("EMUC send finished !\n", Global.data_send_cnt);
return true;
}
return false;
//EMUCSend(Global.com_port, ref Global.frame_send);
//}
Console.WriteLine("EMUC send finished (with {0} data) !\n", Global.data_send_cnt);
}
/// <summary>
///接受到的消息内容
/// </summary>
public static void Start()
{
/* ----- EMUCReceive() ----- */
Global.TRDRecv.Start();
Console.WriteLine("\nEMUC reveice start ...\n");
}
public void StartTest()
{
int i;
int j;
//返回值
int rtn;
/* for EMUCReceiveNonblockCS() */
uint cnt;
uint interval;
CAN_FRAME_INFO[] frame_non_block;
/*-----------------------------*/
//获取Com口给Global
Global.com_port = FindEmucDev();
if (Global.com_port >= 0)
{
Console.WriteLine("EMUC open device (COM {0}) successfully !\n", Global.com_port + 1);
/* ----- EMUCInitCAN() ----- */
rtn = EMUCInitCAN(Global.com_port, CANStatus.EMUC_INACTIVE.GetHashCode(), CANStatus.EMUC_INACTIVE.GetHashCode());
if (rtn == 0)
Console.WriteLine("EMUC initial CAN successfully !\n");
else
Console.WriteLine("EMUC initial CAN failed !\n");
/* ----- EMUCShowVer() ----- */
rtn = EMUCShowVer(Global.com_port, ref Global.ver_info);
if (rtn == 0)
{
Console.WriteLine("EMUC show version successfully !");
Console.WriteLine("FW ver: {0}", Global.ver_info.fw);
Console.WriteLine("LIB ver: {0}", Global.ver_info.api);
Console.WriteLine("Model: {0}\n", Global.ver_info.model);
}
else
Console.WriteLine("EMUC show version failed !\n");
/* ----- EMUCResetCAN() ----- */
rtn = EMUCResetCAN(Global.com_port);
if (rtn == 0)
Console.WriteLine("EMUC reset CAN successfully !\n");
else
Console.WriteLine("EMUC reset CAN failed !\n");
/* ----- EMUCClearFilter() ----- */
Global.CAN_port = CANPort.EMUC_CAN_1.GetHashCode();
rtn = EMUCClearFilter(Global.com_port, Global.CAN_port);
if (rtn == 0)
Console.WriteLine("EMUC clear filter successfully !\n");
else
Console.WriteLine("EMUC clear filter failed !\n");
/* ----- EMUCSetBaudRate() ----- */
rtn = EMUCSetBaudRate(Global.com_port, BaudRate.EMUC_BAUDRATE_1M.GetHashCode(), BaudRate.EMUC_BAUDRATE_1M.GetHashCode());
if (rtn == 0)
Console.WriteLine("EMUC set baud rate successfully !\n");
else
Console.WriteLine("EMUC set baud rate failed !\n");
/* ----- EMUCSetErrorType() ----- */
rtn = EMUCSetErrorType(Global.com_port, ErrType.EMUC_DIS_ALL.GetHashCode());
if (rtn == 0)
Console.WriteLine("EMUC set error type successfully !\n");
else
Console.WriteLine("EMUC set error type failed !\n");
/* ----- EMUCSetMode() ----- */
rtn = EMUCSetMode(Global.com_port, CANMode.EMUC_NORMAL.GetHashCode(), CANMode.EMUC_NORMAL.GetHashCode());
if (rtn == 0)
Console.WriteLine("EMUC set mode successfully !\n");
else
Console.WriteLine("EMUC set mode failed !\n");
/* ----- EMUCSetFilter() ----- */
Global.filter_info.CAN_port = CANPort.EMUC_CAN_1.GetHashCode();
Global.filter_info.flt_type = IDType.EMUC_EID.GetHashCode();
Global.filter_info.flt_id = 0x0000ABCD;
Global.filter_info.mask = 0x1FFFFFFF;
rtn = EMUCSetFilter(Global.com_port, ref Global.filter_info);
if (rtn == 0)
Console.WriteLine("EMUC set CAN 1 filter successfully !\n");
else
Console.WriteLine("EMUC set CAN 1 filter failed !\n");
Global.filter_info.CAN_port = CANPort.EMUC_CAN_2.GetHashCode();
Global.filter_info.flt_type = IDType.EMUC_EID.GetHashCode();
Global.filter_info.flt_id = 0x00001234;
Global.filter_info.mask = 0x00FFEEEE;
rtn = EMUCSetFilter(Global.com_port, ref Global.filter_info);
if (rtn == 0)
Console.WriteLine("EMUC set CAN 2 filter successfully !\n");
else
Console.WriteLine("EMUC set CAN 2 filter failed !\n");
/* ----- EMUCGetCfg() ----- */
rtn = EMUCGetCfg(Global.com_port, ref Global.cfg_info);
if (rtn == 0)
{
Console.WriteLine("EMUC get config. successfully !");
for (i = 0; i < Global.CAN_NUM; i++)
{
Console.WriteLine("CAN {0}:", i + 1);
Console.WriteLine("baud rate = {0}", Global.cfg_info.baud[i]);
Console.WriteLine("mode = {0}", Global.cfg_info.mode[i]);
Console.WriteLine("filter type = {0}", Global.cfg_info.flt_type[i]);
Console.WriteLine("filter id = {0:X8}", Global.cfg_info.flt_id[i]);
Console.WriteLine("filter mask = {0:X8}\n", Global.cfg_info.flt_mask[i]);
}
Console.WriteLine("error set = {0}\n", Global.cfg_info.err_set);
}
else
Console.WriteLine("EMUC get config. failed !\n");
/* ----- EMUCExpCfg() ----- */
rtn = EMUCExpCfg(Global.com_port, Global.file_name);
if (rtn == 0)
Console.WriteLine("EMUC export config. successfully !\n");
else
Console.WriteLine("EMUC export config. failed !\n");
/* ----- EMUCImpCfg() ----- */
rtn = EMUCImpCfg(Global.com_port, Global.file_name);
if (rtn == 0)
Console.WriteLine("EMUC import config. successfully !\n");
else
Console.WriteLine("EMUC import config. failed !\n");
/* Send & Receive must initial CAN to EMUC_ACTIVE */
/*---------------------------------------------------------------------------*/
EMUCClearFilter(Global.com_port, CANPort.EMUC_CAN_1.GetHashCode()); /* not necessary */
EMUCClearFilter(Global.com_port, CANPort.EMUC_CAN_2.GetHashCode()); /* not necessary */
EMUCInitCAN(Global.com_port, CANStatus.EMUC_ACTIVE.GetHashCode(), CANStatus.EMUC_ACTIVE.GetHashCode());
/* ----- EMUCSend ----- */
Global.frame_send.CAN_port = CANPort.EMUC_CAN_1.GetHashCode();
Global.frame_send.id_type = IDType.EMUC_EID.GetHashCode();
Global.frame_send.rtr = RTRSelect.EMUC_DIS_RTR.GetHashCode();
Global.frame_send.dlc = 8;
Global.frame_send.id = 0x001234AB;
Global.frame_send.data = Global.data_send;
Console.WriteLine("EMUC send started !");
for (i = 0; i < Global.data_send_cnt; i++)
{
Thread.Sleep(1);
EMUCSend(Global.com_port, ref Global.frame_send);
}
Console.WriteLine("EMUC send finished (with {0} data) !\n", Global.data_send_cnt);
/* ----- EMUCReceiveNonblock() ----- */
cnt = 5;
interval = 5 * 1000;
frame_non_block = new CAN_FRAME_INFO[cnt];
Console.WriteLine("Non-block ---------------------> Time start !");
rtn = EMUCReceiveNonblockCS(Global.com_port, cnt, interval, frame_non_block);
if (rtn > 0)
{
Console.WriteLine("Non-block ---------------------> Time out or Data enough !\n");
for (i = 0; i < rtn; i++)
{
switch (frame_non_block[i].msg_type)
{
case (int)MsgType.EMUC_DATA_TYPE:
PrintData(frame_non_block[i]);
break;
case (int)MsgType.EMUC_EEERR_TYPE:
Console.WriteLine("EEPROM Error !");
break;
case (int)MsgType.EMUC_BUSERR_TYPE:
Console.WriteLine("Bus Error !");
System.Console.Write("error data (CAN 1): ");
for (j = 0; j < Global.DATA_LEN_ERR; j++)
System.Console.Write("{0:X2} ", frame_non_block[i].data_err[j]);
Console.WriteLine();
System.Console.Write("error data (CAN 2): ");
for (j = 0; j < Global.DATA_LEN_ERR; j++)
System.Console.Write("{0:X2} ", frame_non_block[i].data_err[j + Global.DATA_LEN_ERR]);
Console.WriteLine();
break;
default:
break;
}
}
}
else
Console.WriteLine("Non-block ---------------------> Time out (No data) !\n");
/* ----- EMUCReceive() ----- */
Global.TRDRecv.Start();
Console.WriteLine("\nEMUC reveice start ...\n");
/* ----- EMUCCloseDevice() ----- */
/*
rtn = EMUCCloseDevice(Global.com_port);
if(rtn == 0)
Console.WriteLine("EMUC close device (COM {0}) successfully !\n", Global.com_port + 1);
else
Console.WriteLine("EMUC close device failed !\n");
*/
while (true)
Thread.Sleep(10000);
}
else
Console.WriteLine("No EMUC device !\n");
Console.ReadLine();
}
#region
/* success: return COM ID, failed: return -1 */
/*---------------------------------------------------------------------*/
/// <summary>
/// 打开后返回对应的Com口
/// 返回Com口的ID
/// </summary>
/// <returns></returns>
public static int FindEmucDev()
{
int i;
int rtn = -1;
for (i = 0; i < Global.MAX_COM_NUM; i++)
{
if (EMUCOpenDevice(i) == 0)
{
rtn = i;
break;
}
}
return rtn;
} /* END: FindEmucDev() */
/*---------------------------------------------------------------------*/
/// <summary>
/// 循环接受数据
/// </summary>
public static void TRDRecvFx()
{
int i;
int rtn;
while (true)
{
rtn = EMUCReceive(Global.com_port, ref Global.frame_recv);
if (rtn == 1)
{
switch (Global.frame_recv.msg_type)
{
case (int)MsgType.EMUC_DATA_TYPE:
PrintData(Global.frame_recv);
switch (Global.frame_recv.id)
{
case 402686016://ID(0x18008040)
ACCANParsData.Load_0x18008040_Msg(Global.frame_recv);
break;
case 402751552://ID(0x18018040)
ACCANParsData.Load_0x18018040_Msg(Global.frame_recv);
break;
default:
break;
}
break;
case (int)MsgType.EMUC_EEERR_TYPE:
Console.WriteLine("EEPROM Error !");
break;
case (int)MsgType.EMUC_BUSERR_TYPE:
//Console.WriteLine("Bus Error !");
//System.Console.Write("error data (CAN 1): ");
//for (i = 0; i < Global.DATA_LEN_ERR; i++)
// //System.Console.Write("{0:X2} ", Global.frame_recv.data_err[i]);
////Console.WriteLine();
//System.Console.Write("error data (CAN 2): ");
//for (i = 0; i < Global.DATA_LEN_ERR; i++)
// //System.Console.Write("{0:X2} ", Global.frame_recv.data_err[i + Global.DATA_LEN_ERR]);
////Console.WriteLine();
break;
default:
break;
}
}
}
} /* END: TRDRecvFx() */
public static void ParseData(byte[] data)
{
}
/*---------------------------------------------------------------------*/
/// <summary>
/// 打印数据
/// </summary>
/// <param name="frame_recv"></param>
public static void PrintData(CAN_FRAME_INFO frame_recv)
{
int i;
/* CAN port & cnt */
if (frame_recv.CAN_port == CANPort.EMUC_CAN_1.GetHashCode())
{
Global.recv_cnt1++;
//System.Console.Write("(CAN 1) {0}. ", Global.recv_cnt1);
}
else if (frame_recv.CAN_port == CANPort.EMUC_CAN_2.GetHashCode())
{
Global.recv_cnt2++;
//System.Console.Write("(CAN 2) {0}. ", Global.recv_cnt2);
}
/* ID */
//if (frame_recv.id_type == IDType.EMUC_SID.GetHashCode())
//System.Console.Write("ID: {0:X3}; ", frame_recv.id);
//else if (frame_recv.id_type == IDType.EMUC_EID.GetHashCode())
//System.Console.Write("ID: {0:X8}; ", frame_recv.id);
/* Data */
//System.Console.Write("Data: ");
//for (i = 0; i < frame_recv.dlc; i++)
//System.Console.Write("{0:X2} ", frame_recv.data[i]);
//Console.WriteLine();
} /* END: PrintData() */
#endregion
/* global variables */
public class Global
{
/// <summary>
/// 设备最大的COM数
/// </summary>
public const int MAX_COM_NUM = 256;
public const int CAN_NUM = 2;
public const int DATA_LEN = 8;
public const int DATA_LEN_ERR = 6;
/// <summary>
/// Com口
/// -1是失败的
/// </summary>
public static int com_port { get; set; }
/// <summary>
/// CAN口
/// </summary>
public static int CAN_port { get; set; }
[MarshalAs(UnmanagedType.LPStr)]
public static string file_name = "emuc_config";
public static int data_send_cnt = 500;
public static byte[] data_send = { 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88 };
public static uint recv_cnt1 = 0;
public static uint recv_cnt2 = 0;
/// <summary>
/// 版本信息
/// </summary>
public static VER_INFO ver_info = new VER_INFO();
/// <summary>
/// 过滤信息
/// </summary>
public static FILTER_INFO filter_info = new FILTER_INFO();
public static CFG_INFO cfg_info = new CFG_INFO();
public static CAN_FRAME_INFO frame_send = new CAN_FRAME_INFO();
public static CAN_FRAME_INFO frame_recv = new CAN_FRAME_INFO();
public static Thread TRDRecv = new Thread(TRDRecvFx);
}
}
/* structure */
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct VER_INFO
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 16)]
public string fw;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 16)]
public string api;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 16)]
public string model;
}
/// <summary>
///
/// CAN标识符、过滤器、屏蔽器之间的关系
///CAN节点通过标识符来识别CAN帧是不是自己想要的,识别方法就是通过滤波屏蔽寄存器的设置来完成,接收滤波寄存器设置了标识符每位的值,
///接收屏蔽寄存器一般有相同的数量匹配接收滤波寄存器,规定接收滤波寄存器标识符每一位的值是否需要进行匹配,比如芯片设置有6个接收滤波寄存器和6个接收屏蔽青存器,
///从总线上接收 CAN 帧,然后依次将收到的 CAN 帧标识符与6对接收滤波和屏蔽寄存器进行匹配,符合某对接收滤波和屏蔽寄存器要求了,就停止匹配,将数据接收到对应的缓冲区中..
///例如:设置某接收滤波寄存器 00000000001(11 位),接收屏蔽寄存器 11111111101(11 位),则该对组合会拒绝接收 00000000011和 00000000001 之外所有的标识符对应的 CAN 帧,
///因为屏蔽器规定第二位(为 0)以外的所有标识符位要严格匹配(与滤波器值一致),第二位的滤波器值和收到的 CAN 标识符第二位值是否一致都可以。
/// https://www.cnblogs.com/lijf/p/17418979.html
///对于机器来说我们要为它准备好两张纸片一片写上屏蔽码另一片纸片写上验证码屏蔽码上相应位为1时表示此位需要与验证码对应位进行比较反之则表示不需要。机器在执行任务的时候先将获取的身份证号码与屏蔽码进行“与”操作再将结果与验证码的进行比较根据判断是否相同来决定是否通过。整个判别流程如下所示
///从上图可以很容易地理解屏蔽码与验证码的含义,这样一来,能通过的结果数量就完全取决于屏蔽码,设得宽,则可以通过的多(所有位为0则不过任何过滤操作则谁都可以通过),设得窄,则通过的少(所有位设为1则只有一个能通过)。那么知道这个有什么用呢因为bxCAN的过滤器的掩码模式就是采用这种方式在bxCAN中分别采用了两个寄存器(CAN_FiR1,CAN_FiR2)来存储屏蔽码与验证码,从而实现掩码模式的工作流程的。这样,我们就知道了bxCAN过滤器的掩码模式的大概工作原理。
///
/// </summary>
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct FILTER_INFO
{
public int CAN_port;
/// <summary>
/// 过滤类型/方式
/// 比如:只收标准码,只收拓展码,接受所有类型
/// </summary>
public int flt_type;
/// <summary>
/// 过滤验收码
/// 就是要接收的帧ID
/// </summary>
public uint flt_id;
/// <summary>
/// 过滤屏蔽码
/// 就是选择性的过滤帧ID。
/// 当屏蔽码的某一位为1时则忽略此位此位不需要与验收码一致。当屏蔽码的某一位为0时此位必须与验收码的此位一致。
/// </summary>
public uint mask;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct CFG_INFO
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
public byte[] baud;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
public byte[] mode;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
public byte[] flt_type;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
public uint[] flt_id;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
public uint[] flt_mask;
public byte err_set;
}
#region
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct CAN_FRAME_INFO
{
/// <summary>
/// 哪个端口发送的
/// 当前的CAN模块有两个端口
/// </summary>
public int CAN_port;
/// <summary>
/// : [input] CAN ID type. (SID=11bit, EID=29bit)
/// 标准还是拓展
/// </summary>
public int id_type;
/// <summary>
/// [input] Remote transmit request
/// 远程还是数据帧
/// </summary>
public int rtr;
/// <summary>
/// dlc: [input] Data length.
/// 数据长度
/// </summary>
public int dlc;
/// <summary>
/// There three types of received data define in msg_type.
//1. EMUC_DATA_TYPE: Normal CAN frame.
//2. EMUC_EEERR_TYPE: EEPROM error message.
//3. EMUC_BUSERR_TYPE: Register of CANbus error status.
/// </summary>
public int msg_type;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 13)]
public string recv_time; /* e.g., 15:30:58:789 (h:m:s:ms) */
/// <summary>
/// 帧Id
/// </summary>
public uint id;
/// <summary>
/// 接受的数据
/// </summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
public byte[] data;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 12)]
public byte[] data_err;
}
/* enumeration */
enum CANPort : int
{
/// <summary>
/// CAN1
/// </summary>
EMUC_CAN_1 = 0,
/// <summary>
/// CAN2
/// </summary>
EMUC_CAN_2
};
/*----------------------*/
public enum BaudRate : int
{
EMUC_BAUDRATE_100K = 4,
EMUC_BAUDRATE_125K,
EMUC_BAUDRATE_250K,
EMUC_BAUDRATE_500K,
EMUC_BAUDRATE_800K,
EMUC_BAUDRATE_1M
};
/*----------------------*/
enum CANStatus : int
{
/// <summary>
/// 默认
/// 未激活
/// </summary>
EMUC_INACTIVE = 0,
/// <summary>
/// 激活
/// </summary>
EMUC_ACTIVE
};
/*----------------------*/
enum CANMode : int
{
/// <summary>
/// 正常
/// </summary>
EMUC_NORMAL = 0,
/// <summary>
/// 监听(只听)模式
/// </summary>
EMUC_LISTEN
};
/*----------------------*/
/// <summary>
/// 过滤类型/方式
///
/// 比如:只收标准码,只收拓展码,接受所有类型
///
/// ***也可以作为发送时的帧的类型的***
/// </summary>
public enum IDType : int
{
//0可能是接受所有类型
/// <summary>
/// SID=11bit
/// 标准帧
/// </summary>
EMUC_SID = 1,
/// <summary>
/// EID=29bit
/// Extended Mode
/// 拓展帧
/// </summary>
EMUC_EID
};
/*----------------------*/
enum RTRSelect : int
{
/// <summary>
/// 取消使用RTR
/// 普通的
/// 数据帧
/// </summary>
EMUC_DIS_RTR = 0,
/// <summary>
/// 启用RTR
/// 远程帧
/// </summary>
EMUC_EN_RTR
};
/*----------------------*/
/// <summary>
/// CAN Error Frame
/// </summary>
enum ErrType : int
{
/// <summary>
/// disable all error frame
/// </summary>
EMUC_DIS_ALL = 0,
/// <summary>
/// enable EEPROM error only
/// </summary>
EMUC_EE_ERR,
/// <summary>
/// enable CAN bus error only
/// </summary>
EMUC_BUS_ERR,
/// <summary>
/// enable both EERPOM and CAN bus error
/// </summary>
EMUC_EN_ALL = 255
};
/*----------------------*/
/// <summary>
/// There three types of received data define in msg_type
/// </summary>
enum MsgType : int
{
/// <summary>
/// Normal CAN frame
/// </summary>
EMUC_DATA_TYPE = 0,
/// <summary>
/// EEPROM error message
/// </summary>
EMUC_EEERR_TYPE,
/// <summary>
/// : Register of CANbus error status
/// </summary>
EMUC_BUSERR_TYPE
};
#endregion
}

View File

@@ -0,0 +1,35 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace OrpaonEMS.App.CANDrive
{
/// <summary>
/// 0x301直流 电流 电压 和交直流 交直流 功率 测量 值帧定义 /PCS1_DC_Power_SENSE_Msg
/// </summary>
public class DC_Power_Sense_Msg
{
/// <summary>
/// DC/电池侧电压平均值
/// </summary>
public double Vbus_Ave { get; set; }
/// <summary>
/// DC/电池侧电流平均值
/// </summary>
public double Ibat_Ave { get; set; }
/// <summary>
/// 交流侧功率测量侧
/// </summary>
public double PwrAC { get; set; }
/// <summary>
/// 直流侧功率测量侧
/// </summary>
public double PwrDC { get; set; }
}
}

View File

@@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace OrpaonEMS.App.CANDrive
{
public class Msg_0x04904000
{
}
}

View File

@@ -0,0 +1,67 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace OrpaonEMS.App.CANDrive
{
/// <summary>
/// https://blog.csdn.net/qq_41256212/article/details/95477467
/// 协议数据执行Motorola LSB格式数据类型= Unsigned
/// </summary>
public class Msg_0x18008040
{
/// <summary>
/// TMS 工作状态
/// 0:关机模式1制冷模式2制热模式3自循环模式4自动模式
/// </summary>
public int WorkState { get; set; }
/// <summary>
/// 出水温度
/// 分辨率1℃/bit 偏移量:-40℃范围-40~210℃255无效例如发送数据0x32(50),温度为50-40=10℃
/// </summary>
public double OutTemp { get; set; }
/// <summary>
/// 回水温度
/// 分辨率1℃/bit 偏移量:-40℃范围-40~210℃255无效例如发送数据0x32(50),温度为50-40=10℃
/// </summary>
public double InTemp { get; set; }
/// <summary>
/// 环境温度
/// 分辨率1℃/bit 偏移量:-40℃范围-40~210℃255无效例如发送数据0x32(50),温度为50-40=10℃
/// </summary>
public double SysEnvTemp { get; set; }
/// <summary>
/// 回水压力
/// 分辨率0.1bar/bit 偏移量0bar 255无效例如发送数据 0x32(50),温度为50-40=10℃
/// </summary>
public double InPress { get; set; }
/// <summary>
/// 供水压力
/// 分辨率0.1bar/bit 偏移量0bar 255无效例如发送数据 0x32(50),温度为50-40=10℃
/// </summary>
public double OutPress { get; set; }
/// <summary>
/// 变频器故障代码
/// </summary>
public int InverterErrCode { get; set; }
/// <summary>
/// 故障码
/// </summary>
public int ErrCode { get; set; }
/// <summary>
/// 故障等级
/// </summary>
public int ErrLevel { get; set; }
}
}

View File

@@ -0,0 +1,65 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace OrpaonEMS.App.CANDrive
{
public class Msg_0x18018040
{
/// <summary>
/// 压缩机
/// 0:关闭1开启
/// </summary>
public int CompressorState { get; set; }
/// <summary>
/// 压缩机加热带
/// 0:关闭1开启
/// </summary>
public int CompressorHeatStripState { get; set; }
/// <summary>
/// 电加热
/// 0:关闭1开启
/// </summary>
public int EleHeatState { get; set; }
/// <summary>
/// 供水泵
/// 0:关闭1开启
/// </summary>
public int WaterPumpState { get; set; }
/// <summary>
/// 风机 1
/// 0:关闭1开启
/// </summary>
public int FanState1 { get; set; }
/// <summary>
/// 风机 2
/// 0:关闭1开启
/// </summary>
public int FanState2 { get; set; }
/// <summary>
/// 风机 3
/// 0:关闭1开启
/// </summary>
public int FanState3 { get; set; }
/// <summary>
/// 压机转速
/// 分辨率100rpm/bit 偏移量0
/// </summary>
public double CompressorSpeed { get; set; }
/// <summary>
/// 泵转速
/// 分辨率100rpm/bit 偏移量0
/// </summary>
public double PumpSpeed { get; set; }
}
}

View File

@@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace OrpaonEMS.App.CANDrive
{
public class Msg_ErrL10x18068040
{
}
}

View File

@@ -0,0 +1,272 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace OrpaonEMS.App.CANDrive
{
public static class Int32Extensions
{
public static bool[] ToBooleanArray(this int i)
{
return Convert.ToString(i, 2 /*for binary*/).Select(s => s.Equals('1')).ToArray();
}
}
/// <summary>
/// 发送的CAN报文
/// 关于CAN报文用的Motorola还是Intel格式只在单个信号跨字节时解析才有区别。
/// </summary>
public class SendCanMsg
{
/// <summary>
/// 报文信息
/// </summary>
public static byte[] IntelSignal { get; set; } = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
/// <summary>
/// Motorola
/// </summary>
public static byte[] MotorolaSignal { get; set; } = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
public string bstr = "00000000";
/// <summary>
/// 二进制数据集合
/// </summary>
public static List<BinaryValue> ListBinaryValue { get; set; } = new List<BinaryValue>()
{
new BinaryValue(0,false),
new BinaryValue(1,false),
new BinaryValue(2,false),
new BinaryValue(3,false),
new BinaryValue(4,false),
new BinaryValue(5,false),
new BinaryValue(6,false),
new BinaryValue(7,false),
new BinaryValue(8,false),
new BinaryValue(9,false),
new BinaryValue(10,false),
new BinaryValue(11,false),
new BinaryValue(12,false),
new BinaryValue(13,false),
new BinaryValue(14,false),
new BinaryValue(15,false),
new BinaryValue(16,false),
new BinaryValue(17,false),
new BinaryValue(18,false),
new BinaryValue(19,false),
new BinaryValue(20,false),
new BinaryValue(21,false),
new BinaryValue(22,false),
new BinaryValue(23,false),
new BinaryValue(24,false),
new BinaryValue(25,false),
new BinaryValue(26,false),
new BinaryValue(27,false),
new BinaryValue(28,false),
new BinaryValue(29,false),
new BinaryValue(30,false),
new BinaryValue(31,false),
new BinaryValue(32,false),
new BinaryValue(33,false),
new BinaryValue(34,false),
new BinaryValue(35,false),
new BinaryValue(36,false),
new BinaryValue(37,false),
new BinaryValue(38,false),
new BinaryValue(39,false),
new BinaryValue(40,false),
new BinaryValue(41,false),
new BinaryValue(42,false),
new BinaryValue(43,false),
new BinaryValue(44,false),
new BinaryValue(45,false),
new BinaryValue(46,false),
new BinaryValue(47,false),
new BinaryValue(48,false),
new BinaryValue(49,false),
new BinaryValue(50,false),
new BinaryValue(51,false),
new BinaryValue(52,false),
new BinaryValue(53,false),
new BinaryValue(54,false),
new BinaryValue(55,false),
new BinaryValue(56,false),
new BinaryValue(57,false),
new BinaryValue(58,false),
new BinaryValue(59,false),
new BinaryValue(6,false),
new BinaryValue(61,false),
new BinaryValue(62,false),
new BinaryValue(63,false)
};
/// <summary>
/// 清空ListBinaryValue中的值
/// </summary>
public static void ClearBinaryValue()
{
foreach (var item in ListBinaryValue)
{
item.Value = false;
}
}
/// <summary>
/// 数值 转 intel格式CAN报文
/// Intel自己改装的数据 参考改为Motorola
/// </summary>
/// <param name="values">物理信号值</param>
/// <param name="startBit">信号起始bit</param>
/// <param name="bitLength">信号总长度</param>
/// <param name="factor">精度值</param>
/// <param name="offset">偏移值</param>
/// <returns>intel格式CAN报文</returns>
public static void ValueToMotorolaSignal(double values, int startBit, int bitLength, double factor, double offset)
{
//截取数据
var GetListValue = ListBinaryValue.Skip(startBit).Take(bitLength);
//获取设置的真实数据
UInt64 data = Convert.ToUInt64((values - offset) / factor);
//可能会溢出
var NewBinaryArry = ((int)data).ToBooleanArray().Reverse().ToArray();
//把新设置的数据覆盖到源数据中
for (int i = 0; i < NewBinaryArry.Length; i++)
{
GetListValue.Where(a => a.Index == i + startBit).FirstOrDefault().Value = NewBinaryArry[i];
}
}
///// <summary>
///// 数值 转 Motorola格式CAN报文
///// </summary>
///// <param name="MotorolaSignal">CAN报文</param>
///// <param name="values">物理信号值</param>
///// <param name="startBit">信号起始bit</param>
///// <param name="bitLength">信号总长度</param>
///// <param name="factor">精度值</param>
///// <param name="offset">偏移值</param>
///// <returns>Motorola格式CAN报文</returns>
//public static void ValueToMotorolaSignal(double values, int startBit, int bitLength, double factor, double offset)
//{
// // = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
// ulong data = Convert.ToUInt64((values - offset) / factor);
// int dataLength = bitLength / 8 + (bitLength / 4) % 2;
// int str_length = data.ToString().Length;
// int MotorolaSignal_pos = startBit / 8;
// data = str_length % 2 != 0 ? data << 4 : data;
// for (int Count = dataLength - 1; Count >= 0; Count--, MotorolaSignal_pos++)
// {
// ulong newBit = (data >> (8 * Count)) & 0xFF;
// ulong newBit2 = ((newBit << 4) & 0xF0) + ((newBit >> 4) & 0x0F);
// ulong Bit = (data > 0x0F & bitLength > 8) ? newBit2 : newBit;
// MotorolaSignal[MotorolaSignal_pos] = Convert.ToByte(Bit);
// }
//}
/// <summary>
/// 获取Can的报文信息
/// 8个字节数据
/// </summary>
/// <returns></returns>
public static byte[] GetCanMsg()
{
var ByteArr = new byte[8];
for (int i = 0; i < ByteArr.Length; i++)
{
ByteArr[i] = ConvertToByte(new BitArray(ListBinaryValue.Skip(i * 8).Take(8).Select(a => a.Value).ToArray()));
}
return ByteArr;
}
/// <summary>
/// 获取Can的报文信息
/// 8个字节数据
/// </summary>
/// <returns></returns>
public static byte[] GetMotorolaCanMsg()
{
return MotorolaSignal;
}
/// <summary>
/// BitArray 转为Byte数据
/// 这个只能转换8个bit位的
/// </summary>
/// <param name="bits"></param>
/// <returns></returns>
/// <exception cref="ArgumentException"></exception>
public static byte ConvertToByte(BitArray bits)
{
if (bits.Count > 8)
throw new ArgumentException("ConvertToByte can only work with a BitArray containing a maximum of 8 values");
byte result = 0;
for (byte i = 0; i < bits.Count; i++)
{
if (bits[i])
result |= (byte)(1 << i);
}
return result;
}
///// <summary>
///// 会填充满整个布尔类型的长度
///// </summary>
///// <param name="value"></param>
///// <returns></returns>
//public static bool[] GetBitArray(int value)
//{
// return new BitArray(new int[] { value}).Cast<bool>().ToArray();
//}
///// <summary>
///// 将BitArray转成int
///// </summary>
///// <param name="arr"></param>
///// <returns></returns>
//private int GetIntValue(BitArray arr)
//{
// int number = 0;
// for (int i = arr.Length - 1; i >= 0; i--)
// {
// number <<= 1;
// if (arr[i])
// {
// number++;
// }
// }
// return number;
//}
///// <summary>
///// 将int转成BitArray
///// </summary>
///// <param name="number"></param>
///// <returns></returns>
//private BitArray GetBitArray(int number)
//{
// BitArray tempArray = new BitArray(new int[] { number });
// BitArray returnArray = new BitArray(priorityCount);
// for (int i = 0; i < returnArray.Length; i++)
// {
// returnArray[i] = tempArray[i];
// }
// return returnArray;
//}
}
}