/// <summary> /// 读错误代码 /// </summary> /// <param name="canBusId"></param> /// <returns></returns> public bool ReadError(UInt32 canBusId, out string er) { er = string.Empty; try { if (!_devOpen) { er = "CanBus设备总线【" + canBusId.ToString() + "】未打开"; return(false); } VCI_ERR_INFO err_Info = new VCI_ERR_INFO(); if (VCI_ReadErrInfo((UInt32)_devType, _canBusId, canBusId, ref err_Info) != STATUS_OK) { er = "读取CanBus错误信息通信异常"; return(false); } if (!Enum.IsDefined(typeof(EErrCode), err_Info.ErrCode)) { er = "CanBus错误代码=" + err_Info.ErrCode.ToString(); return(false); } EErrCode errCode = (EErrCode)err_Info.ErrCode; if (errCode != EErrCode.ERR_NORMAL) { er = errCode.ToString(); return(false); } return(true); } catch (Exception ex) { er = ex.ToString(); return(false); } }
public static extern UInt32 VCI_ReadErrInfo(UInt32 DeviceType, UInt32 DeviceInd, UInt32 CANInd, ref VCI_ERR_INFO pErrInfo);
public static extern UInt32 VCI_ReadErrInfo(UInt32 DevType, UInt32 DevIndex, UInt32 CANIndex, ref VCI_ERR_INFO pErrInfo);
static extern uint VCI_ReadErrInfo(uint DeviceType, uint DeviceInd, uint CANInd, ref VCI_ERR_INFO pErrInfo);
public static extern uint FD_ReadErrInfo(uint DeviceType, uint DeviceInd, uint CANInd, ref VCI_ERR_INFO pErrInfo);
/// <summary> /// 接收数据 /// </summary> private void Recieve() { uint len = 0; VCI_ERR_INFO errinfo = new VCI_ERR_INFO(); VCI_CAN_OBJ[] frameinfos = new VCI_CAN_OBJ[1]; while (isOpen) { try { do { len = VCI_Receive(DEVICETYPE, DeviceInd, CNDInd, ref frameinfos[0], 1, 0); if (len <= 0) { VCI_ReadErrInfo(DEVICETYPE, DeviceInd, CNDInd, ref errinfo); } else { foreach (var frameinfo in frameinfos) { if (frameinfo.DataLen > 0 && frameinfo.Data != null) { if (frameinfo.Data.Length < frameinfo.DataLen) { WriteLog("数据格式不正确!"); } buffer.Add(0xFA);//加数据包头 //buffer.Add(0xe1); //buffer.Add(0x08); //buffer.Add(0); //buffer.Add(0); for (int i = 1; i < frameinfo.DataLen + 1; i++) { buffer.Add(frameinfo.Data[i - 1]); } DataRecievedArgs args = new DataRecievedArgs(); args.Buffer = buffer; //System.Diagnostics.Debug.WriteLine(frameinfo.Data[7]); //args.Buffer1 = new byte[frameinfo.DataLen]; ////args.Buffer[0] = 0xe1; ////args.Buffer[1] = 0x08; ////args.Buffer[2] = 0; ////args.Buffer[3] = 0; //for (int i = 0; i < frameinfo.DataLen; i++) //{ // args.Buffer1[i] = frameinfo.Data[i]; //} if (DataReceived != null) DataReceived(args); } } } } while (len <= 0); } catch { } //System.Diagnostics.Debug.WriteLine("end:" + DateTime.Now.Millisecond); //VCI_ClearBuffer(VCI_USBCAN1, DeviceInd, CNDInd); Thread.Sleep(1); } }
private static extern uint VCI_ReadErrInfo(uint DeviceType, uint DeviceInd, uint CANInd, ref VCI_ERR_INFO pErrInfo);
/// <summary> /// 接收CAN总线上的数据 /// </summary> private void DeviceReceive() { VCI_ERR_INFO pErrInfo = new VCI_ERR_INFO(); while (true) { SpinWait.SpinUntil(() => false, 1);//80 //返回接收缓冲区中尚未被读取的帧数 UInt32 num = VCI_GetReceiveNum(devType, devIndex, devChannel); if (num == 0) { continue; } //分配一次最多接收VCI_GetReceiveNum函数返回值的帧数的数据存储内存空间 IntPtr pt = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(VCI_CAN_OBJ)) * (int)num); //返回实际读到的帧数,如返回的为0xFFFFFFFF,则读取数据失败,有错误发生。 UInt32 len = VCI_Receive(devType, devIndex, devChannel, pt, num, -1); if (len == 0xFFFFFFFF) { VCI_ReadErrInfo(devType, devIndex, devChannel, ref pErrInfo); //释放分配的内存空间 Marshal.FreeHGlobal(pt); continue; } //获取CAN总线上的数据并触发事件 for (int i = 0; i < len; i++) { VCI_CAN_OBJ receData = (VCI_CAN_OBJ)Marshal.PtrToStructure((IntPtr)((UInt32)pt + i * Marshal.SizeOf(typeof(VCI_CAN_OBJ))), typeof(VCI_CAN_OBJ)); string _data = String.Empty; byte[] temp = receData.Data; for (int j = 0; j < receData.DataLen; j++) { _data += String.Format("{0:X2}", temp[j]) + " "; } //将接收的数据添加到table中 lock (DataBase) { DataRow _dr = DataBase.NewRow(); _dr["dttype"] = 1; _dr["id"] = "0x" + string.Format("{0:X}", receData.ID); _dr["direction"] = (string)Application.Current.Resources["teReceive"]; _dr["type"] = receData.ExternFlag == 0 ? (string)Application.Current.Resources["teStandardFrame"] : (string)Application.Current.Resources["teExtendedFrame"]; _dr["time"] = DateTime.Now.ToString("MM/dd HH:mm:ss:ffff");//((double)receData.TimeStamp / 10000).ToString().PadRight(9, '0'); _dr["data"] = _data.Trim(); _dr["signal"] = 0; DataBase.Rows.Add(_dr); if (DataBase.Rows.Count > 1000) { for (int n = 0; n < DataBase.Rows.Count - 1000; n++) { DataBase.Rows.RemoveAt(0); } } } } Marshal.FreeHGlobal(pt); } }
/// <summary> /// 初始化各路CAN /// 1 - no error /// 0x1111 - reset error /// 0x2222 - set baudrate error /// 0x3333 - initial error /// 0x4444 - set filter error /// 0x5555 - start CAN error /// 0x6666 - clear Buffer error /// </summary> /// <param name="canIndex"></param> internal UInt32 InitialCan(uint canIndex, uint baudrate) { UInt32 result = 1; int nTimeOut = 1500; //VCI_ResetCAN((uint)m_CanType, m_DeviceIndex, canIndex); //复位 ////清除buffer //VCI_ClearBuffer((uint)m_CanType, m_DeviceIndex, canIndex); VCI_INIT_CONFIG config = new VCI_INIT_CONFIG(); //设备为PCI-5010-U,PCI-5020-U,USBCAN-E-U,USBCAN-2E-U时,必须先使用SetRefrence设置波特率 if (m_CanType == ZlgCanType.PCI5010U || m_CanType == ZlgCanType.PCI5020U || m_CanType == ZlgCanType.USBCAN_E_U || m_CanType == ZlgCanType.USBCAN_2E_U) { //设置波特率 if (!SetCanBaudrate(canIndex, baudrate)) { VCI_CloseDevice((uint)m_CanType, m_DeviceIndex); result = 0x2222; return(result); } } else { //设备不为PCI-5010-U,PCI-5020-U,USBCAN-E-U,USBCAN-2E-U时,使用以下方式设置波特率 config.AccCode = 0x00000000; //验收码 config.AccMask = 0xFFFFFFFF; //屏蔽码 #region 波特率换算 switch (baudrate) { case 5: //5Kbps config.Timing0 = 0xBF; //定时器0 config.Timing1 = 0xFF; //定时器1 break; case 10: //10Kbps config.Timing0 = 0x31; //定时器0 config.Timing1 = 0x1C; //定时器1 break; case 20: //20Kbps config.Timing0 = 0x18; //定时器0 config.Timing1 = 0x1C; //定时器1 break; case 40: //40Kbps config.Timing0 = 0x87; //定时器0 config.Timing1 = 0xFF; //定时器1 break; case 50: //50Kbps config.Timing0 = 0x09; //定时器0 config.Timing1 = 0x1C; //定时器1 break; case 80: //80Kbps config.Timing0 = 0x83; //定时器0 config.Timing1 = 0xFF; //定时器1 break; case 100: //100Kbps config.Timing0 = 0x04; //定时器0 config.Timing1 = 0x1C; //定时器1 break; case 125: //125Kbps config.Timing0 = 0x03; //定时器0 config.Timing1 = 0x1C; //定时器1 break; case 200: //200Kbps config.Timing0 = 0x81; //定时器0 config.Timing1 = 0xFA; //定时器1 break; case 250: //250Kbps config.Timing0 = 0x01; //定时器0 config.Timing1 = 0x1C; //定时器1 break; case 400: //400Kbps config.Timing0 = 0x80; //定时器0 config.Timing1 = 0xFA; //定时器1 break; case 500: //500Kbps config.Timing0 = 0x00; //定时器0 config.Timing1 = 0x1C; //定时器1 break; case 666: //666Kbps config.Timing0 = 0x80; //定时器0 config.Timing1 = 0xB6; //定时器1 break; case 800: //800Kbps config.Timing0 = 0x00; //定时器0 config.Timing1 = 0x16; //定时器1 break; case 1000: //5Kbps config.Timing0 = 0x00; //定时器0 config.Timing1 = 0x14; //定时器1 break; default: //250Kbps config.Timing0 = 0x01; //定时器0 config.Timing1 = 0x1C; //定时器1 break; } #endregion config.Filter = 1; //0双滤波,1单滤波 } //初始化,对于上述4个设备,滤波及波特率要放到SetReference,而pInitConfig只有Mode需要设置,其他成员忽略 config.Mode = 0; //0正常,1只听 if (VCI_InitCAN((uint)m_CanType, m_DeviceIndex, canIndex, ref config) == 0) //多个通道需要多次调用,1成功,0失败 { VCI_ERR_INFO vciError = new VCI_ERR_INFO(); VCI_ReadErrInfo((uint)m_CanType, m_DeviceIndex, canIndex, ref vciError); VCI_CloseDevice((uint)m_CanType, m_DeviceIndex); result = 0x3333; return(result); } ////设置滤波 //if (!SetCanIndexFilter(canIndex)) //{ // DisConnectCan(); // result = 0x4444; // return result; //} //启动CAN if (VCI_StartCAN((uint)m_CanType, m_DeviceIndex, canIndex) == 0) //启动CAN,多路则多次调用,1成功,0失败 { VCI_CloseDevice((uint)m_CanType, m_DeviceIndex); result = 0x5555; return(result); } if (VCI_ClearBuffer((uint)m_CanType, m_DeviceIndex, canIndex) == 0)//1成功,0失败 { result = 0x6666; } //设置发送数据超时时间 //VCI_SetReference((uint)m_CanType, m_DeviceIndex, canIndex, 1, (byte*)&nTimeOut); return(result); }
/// <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; } }