public class SerialHelper
{
private SerialPort _serialPort;
private SerialParam _serialParam;
public SerialHelper(SerialParam param)
{
_serialParam = param;
Open();
}
private void Open()
{
_serialPort = new SerialPort(_serialParam.PortName, _serialParam.BaudRate, _serialParam.PortParity, _serialParam.DataBits);
_serialPort.Open();
}
public bool GetSerialPortState()
{
return _serialPort.IsOpen;
}
public void Close()
{
if (_serialPort == null) return;
_serialPort.Close();
_serialPort.Dispose();
_serialPort = null;
}
/// <summary>
/// 获取本机可用串口
/// </summary>
/// <returns></returns>
public static string[] GetLocalSerialPortNames()
{
return SerialPort.GetPortNames();
}
/// <summary>
/// 发送数据
/// </summary>
/// <param name="msg">数据</param>
/// <param name="timeout">超时时间</param>
/// <param name="count">串口回复字节数</param>
/// <returns></returns>
public byte[] SendMessage(byte[] msg, TimeSpan timeout, int count)
{
var stopwatch = Stopwatch.StartNew();
var originalWriteTimeout = _serialPort.WriteTimeout;
var originalReadTimeout = _serialPort.ReadTimeout;
try
{
_serialPort.WriteTimeout = (int)Math.Max((timeout - stopwatch.Elapsed).TotalMilliseconds, 0);
_serialPort.Write(msg, 0, msg.Length);
var tmpCount = count;
byte[] buffer = new byte[tmpCount];
int offset = 0;
while (tmpCount > 0)
{
_serialPort.ReadTimeout = (int)Math.Max((timeout - stopwatch.Elapsed).TotalMilliseconds, 0);
var readCount = _serialPort.Read(buffer, offset, tmpCount);
offset += readCount;
tmpCount -= readCount;
}
return buffer;
}
finally
{
_serialPort.ReadTimeout = originalReadTimeout;
_serialPort.WriteTimeout = originalWriteTimeout;
}
}
/// <summary>
/// 发送数据
/// </summary>
/// <param name="msg">数据</param>
/// <param name="timeout">超时时间</param>
/// <param name="count">串口回复字节数</param>
/// <returns></returns>
public async Task<byte[]> SendMessageAsync(byte[] msg, TimeSpan timeout, int count)
{
var sendTask = Task.Run(() => SendMessage(msg, timeout, count));
try
{
await Task.WhenAny(sendTask, Task.Delay(timeout));
}
catch (TaskCanceledException)
{
throw new TimeoutException();
}
return await sendTask;
}
}
public class SerialParam
{
public string PortName { get; set; } = "COM3";
public int BaudRate { get; set; } = 57600;
public int DataBits { get; set; } = 8;
public Parity PortParity { get; set; } = Parity.None;
public StopBits PortStopBits { get; set; } = StopBits.None;
}
调用方式也很简单:
Console.WriteLine("Hello, World!");
// 查看本机可用串口
foreach (var val in SerialHelper.GetLocalSerialPortNames())
{
Console.WriteLine(val);
}
// 初始化
var port = new SerialHelper(new SerialParam
{
PortName = "COM4",
BaudRate = 57600,
DataBits = 8
});
// 发送并接收
var result = await port.SendMessageAsync(
"239,1,255,255,255,255,1,0,3,1,0,5".Split(',').Select(c => byte.Parse(c)).ToArray(),
TimeSpan.FromSeconds(1),
14);
Console.WriteLine(string.Join(",", result));
Console.ReadLine();
注意:这边的发送接收是有超时机制的,注意捕获超时异常并处理。