using System; using System.Collections.Generic; using System.Text; using System.Windows.Forms; using System.IO.Ports; using System.Text.RegularExpressions; namespace HalconTools { public class SerialportWrapper { private SerialPort comm = new SerialPort(); string[] ports; private long received_count = 0;//接收计数 private long send_count = 0;//发送计数 public StringBuilder builder = new StringBuilder();//避免在事件处理方法中反复的创建,定义到外面。 private bool flagHexDisplay = false; private bool flagSendNewLine = false; public SerialportWrapper() { //初始化下拉串口名称列表框 ports = SerialPort.GetPortNames(); Array.Sort(ports); //初始化SerialPort对象 comm.NewLine = "/r/n"; comm.RtsEnable = true;//根据实际情况吧。 //添加事件注册 comm.DataReceived += comm_DataReceived; } void comm_DataReceived(object sender, SerialDataReceivedEventArgs e) { int n = comm.BytesToRead;//先记录下来,避免某种原因,人为的原因,操作几次之间时间长,缓存不一致 byte[] buf = new byte[n];//声明一个临时数组存储当前来的串口数据 received_count += n;//增加接收计数 comm.Read(buf, 0, n);//读取缓冲数据 //builder.Remove(0, builder.Length);//清除字符串构造器的内容 //因为要访问ui资源,所以需要使用invoke方式同步ui。 if (flagHexDisplay) { //依次的拼接出16进制字符串 foreach (byte b in buf) { builder.Append(b.ToString("X2") + " "); } } else { //直接按ASCII规则转换成字符串 builder.Append(Encoding.ASCII.GetString(buf)); } } public void Open(string portName, int baudRate, bool hexDisplay) { bool flagPortExists = false; foreach (string port in ports) { if (port.Equals(portName)) { flagPortExists = true; } } if (!flagPortExists) { MessageBox.Show("指定串口(%s)不存在", portName); } comm.PortName = portName; comm.BaudRate = baudRate; this.flagHexDisplay = hexDisplay; try { comm.Open(); } catch (Exception ex) { //捕获到异常信息,创建一个新的comm对象,之前的不能用了。 comm = new SerialPort(); //现实异常信息给客户。 MessageBox.Show(ex.Message); } } public void Open(int index, int baudRate, bool hexDisplay) { if (index > ports.Length) { MessageBox.Show("指定串口(%d)不存在", index.ToString()); } comm.PortName = ports[index]; comm.BaudRate = baudRate; this.flagHexDisplay = hexDisplay; try { comm.Open(); } catch (Exception ex) { //捕获到异常信息,创建一个新的comm对象,之前的不能用了。 comm = new SerialPort(); //现实异常信息给客户。 MessageBox.Show(ex.Message); } } public void Close() { //根据当前串口对象,来判断操作 if (comm.IsOpen) { //打开时点击,则关闭串口 comm.Close(); } } public void Send(string content) { //定义一个变量,记录发送了几个字节 int n = 0; //16进制发送 if (flagHexDisplay) { //我们不管规则了。如果写错了一些,我们允许的,只用正则得到有效的十六进制数 MatchCollection mc = Regex.Matches(content, @"(?i)[/da-f]{2}"); List buf = new List();//填充到这个临时列表中 //依次添加到列表中 foreach (Match m in mc) { buf.Add(byte.Parse(m.Value)); } //转换列表为数组后发送 comm.Write(buf.ToArray(), 0, buf.Count); //记录发送的字节数 n = buf.Count; } else//ascii编码直接发送 { //包含换行符 if (flagSendNewLine) { comm.WriteLine(content); n = content.Length + 2; } else//不包含换行符 { comm.Write(content); n = content.Length; } } send_count += n;//累加发送字节数 } public void Reset() { //复位接受和发送的字节数计数器并更新界面。 send_count = received_count = 0; builder.Remove(0, builder.Length); } public void Clear() { builder.Remove(0, builder.Length); } } }