C#串口通信帮助类

最近开发涉及到和下位机程序进行通信,采用RS485模式,之前也做过类似的开发,本次将封装的通信类进行公开,方便后续类似问题进行快速解决处理。

using System;
using System.Collections.Generic;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace Common
{
public class SerialPortHelper:IDisposable
{
/// <summary>
/// 串口实例
/// </summary>
private SerialPort serialPort;
/// <summary>
/// 默认数据编码格式
/// </summary>
private Encoding defaultEncoding = Encoding.UTF8;

/// <summary>
/// 串口数据返回
/// </summary>
public Action<byte[]> DataRecived;

/// <summary>
/// 初始化串口实例
/// </summary>
/// <param name="port">串口号</param>
/// <param name="baudrate">波特率</param>
/// <param name="parity">校验位</param>
/// <param name="stopBits">停止位</param>
/// <param name="dataBit">数据位</param>
public SerialPortHelper(int port,int baudrate=115200, Parity parity= Parity.None, StopBits stopBits= StopBits.One,int dataBit=8)
{
serialPort = new SerialPort();
serialPort.PortName = "COM"+port;//串口名给了串口类
serialPort.BaudRate = baudrate; // 波特率
serialPort.Parity = parity; //校验位
//停止位
serialPort.StopBits = stopBits;
serialPort.DataBits = dataBit;//数据位
serialPort.DataReceived += SerialPort_DataReceived;
}

private void SerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
Thread.Sleep(100);
if (serialPort.BytesToRead > 0)
{
byte[] a = new byte[serialPort.BytesToRead];//读出缓冲区串口通信的字节
int readbytes = 0;
while (serialPort.Read(a, readbytes, serialPort.BytesToRead - readbytes) <= 0) ;
string str = defaultEncoding.GetString(a);

Console.WriteLine("default 接收到的数据:"+str);

Console.WriteLine($"{serialPort.PortName}接收数据:" + ByteHelper.ByteArrayToHexString(a));

DataRecived?.Invoke(a);
}
}


/// <summary>
/// 打开串口
/// </summary>
/// <param name="encoding">数据编码</param>
public void Open(Encoding encoding=null)
{
try
{
if (null!=encoding)
{
defaultEncoding = encoding;
}
serialPort.Encoding = defaultEncoding;//串口通信的编码格式
if (!serialPort.IsOpen)
{
serialPort.Open();
}
else
{
throw new Exception($"串口{serialPort.PortName}已经打开,请勿重复打开!");
}
}
catch (Exception ex)
{
throw new Exception($"打开串口{serialPort.PortName}失败,如果已经开启,请先关闭!"+ex.Message);
}
}


/// <summary>
/// 关闭串口
/// </summary>
public void Close()
{
if (serialPort.IsOpen)
{
serialPort.DataReceived -= SerialPort_DataReceived;
serialPort.DiscardInBuffer();
serialPort.Dispose();
serialPort.Close();
}
}

/// <summary>
/// 发送数据
/// </summary>
/// <param name="data"></param>
public void Send(byte[] data)
{
Console.WriteLine($"{serialPort.PortName}发送数据:"+ByteHelper.ByteArrayToHexString(data));
serialPort.Write(data,0,data.Length);//将数据写入串行端口输出缓冲区
}

public void Dispose()
{
this.Close();
}
}
}