Files
YuPu-OrpaonEMS/OrpaonEMS.App/CANDrive/CAN.cs
2025-02-28 22:23:13 +08:00

956 lines
37 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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
}