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<byte> buf = new List<byte>();//填充到这个临时列表中
|
//依次添加到列表中
|
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);
|
}
|
}
|
}
|