using System; using System.Collections.Generic; using System.IO.Ports; using System.Linq; using System.Text.RegularExpressions; namespace EC.Utils.SerialPortHelper { /// /// 返回数据类型 /// public enum ReturnDateType { /// /// 返回byte[] /// Bytes = 0, HexStr = 1, Str = 2, } /// /// EC 串口类 /// public class ECSerialPort { private SerialPort comm = new SerialPort();//声明一个串口 private SerialCustomer serialCustomer = null; private bool openFlag = false;// 是否打开成功 public long ReceivedCount { get; set; }//接收计数 public long RendCount { get; set; }//发送计数 public ECSerialPort(SerialCustomer serialCustomer) { this.serialCustomer = serialCustomer; } public bool OpenCom() { //根据当前串口对象,来判断操作 if (comm.IsOpen) { //打开时点击,则关闭串口 comm.Close(); openFlag = false; } else { if (serialCustomer.ComName == "") { throw new Exception("请插入串口设备!"); } //关闭时点击,则设置好端口,波特率后打开 //获得串口端口信息为: COM1:通讯端口 comm.PortName = serialCustomer.ComName; comm.BaudRate = serialCustomer.BaudRate;// int.Parse(comboBaudrate.Text);//波特率 comm.DataBits = serialCustomer.DataBits;//数据位 comm.Parity = (Parity)serialCustomer.Parity;//奇偶校验0-4=no,odd,even,mark,space comm.StopBits = (StopBits)Convert.ToInt32(serialCustomer.StopBits);//停止位 comm.ReadTimeout = 2000;//写超时 comm.WriteTimeout = 500;//读超时 //comm.WriteBufferSize = 1024; //comm.ReadBufferSize = 1024; comm.ReceivedBytesThreshold = serialCustomer.ReceivedBytesThreshold;//128Btye时触发一次事件,设置为1时易造成线程死锁。 comm.RtsEnable = true; comm.DtrEnable = true; //comm.Handshake = Handshake.None; //添加事件注册 comm.DataReceived += new SerialDataReceivedEventHandler(Comm_DataReceived); comm.Open(); } openFlag = comm.IsOpen ? true : false; return openFlag; } /// /// 关闭串口 /// public void CloseCom() { comm.Close(); openFlag = false; } public bool IsOpen() { return comm.IsOpen; } public event EventHandler OnRecData; //定义一个委托类型的事件 private void Comm_DataReceived(object sender, EventArgs e) { int n = comm.BytesToRead;//获取缓存区字节数 byte[] buf = new byte[n];//存储串口数据用 ReceivedCount += n;//接收计数 comm.Read(buf, 0, n);//读取缓冲数据 //OnRecData?.BeginInvoke(this, buf, null, null); OnRecData?.Invoke(this, buf); } /// /// 发送串口 /// /// /// /// public void Send(bool checkBoxHexSend, string sendtext, bool newLine = false) { //定义一个变量,记录发送了几个字节 int n = 0; //16进制发送 if (checkBoxHexSend) { //正则得到有效的十六进制数(?i)对大小写不敏感,[/da-f],{2}连续出现2次 // MatchCollection mc = Regex.Matches(txSend.Text, @"(?i)[/da-f]{2}"); MatchCollection mc = Regex.Matches(sendtext, @"(?i)[\da-f]{2}"); List buf = new List();//填充到这个临时列表中 //依次添加到列表中 foreach (Match m in mc) { buf.Add(byte.Parse(m.Value, System.Globalization.NumberStyles.HexNumber)); } //转换列表为数组后发送 comm.Write(buf.ToArray(), 0, buf.Count); if (newLine == true) { //记录发送的字节数 comm.WriteLine("\r\n"); n = buf.Count + 2; } else n = buf.Count; } else//ascii编码直接发送 { if (newLine == true) { comm.Write(sendtext + "\r\n"); n = sendtext.Length + 2; } else//不包含换行符 { comm.Write(sendtext); n = sendtext.Length; } } RendCount += n;//累加发送字节数 } /// /// 16进制发送 /// /// /// public void SendHex(byte[] buf, bool newline = false) { //定义一个变量,记录发送了几个字节 int n = 0; int bufLen = buf.Count(); comm.Write(buf, 0, bufLen); //if (newline == true) //{ //记录发送的字节数 //comm.WriteLine("\n"); //n = bufLen + 2; //} //else // n = bufLen; RendCount += n;//累加发送字节数 } public void DiscardInBuffer() { comm.DiscardInBuffer(); } } }