using System; using System.Collections.Generic; using System.IO.Ports; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; using Core.ONH.Collection.Send; namespace Core.ONH.Collection.comm { public delegate void ReceiveDataHandler(object sender, ONHData data, string Message); public class SerialPortEntity : SerialPort { private CancellationTokenSource ct = new CancellationTokenSource(); private Task task; public string StrBaudRate { get { return BaudRate.ToString(); } set { var iBaudRate = 0; if (!int.TryParse(value, out iBaudRate)) iBaudRate = 2400; BaudRate = iBaudRate; } } public string StrDataBits { get { return DataBits.ToString(); } set { var iDataBits = 0; if (!int.TryParse(value, out iDataBits)) iDataBits = 8; DataBits = iDataBits; } } public string StrParity { get { switch (Parity) { case Parity.None: return "NONE"; case Parity.Even: return "EVEN"; case Parity.Mark: return "MARK"; case Parity.Odd: return "ODD"; case Parity.Space: return "SPACE"; default: return "EVEN"; ; } } set { switch (value) { case "EVEN": Parity = Parity.Even; break; case "MARK": Parity = Parity.Mark; break; case "NONE": Parity = Parity.None; break; case "ODD": Parity = Parity.Odd; break; case "SPACE": Parity = Parity.Space; break; default: Parity = Parity.Even; break; } } } public string StrStopBits { get { switch (StopBits) { case StopBits.None: return "NONE"; case StopBits.One: return "ONE"; case StopBits.OnePointFive: return "ONEPOINTFIVE"; case StopBits.Two: return "TWO"; default: return "ONE"; ; } } set { switch (value) { case "NONE": StopBits = StopBits.None; break; case "ONE": StopBits = StopBits.One; break; case "ONEPOINTFIVE": StopBits = StopBits.OnePointFive; break; case "TWO": StopBits = StopBits.Two; break; default: StopBits = StopBits.One; break; } } } public string DeviceName { get; set; } public event ReceiveDataHandler ReceiveData; /// /// 触发试样编号值改变事件 /// /// protected virtual void OnReceiveData(ONHData data, string message) { var handler = ReceiveData; if (handler != null) new Task(() => { handler(this, data, DeviceName + " " + message); }).Start(); // handler(this, data, DeviceName + " " + message); } public void SendDataWithReplay(string data) { var byteArray = Encoding.Default.GetBytes(data); //组成特定帧 var fullyByte = CoreProtocol.Framing(byteArray); // 组成符合自定义协议的数据帧 Open(); Thread.Sleep(200); try { Write(fullyByte, 0, fullyByte.Length); var ts1 = new TimeSpan(DateTime.Now.Ticks); var ReadData = new List(); var OverTime = false; var RightReplay = false; List Data = null; while (!OverTime && !RightReplay) if (BytesToRead > 0) { var Datas = new byte[BytesToRead]; Read(Datas, 0, Datas.Length); ReadData = ReadData.Concat(Datas).ToList(); if (AnalaysData(ReadData, out Data) == DeframeType.RightFrame) RightReplay = true; } else { var ts2 = new TimeSpan(DateTime.Now.Ticks); var ts3 = ts1.Subtract(ts2).Duration(); if (ts3.TotalSeconds > 10) OverTime = true; } if (OverTime) throw new Exception("发送超时"); if (Data!=null && Data.Count>0 && Data[0] == 0x00) { } else { throw new Exception("通讯异常, 请重新发送"); } } finally { if (IsOpen) Close(); } } public void Start() { try { Open(); OnReceiveData(null, string.Format("打开串口[{0}--{1} {2} {3} {4}]成功!", PortName, StrBaudRate, StrParity, StrDataBits, StrStopBits)); ct = new CancellationTokenSource(); task = new Task(ReceiveTask, ct.Token); task.Start(); OnReceiveData(null, "开始监听数据"); } catch (Exception ex) { OnReceiveData(null, ex.Message); } } public void ReceiveTask() { var ReceiveData = new List(); while (!ct.IsCancellationRequested) try { if (!IsOpen) continue; if (BytesToRead > 0) { //等待100毫秒 等足够帧过来 Thread.Sleep(100); var Datas = new byte[BytesToRead]; Read(Datas, 0, Datas.Length); ReceiveData = ReceiveData.Concat(Datas).ToList(); List Data; DeframeType Result = AnalaysData(ReceiveData, out Data); if(Result!= DeframeType.LengthLess) ReceiveData.Clear(); if (Result == DeframeType.RightFrame) { //回应0x00 收到正确数据 var replay = CoreProtocol.Framing(new byte[] { 0x00 }); Write(replay, 0, replay.Length); ONHData ONHData = new ONHData(); String StrData = Encoding.Default.GetString(Data.ToArray()); ONHDataHelper.AnalysisString(StrData, out ONHData); ONHData.DeviceName = DeviceName; OnReceiveData(ONHData, "成功接受数据:" + StrData); } if (Result == DeframeType.WrongFrame) { //回应0x01 收到数据异常 var replay1 = CoreProtocol.Framing(new byte[] { 0x01 }); Write(replay1, 0, replay1.Length); OnReceiveData(null, "数据丢失,请重新发送 "); } } } catch (Exception) { } OnReceiveData(null, "停止监听数据"); } private DeframeType AnalaysData(List ReceiveData, out List Data) { ReceiveData = ReceiveData.SkipWhile(p => p != 0x68).ToList(); DeframeType Result = CoreProtocol.Deframe(ReceiveData, out Data); if (Result == DeframeType.WrongHead) { //帧头 不正确 去掉第一字节 递归 ReceiveData.RemoveAt(0); return AnalaysData(ReceiveData, out Data); } return Result; } public void Stop() { try { ct.Cancel(); task.Wait(); } catch (Exception ex) { // ignored } Thread.Sleep(100); if (IsOpen) { Close(); OnReceiveData(null, string.Format("关闭串口[{0}]成功!", PortName)); } } } }