You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

184 lines
4.6 KiB

using System;
using System.Collections.Generic;
using System.IO.Ports;
using System.Linq;
using System.Text.RegularExpressions;
namespace EC.Utils.SerialPortHelper
{
/// <summary>
/// 返回数据类型
/// </summary>
public enum ReturnDateType
{
/// <summary>
/// 返回byte[]
/// </summary>
Bytes = 0,
HexStr = 1,
Str = 2,
}
/// <summary>
/// EC 串口类
/// </summary>
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;
}
/// <summary>
/// 关闭串口
/// </summary>
public void CloseCom()
{
comm.Close();
openFlag = false;
}
public bool IsOpen()
{
return comm.IsOpen;
}
public event EventHandler<byte[]> 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);
}
/// <summary>
/// 发送串口
/// </summary>
/// <param name="checkBoxHexSend"></param>
/// <param name="sendtext"></param>
/// <param name="newLine"></param>
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<byte> buf = new List<byte>();//填充到这个临时列表中
//依次添加到列表中
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;//累加发送字节数
}
/// <summary>
/// 16进制发送
/// </summary>
/// <param name="buf"></param>
/// <param name="newline"></param>
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();
}
}
}