123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345 |
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Threading;
- using System.IO.Ports;
- using System.Windows.Forms;
- namespace Dispatch
- {
- internal class SerialPortEx
- {
- public SerialPortEx()
- {
- serialPort1 = new SerialPort();
- serialPort1.PortName = "COM1";
- serialPort1.BaudRate = 9600;
- serialPort1.StopBits = StopBits.One;
- serialPort1.Parity = Parity.None;
- serialPort1.DataBits = 8;
- serialPort1.ReceivedBytesThreshold = 1;
- serialPort1.ReadTimeout = 1000;
- serialPort1.DataReceived += new SerialDataReceivedEventHandler(serialPort1_DataReceived);
- thread = new Thread(ThreadHandler);
- }
- /************************************************************************/
- /*添加了读写串口事件*/
- /************************************************************************/
- public event EventHandler ReadingData;
- public event EventHandler WritingData;
- void OnReadingData(EventArgs e)
- {
- if (ReadingData != null)
- {
- ReadingData(this, e);
- }
- }
- void OnWritingData(EventArgs e)
- {
- if (WritingData != null)
- {
- WritingData(this, e);
- }
- }
- public void Write(string text)
- {
- try
- {
- serialPort1.Write(text);
- OnWritingData(null);
- }
- catch (System.Exception ex)
- {
- throw new Exception("写串口:" + ex.Message);
- }
- }
- public void Write(byte[] buffer, int offset, int count)
- {
- try
- {
- serialPort1.Write(buffer, offset, count);
- OnWritingData(null);
- }
- catch (System.Exception ex)
- {
- throw new Exception("写串口:" + ex.Message);
- }
- }
- public void Write(char[] buffer, int offset, int count)
- {
- try
- {
- serialPort1.Write(buffer, offset, count);
- OnWritingData(null);
- }
- catch (System.Exception ex)
- {
- throw new Exception("写串口:" + ex.Message);
- }
- }
- public void Open()
- {
- try
- {
- if (!serialPort1.IsOpen)
- {
- serialPort1.Open();
- if (thread != null)
- {
- if (thread.ThreadState == ThreadState.Suspended)
- thread.Resume();
- else if (thread.ThreadState == ThreadState.Stopped || thread.ThreadState == ThreadState.Unstarted)
- {
- thread.Start();
- }
- }
- else
- {
- thread = new Thread(ThreadHandler);
- thread.Start();
- }
- }
- }
- catch (System.Exception ex)
- {
- throw new Exception("打开串口:" + ex.Message);
- }
- }
- public void Close()
- {
- try
- {
- serialPort1.Close();
- if (thread != null && thread.ThreadState == ThreadState.Running)
- {
- if (done.WaitOne(500))
- {
- thread.Suspend();
- }
- thread.Suspend();
- }
- receiveBuffer.Clear();
- }
- catch (System.Exception ex)
- {
- throw new Exception("关闭串口:" + ex.Message);
- }
- }
- public SerialPort serialPort1;
- public List<byte> receiveBuffer = new List<byte>(2046);
- private object portLock = new object();
- public delegate void MatchedParityHandler(object sender, PortDataEventArgs e);
- public event MatchedParityHandler MatchedParity;
- private Thread thread;
- private void OnMatchedParity(object sender, PortDataEventArgs e)
- {
- if (MatchedParity != null)
- {
- MatchedParity(sender, e);
- }
- }
- private class MyData
- {
- public object sender;
- public PortDataEventArgs e;
- }
- public void OnMatchParity(object o)
- {
- MyData data = o as MyData;
- Console.ForegroundColor = ConsoleColor.Yellow;
- //Console.WriteLine("所在线程ID:" + Thread.CurrentThread.ManagedThreadId.ToString() + "类型:" + data.e.type + " " + Byte2HexString(data.e.data));
- Console.ResetColor();
- OnMatchedParity(data.sender, data.e);
- Thread.Sleep(500);//加延时是为了避免解析后有过长的操作占用系统资源
- }
- public static string Byte2HexString(byte[] buffer)
- {
- StringBuilder builder = new StringBuilder(buffer.Length * 3);
- foreach (byte data in buffer)
- {
- builder.Append(Convert.ToString(data, 16).PadLeft(2, '0').PadRight(3, ' '));
- }
- return builder.ToString().ToUpper();
- }
- private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
- {
- byte[] buffer = new byte[serialPort1.BytesToRead];
- serialPort1.Read(buffer, 0, buffer.Length);
- OnReadingData(null);
- Console.ForegroundColor = ConsoleColor.Green;
- //Console.WriteLine("接收数据:" + Byte2HexString(buffer));
- Console.ResetColor();
- lock (portLock)
- {
- receiveBuffer.AddRange(buffer);
- }
- //Console.WriteLine("缓冲区数据:" + Byte2HexString(receiveBuffer.ToArray()));
- }
- public static byte XOR_Check(byte[] buffer, int count, int index = 0)
- {
- byte b = 0;
- for (int i = 0; i < count; i++)
- {
- b ^= buffer[index + i];
- }
- return b;
- }
- int endCodeIndex = 8;//尾码索引号
- int endCodeCount = 0;//找到尾码的次数
- private byte[] DataHander(out int type)
- {
- type = -1;
- int i, j;
- if (receiveBuffer.Count >= 9)
- {
- i = receiveBuffer.FindIndex(0, b => b == 0x10);
- if (i != -1)
- {
- //Console.WriteLine("找到0x10,在位置:{0}", i);
- j = receiveBuffer.FindIndex(endCodeIndex, b => b == 0x03);
-
- if (j != -1 && j > i)
- {
- endCodeIndex = j;
- endCodeIndex++;//索引自加
- endCodeCount++;
- //Console.WriteLine(string.Format("找到0x03,在位置:{0},endcodeIndex={1}", j, endCodeIndex));
- if ((j - i + 1) == 10)
- {
- byte[] tempBuffer = new byte[10];
- receiveBuffer.CopyTo(i, tempBuffer, 0, 10);
- if (XOR_Check(tempBuffer, 8) == tempBuffer[8])
- {
- type = 2;
- lock (portLock)
- {
- receiveBuffer.RemoveRange(0, j + 1);
- endCodeIndex = 0;//
- endCodeCount = 0;
- }
- return tempBuffer;
- }
- else
- {
- //Console.WriteLine(string.Format("没通过校验:{0}", Byte2HexString(tempBuffer)));
- lock (portLock)
- {
- receiveBuffer.RemoveRange(0, j + 1);
- }
- }
- }
- else if (receiveBuffer.Count - i > 30)//如果数据长度超过30但校验没通过
- {
- endCodeIndex = 0;//
- endCodeCount = 0;
- //Console.WriteLine(string.Format("0x10与0x03间数据过长:", Byte2HexString(receiveBuffer.ToArray())));
- lock (portLock)
- {
- receiveBuffer.RemoveRange(0, j + 1);
- }
- }
- else if (j - i + 1 < 9)
- {
- //Console.WriteLine(string.Format("找到0x03,但0x03与0x10间数据过短,0x03位置:{0},0x10位置:{1}", j, i));
- }
- else
- {
- //Console.WriteLine(string.Format("在找到0x03中没考虑的情况,0x03位置:{0},0x10位置:{1}", j, i));
- }
- }
- else if (j != -1 && j < i)
- {
- endCodeIndex = 0;//
- endCodeCount = 0;
- //Console.WriteLine(string.Format("0x03位置:{0}小于0x10位置:{1},数据:{2}", j, i, Byte2HexString(receiveBuffer.ToArray())));
- lock (portLock)
- {
- //receiveBuffer.RemoveAt(i);
- receiveBuffer.RemoveRange(0, j + 1);
- }
- }
- else if (/*j == -1 && */receiveBuffer.Count - i > 1000)
- {
- endCodeIndex = 0;//
- endCodeCount = 0;
- //Console.WriteLine(string.Format("数据量超过1000:", Byte2HexString(receiveBuffer.ToArray())));
- lock (portLock)
- {
- //receiveBuffer.RemoveAt(i);
- receiveBuffer.RemoveRange(0, receiveBuffer.Count);
- }
- }
- else
- {
- //Console.WriteLine(string.Format("没考虑到情况,可能找到0x03,0x10位置:{0},0x03位置:{1},数据:{2}", Byte2HexString(receiveBuffer.ToArray())));
- }
- }
- else
- {
- //Console.WriteLine(string.Format("0x10没找到:", Byte2HexString(receiveBuffer.ToArray())));
- lock (portLock)
- {
- receiveBuffer.RemoveRange(0, receiveBuffer.Count);
- }
- }
- }
- return new byte[1] { 0 };
- }
- AutoResetEvent done = new AutoResetEvent(true);//在处理数据的时候不允许被打断(只有在线程正常挂起时有效)
- public void ThreadHandler()
- {
- while (true)
- {
- if (serialPort1.IsOpen)
- {
- //Console.WriteLine("分析线程运行中...");
- if (receiveBuffer.Count > 0)
- {
- done.Reset();
- byte[] buffer;
- int type;
- buffer = DataHander(out type);
- PortDataEventArgs e = new PortDataEventArgs();
- e.type = type;
- e.data = buffer;
- if (type != -1)
- {
- MyData data = new MyData();
- data.sender = this;
- data.e = e;
- Thread t = new Thread(OnMatchParity);
- t.Start(data);
- //OnMatchedParity(this, e);
- Console.ForegroundColor = ConsoleColor.Blue;
- //Console.WriteLine("类型:" + type.ToString() + " " + Byte2HexString(buffer));
- Console.ResetColor();
- }
- }
- }
- Thread.Sleep(10);
- done.Set();
- }
- }
- }
- internal class PortDataEventArgs : EventArgs
- {
- public byte[] data;
- public int type;
- }
- }
|