/// <summary> /// 启动某一路CAN通道 /// </summary> /// <param name="canIndex"></param> private bool StartDevice() { if (ZLGInfo.DevType != (uint)ZLGType.VCI_USBCANFD_100U) { UInt32 res = VCI_StartCAN(ZLGInfo.DevType, zlgInfo.DevIndex, zlgInfo.DevChannel); if ((Status)res == Status.ERROR) { string strErr = "设备类型号:" + ZLGInfo.DevType.ToString() + " 设备索引号: " + zlgInfo.DevIndex.ToString() + " CAN通道号: " + zlgInfo.DevChannel.ToString(); return(false); } else { return(true); } } else { UInt32 res = ZLGCAN_API.ZCAN_StartCAN(channel_handle); if ((Status)res == Status.ERROR) { string strErr = "设备类型号:" + ZLGInfo.DevType.ToString() + " 设备索引号: " + zlgInfo.DevIndex.ToString() + " CAN通道号: " + zlgInfo.DevChannel.ToString(); return(false); } else { return(true); } } }
/// <summary> /// 打开ZLG接口卡设备,此方法对于一个设备只能被调用一次 /// </summary> private bool OpenDevice() { try { if (zlgInfo.IsRecFrame) { return(true); } if (ZLGInfo.DevType != (uint)ZLGType.VCI_USBCANFD_100U) { uint ret = VCI_OpenDevice(ZLGInfo.DevType, zlgInfo.DevIndex, 0); if ((Status)ret == Status.ERROR) { zlgInfo.IsRecFrame = false; string strErr = "设备类型号:" + ZLGInfo.DevType.ToString() + " 设备索引号: " + zlgInfo.DevIndex.ToString(); return(false); } else { zlgInfo.IsRecFrame = true; return(true); } } else { device_handle = ZLGCAN_API.ZCAN_OpenDevice(ZLGInfo.DevType, zlgInfo.DevIndex, 0); if ((int)device_handle == 0) { zlgInfo.IsRecFrame = false; string strErr = "设备类型号:" + ZLGInfo.DevType.ToString() + " 设备索引号: " + zlgInfo.DevIndex.ToString(); return(false); } else { zlgInfo.IsRecFrame = true; return(true); } } } catch (Exception ex) { } return(false); }
/// <summary> /// 关闭设备 /// </summary> private bool CloseDevice() { if (zlgInfo.IsRecFrame) { if (ZLGInfo.DevType == (uint)ZLGType.VCI_USBCANFD_100U) { UInt32 res = ZLGCAN_API.ZCAN_CloseDevice(device_handle); if ((Status)res == Status.SUCCESS) { zlgInfo.IsRecFrame = false; } else { zlgInfo.IsRecFrame = true; } } else if (ZLGInfo.DevType == (uint)ZLGType.PCAN) { bool ret = PCANInterface.PCANInstance.ConnectRelease(); if (ret == true) { zlgInfo.IsRecFrame = false; } else { zlgInfo.IsRecFrame = true; } } else { UInt32 res = VCI_CloseDevice(ZLGInfo.DevType, zlgInfo.DevIndex); if ((Status)res == Status.SUCCESS) { zlgInfo.IsRecFrame = false; } else { zlgInfo.IsRecFrame = true; } } return(zlgInfo.IsRecFrame); } else { return(true); } }
/// <summary> /// 发送单帧信息 /// </summary> /// <param name="ID"></param> /// <param name="canIndex"></param> /// <param name="data"></param> /// <param name="dataLength"></param> public void SingleTransmit(VCI_CAN_OBJ obj) { try { if (ZLGInfo.DevType == (uint)ZLGType.VCI_USBCANFD_100U) { ZLGCAN_API.ZCAN_Transmit_Data can_data = new ZLGCAN_API.ZCAN_Transmit_Data(); obj.ExternFlag = 1; can_data.frame.can_id = MakeCanId(obj.ID, obj.ExternFlag, 0, 0); can_data.frame.data = new byte[8]; Buffer.BlockCopy(obj.Data, 0, can_data.frame.data, 0, obj.DataLen); can_data.frame.can_dlc = (byte)obj.Data.Length; can_data.transmit_type = obj.SendType; IntPtr ptr = Marshal.AllocHGlobal(Marshal.SizeOf(can_data)); Marshal.StructureToPtr(can_data, ptr, true); BoqiangH5Repository.CSVFileHelper.WriteLogs("log", "发送", CSVFileHelper.ToHexStrFromByte(can_data.frame.data, false), false); uint res = ZLGCAN_API.ZCAN_Transmit(channel_handle, ptr, 1); Marshal.FreeHGlobal(ptr); if (res == 0) { _dispatcher.BeginInvoke(new Action(delegate() { })); AbortThread(); return; } else { OnRaiseZLGCommunicateEvent(this, new CANEvent() { eventType = CANEventType.SendEvent, //ID = can_data.frame.can_id, DataLen = can_data.frame.data[2], listData = new List <byte>(can_data.frame.data) }); } } else if (ZLGInfo.DevType == (uint)ZLGType.PCAN) { bool isRemote = false; if (obj.RemoteFlag == 0x00) { isRemote = false; } else { isRemote = true; } BoqiangH5Repository.CSVFileHelper.WriteLogs("log", "发送", CSVFileHelper.ToHexStrFromByte(obj.Data, false), false); PCANInterface.PCANInstance.PCAN_WriteData(obj.ID, obj.DataLen, isRemote, obj.Data); } else { //在非托管内存中分配一个VCI_CAN_OBJ结构体大小的内存空间 IntPtr pt = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(VCI_CAN_OBJ)) * 1); VCI_CAN_OBJ pSend = (VCI_CAN_OBJ)Marshal.PtrToStructure((IntPtr)((UInt32)pt), typeof(VCI_CAN_OBJ)); //IsSendFrame = true; pSend.ID = obj.ID; pSend.SendType = obj.SendType; pSend.RemoteFlag = obj.RemoteFlag; pSend.ExternFlag = obj.ExternFlag; pSend.DataLen = obj.DataLen; string strSendDdata = String.Empty; byte[] temp = obj.Data; for (int j = 0; j < pSend.DataLen; j++) { strSendDdata += String.Format("{0:X2}", temp[j]) + " "; } for (int i = 0; i < obj.DataLen; i++) { pSend.Data[i] = obj.Data[i]; } if (pSend.Data[0] == 0x30 && pSend.Data[1] == 0xff && pSend.Data[3] == 0x00) { } BoqiangH5Repository.CSVFileHelper.WriteLogs("log", "发送", CSVFileHelper.ToHexStrFromByte(pSend.Data, false), false); //返回实际发送成功的帧数 UInt32 res = VCI_Transmit(ZLGInfo.DevType, zlgInfo.DevIndex, zlgInfo.DevChannel, ref pSend, 1); if (res == 0) { _dispatcher.BeginInvoke(new Action(delegate() { })); AbortThread(); return; } else { OnRaiseZLGCommunicateEvent(this, new CANEvent() { eventType = CANEventType.SendEvent, //ID = pSend.ID, DataLen = pSend.DataLen, listData = new List <byte>(pSend.Data) }); } Marshal.FreeHGlobal(pt); } } catch (Exception ex) { } }
/// <summary> /// 接收CAN总线上的数据 /// </summary> private void ReceiveDataFromCAN() { try { if (ZLGInfo.DevType == (uint)ZLGType.VCI_USBCANFD_100U) { ZLGCAN_API.ZCAN_Receive_Data[] can_data = new ZLGCAN_API.ZCAN_Receive_Data[100]; //ZLGCAN_API.ZCAN_Receive_Data[] can_data = new ZLGCAN_API.ZCAN_Receive_Data[500]; uint len; while (true) { lock (locker) { len = ZLGCAN_API.ZCAN_GetReceiveNum(channel_handle, TYPE_CAN); int nRecvIndex = 0; if (len > 0) { int size = Marshal.SizeOf(typeof(ZLGCAN_API.ZCAN_Receive_Data)); IntPtr ptr = Marshal.AllocHGlobal((int)len * size); len = ZLGCAN_API.ZCAN_Receive(channel_handle, ptr, len, 50); byte[] byRecvData = new byte[len * 8]; string canIDStr = string.Empty; for (int i = 0; i < len; ++i) { can_data[i] = (ZLGCAN_API.ZCAN_Receive_Data)Marshal.PtrToStructure( (IntPtr)((UInt32)ptr + i * size), typeof(ZLGCAN_API.ZCAN_Receive_Data)); Buffer.BlockCopy(can_data[i].frame.data, 0, byRecvData, nRecvIndex, 8); nRecvIndex += 8; canIDStr += can_data[i].frame.can_id.ToString("X"); canIDStr += ","; } Marshal.FreeHGlobal(ptr); if (RaiseZLGRecvDataEvent != null) { OnRaiseZLGRecvDataEvent(this, new CANEvent() { eventType = CANEventType.ReceEvent, DataLen = byRecvData[1], listData = new List <byte>(byRecvData), ID = canIDStr.TrimEnd(',') });; //Marshal.FreeHGlobal(ptr); } } } Thread.Sleep(100); } } else if (ZLGInfo.DevType == (uint)ZLGType.PCAN) { PCANInterface.PCANInstance.ReadMessages(); } else { VCI_ERR_INFO pErrInfo = new VCI_ERR_INFO(); while (true) { //为了不占用CPU SpinWait.SpinUntil(() => false, 150); //返回接收缓冲区中尚未被读取的帧数 UInt32 num = VCI_GetReceiveNum(ZLGInfo.DevType, zlgInfo.DevIndex, zlgInfo.DevChannel); if (num == 0) { continue; } zlgInfo.IsSendFrame = false; //分配一次最多接收VCI_GetReceiveNum函数返回值的帧数的数据存储内存空间 IntPtr pt = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(VCI_CAN_OBJ)) * (int)num); //返回实际读到的帧数,如返回的为0xFFFFFFFF,则读取数据失败,有错误发生。 UInt32 len = VCI_Receive(ZLGInfo.DevType, zlgInfo.DevIndex, zlgInfo.DevChannel, pt, num, -1); if (len == 0xFFFFFFFF) { VCI_ReadErrInfo(ZLGInfo.DevType, zlgInfo.DevIndex, zlgInfo.DevChannel, ref pErrInfo); //释放分配的内存空间 Marshal.FreeHGlobal(pt); continue; } else { } int nRecvIndex = 0; byte[] byRecvData = new byte[len * 8]; string canIDStr = String.Empty; //获取CAN总线上的数据并触发事件 for (int i = 0; i < len; i++) { VCI_CAN_OBJ recvData = (VCI_CAN_OBJ)Marshal.PtrToStructure((IntPtr)((UInt32)pt + i * Marshal.SizeOf(typeof(VCI_CAN_OBJ))), typeof(VCI_CAN_OBJ)); Buffer.BlockCopy(recvData.Data, 0, byRecvData, nRecvIndex, 8); nRecvIndex += 8; canIDStr += recvData.ID.ToString("X"); canIDStr += ","; } if (RaiseZLGRecvDataEvent != null) { OnRaiseZLGRecvDataEvent(this, new CANEvent() { eventType = CANEventType.ReceEvent, DataLen = byRecvData[2], listData = new List <byte>(byRecvData), ID = canIDStr.TrimEnd(',') }); } VCI_ClearBuffer(ZLGInfo.DevType, zlgInfo.DevIndex, zlgInfo.DevChannel); Marshal.FreeHGlobal(pt); } } } catch (Exception ex) { string str = ex.Message; } }
/// <summary> /// 初始化某一路CAN通道 /// </summary> private bool InitDevice() { if (ZLGInfo.DevType != (uint)ZLGType.VCI_USBCANFD_100U) { VCI_INIT_CONFIG config = new VCI_INIT_CONFIG(); UInt32 pData = 0x060007; if (ZLGInfo.DevType > 18 && ZLGInfo.DevType < 23) { config.Mode = 0; SetBaudRate(ZLGInfo.Baudrate, ref pData); VCI_SetReference(ZLGInfo.DevType, zlgInfo.DevIndex, 0, 0, ref pData); } else { config.AccCode = zlgInfo.AccCode; config.AccMask = zlgInfo.AccMask; config.Filter = 1; config.Mode = zlgInfo.Mode; config.Timing0 = ZLGInfo.Timing0; config.Timing1 = ZLGInfo.Timing1; } UInt32 res = VCI_InitCAN(ZLGInfo.DevType, zlgInfo.DevIndex, zlgInfo.DevChannel, ref config); if ((Status)res == Status.ERROR) { string strErr = "设备类型号:" + ZLGInfo.DevType.ToString() + " 设备索引号: " + zlgInfo.DevIndex.ToString() + " CAN通道号: " + zlgInfo.DevChannel.ToString(); return(false); } else { return(true); } } else { IntPtr ptr = ZLGCAN_API.GetIProperty(device_handle); if (0 == (int)ptr) { return(false);//设置指定路径属性失败 } ZLGCAN_API.IProperty _property = (ZLGCAN_API.IProperty)Marshal.PtrToStructure((IntPtr)((UInt32)ptr), typeof(ZLGCAN_API.IProperty)); if (_property.SetValue(zlgInfo.DevChannel.ToString() + "/canfd_standard", zlgInfo.CANFD.ToString()) != 1) { return(false);//设置CANFD标准失败 } ZLGCAN_API.ZCAN_CHANNEL_INIT_CONFIG config = new ZLGCAN_API.ZCAN_CHANNEL_INIT_CONFIG(); config.canfd.mode = zlgInfo.Mode; config.can_type = TYPE_CANFD;//设置CAN类型为CAN uint pData = 0x00018B2E; SetArbitrationBaudRate(zlgInfo.ArbitrationBaudrate, ref pData); config.canfd.abit_timing = pData; uint _pData = 0x00010207; SetDataBaudRate(zlgInfo.DataBaudRate, ref _pData); config.canfd.dbit_timing = _pData; IntPtr pConfig = Marshal.AllocHGlobal(Marshal.SizeOf(config)); Marshal.StructureToPtr(config, pConfig, true); //int size = sizeof(ZCAN_CHANNEL_INIT_CONFIG); //IntPtr ptr = System.Runtime.InteropServices.Marshal.AllocCoTaskMem(size); //System.Runtime.InteropServices.Marshal.StructureToPtr(config_, ptr, true); channel_handle = ZLGCAN_API.ZCAN_InitCAN(device_handle, (uint)zlgInfo.DevChannel, pConfig); Marshal.FreeHGlobal(pConfig); //Marshal.FreeHGlobal(ptr); if (0 == (int)channel_handle) { string strErr = "设备类型号:" + ZLGInfo.DevType.ToString() + " 设备索引号: " + zlgInfo.DevIndex.ToString() + " CAN通道号: " + zlgInfo.DevChannel.ToString(); return(false);//初始化CAN失败 } if (zlgInfo.TerminaiResistanceEnabled == 1) { if (_property.SetValue(zlgInfo.DevChannel.ToString() + "/initenal_resistance", zlgInfo.TerminaiResistanceEnabled.ToString()) != 1) { return(false);//设置使能终端电阻失败 } } return(true); } }