using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Threading; using Peak.Can.Basic; namespace Can { using TPCANHandle = System.UInt16; //using TPCANBitrateFD = System.String; //using TPCANTimestampFD = System.UInt64; class PcanDevice : CanDevice { private TPCANHandle PcanHandle; Thread ReadThread; AutoResetEvent ReceiveEvent; bool IsConnect; //private TPCANBaudrate Baudrate; public PcanDevice() { IsConnect = false; this.PcanHandle = PCANBasic.PCAN_USBBUS1; } public override string CanInit() { TPCANStatus stsResult; string ret; /*stsResult = PCANBasic.Initialize( PcanHandle, TPCANBaudrate.PCAN_BAUD_500K, TPCANType.PCAN_TYPE_ISA, (UInt32)0x0100, (UInt16)0x03);*/ stsResult = PCANBasic.Initialize( PcanHandle, TPCANBaudrate.PCAN_BAUD_500K, TPCANType.PCAN_TYPE_ISA, (UInt32)0x0, (UInt16)0x0); if (stsResult != TPCANStatus.PCAN_ERROR_OK) { ret = GetFormatedError(stsResult); } else //连接成功 { IsConnect = true; ReadThread = new Thread(new ThreadStart(this.CANReadThreadFunc)); ReceiveEvent = new System.Threading.AutoResetEvent(false); ReadThread.IsBackground = true; //ReadThread.Start(); ret = "OK"; } return ret; } public override string CanDeInit() { base.CanDeInit(); TPCANStatus stsResult; stsResult = PCANBasic.Uninitialize(PcanHandle); if (TPCANStatus.PCAN_ERROR_OK == stsResult) { IsConnect = false; ReadThread.Abort(); return "OK"; } else { return GetFormatedError(stsResult); } } public override string CanReceiveEventEnable() { string ret; if (null == ReadThread) { ret = "线程为null"; } else { ReadThread.Start(); ret = "OK"; } return ret; } public override string CanReceiveEventDisable() { string ret; if (null == ReadThread) { ret = "线程为null"; } else { ReadThread.Abort(); ret = "OK"; } return ret; } public override string CanSetFilter(UInt32 stratId, UInt32 endId) { string ret; TPCANStatus stsResult; stsResult = PCANBasic.FilterMessages(PcanHandle, stratId, endId, TPCANMode.PCAN_MODE_STANDARD); //stsResult = PCANBasic.FilterMessages(PcanHandle, stratId, endId, TPCANMode.PCAN_MODE_EXTENDED); if (stsResult != TPCANStatus.PCAN_ERROR_OK) { ret = GetFormatedError(stsResult); } else { ret = "OK"; } return ret; } private string GetFormatedError(TPCANStatus error) { StringBuilder strTemp; // Creates a buffer big enough for a error-text // strTemp = new StringBuilder(256); // Gets the text using the GetErrorText API function // If the function success, the translated error is returned. If it fails, // a text describing the current error is returned. // if (PCANBasic.GetErrorText(error, 0, strTemp) != TPCANStatus.PCAN_ERROR_OK) return string.Format("An error occurred. Error-code's text ({0:X}) couldn't be retrieved", error); else return strTemp.ToString(); } public override void CanSendMessage(UInt32 id, byte[] data, int len) { TPCANMsg msg; msg.ID = id; msg.DATA = data; msg.LEN = MessagesLenToDlc(len); msg.MSGTYPE = TPCANMessageType.PCAN_MESSAGE_STANDARD; PCANBasic.Write(PcanHandle, ref msg); } public override bool CanReadMessage(ref UInt32 id, byte[] data, ref int len) { TPCANMsg msg; TPCANTimestamp timeStamp; TPCANStatus stsResult; stsResult = PCANBasic.Read(PcanHandle, out msg, out timeStamp); if (stsResult != TPCANStatus.PCAN_ERROR_QRCVEMPTY) { id = msg.ID; msg.DATA.CopyTo(data, 0); len = msg.LEN; return true; } else { return false; } } private void CANReadThreadFunc() { UInt32 id = 0; byte[] data = new byte[8]; int len = 0; UInt32 iBuffer; TPCANStatus stsResult; iBuffer = Convert.ToUInt32(ReceiveEvent.SafeWaitHandle.DangerousGetHandle().ToInt32()); // Sets the handle of the Receive-Event. // stsResult = PCANBasic.SetValue(PcanHandle, TPCANParameter.PCAN_RECEIVE_EVENT, ref iBuffer, sizeof(UInt32)); if (stsResult != TPCANStatus.PCAN_ERROR_OK) { return; } // While this mode is selected while (IsConnect) { if (ReceiveEvent.WaitOne(50)) { while (true == CanReadMessage(ref id, data, ref len)) { CanReadEventInvoke(id, data, len); } } } } public override string CanFdInit() { string ret; TPCANStatus stsResult; stsResult = PCANBasic.InitializeFD(PcanHandle, "f_clock_mhz=24, nom_brp=8, nom_tseg1=4, nom_tseg2=1, nom_sjw=1, data_brp=2, data_tseg1=4, data_tseg2=1, data_sjw=1"); if (stsResult != TPCANStatus.PCAN_ERROR_OK) { ret = GetFormatedError(stsResult); } else //连接成功 { IsConnect = true; ReadThread = new Thread(new ThreadStart(this.CanFdReadThreadFunc)); ReceiveEvent = new System.Threading.AutoResetEvent(false); ReadThread.IsBackground = true; ret = "OK"; } return ret; } //CANFD初始化 public override string CanFdDeInit() { return this.CanDeInit(); } public override string CanFdReceiveEventEnable() { return this.CanReceiveEventEnable(); } public override string CanFdReceiveEventDisable() { return this.CanReceiveEventDisable(); } //CANFD设置ID过滤器 public override string CanFdSetFilter(UInt32 startId, UInt32 endId) { return this.CanSetFilter(startId, endId); } //CANFD发送一帧报文 public override void CanFdSendMessage(UInt32 id, byte[] data, int len) { TPCANMsgFD msg = new TPCANMsgFD(); msg.ID = id; msg.DLC = MessagesLenToDlc(len); msg.DATA = new byte[64]; Array.Copy(data, msg.DATA, len); //msg.MSGTYPE = (chbExtended.Checked) ? TPCANMessageType.PCAN_MESSAGE_EXTENDED : TPCANMessageType.PCAN_MESSAGE_STANDARD; // msg.MSGTYPE |= (chbFD.Checked) ? TPCANMessageType.PCAN_MESSAGE_FD : TPCANMessageType.PCAN_MESSAGE_STANDARD; //msg.MSGTYPE |= (chbBRS.Checked) ? TPCANMessageType.PCAN_MESSAGE_BRS : TPCANMessageType.PCAN_MESSAGE_STANDARD; msg.MSGTYPE = TPCANMessageType.PCAN_MESSAGE_STANDARD; msg.MSGTYPE |= TPCANMessageType.PCAN_MESSAGE_FD; msg.MSGTYPE |= TPCANMessageType.PCAN_MESSAGE_BRS; //msg.MSGTYPE |= TPCANMessageType.PCAN_MESSAGE_RTR; PCANBasic.WriteFD(PcanHandle, ref msg); } //CANFD从FIFO读取一帧报文 public override bool CanFdReadMessage(ref UInt32 id, byte[] data, ref int len) { TPCANMsgFD msg; UInt64 timeStamp; TPCANStatus stsResult; // We execute the "Read" function of the PCANBasic // stsResult = PCANBasic.ReadFD(PcanHandle, out msg, out timeStamp); if (stsResult != TPCANStatus.PCAN_ERROR_QRCVEMPTY) { id = msg.ID; msg.DATA.CopyTo(data, 0); len = MessagesDlcToLen(msg.DLC); return true; } else { return false; } } private void CanFdReadThreadFunc() { UInt32 id = 0; byte[] data = new byte[64]; int len = 0; UInt32 iBuffer; TPCANStatus stsResult; iBuffer = Convert.ToUInt32(ReceiveEvent.SafeWaitHandle.DangerousGetHandle().ToInt32()); // Sets the handle of the Receive-Event. // stsResult = PCANBasic.SetValue(PcanHandle, TPCANParameter.PCAN_RECEIVE_EVENT, ref iBuffer, sizeof(UInt32)); if (stsResult != TPCANStatus.PCAN_ERROR_OK) { return; } // While this mode is selected while (IsConnect) { if (ReceiveEvent.WaitOne(50)) { while (true == CanFdReadMessage(ref id, data, ref len)) { CanReadEventInvoke(id, data, len); } } } } } }