Demo
private readonly SerialPortHelper _spHelper;
ctor()
{
_spHelper = new SerialPortHelper();
_spHelper.DataReceivedEvent += SerialPort_DataReceivedEvent;
_spHelper.Close();
if (_spHelper.Init("COM1"))
{
_spHelper.SetStartIdentifier(new byte[] { 0xFA, 0xFA });
_spHelper.SetEndIdentifier(new byte[] { 0xFB, 0xFB });
}
_spHelper.WriteXORCheck(command, WatchdogIdentifiers.讀取數據);
}
private void SerialPort_DataReceivedEvent(object sender, EventArgs e)
{
if (e is CustomSerialPortEventArgs arg)
{
var data = arg.Message;
if (_spHelper.DataXORCheck(data))
{
switch (data[1])
{
case (byte)WatchdogIdentifiers.設置數據:
{
}
break;
case (byte)WatchdogIdentifiers.讀取數據:
{
}
break;
}
}
}
}
/// <summary>
/// 看門狗的通信標識
/// </summary>
internal enum WatchdogIdentifiers
{
/// <summary>
/// 1_1
/// </summary>
[Description("1")]
設置數據 = 1,
/// <summary>
/// 1_2
/// </summary>
[Description("2")]
讀取數據 = 2,
}
SerialPortHelper
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO.Ports;
/// <summary>
/// 串行端口通信幫助類(有幀頭、幀尾檢測)
/// </summary>
internal class SerialPortHelper
{
private readonly WeakEvent<EventArgs> _dataReceivedEvent = new WeakEvent<EventArgs>();
/// <summary>
/// 返回的消息數據弱事件
/// </summary>
public event EventHandler<EventArgs> DataReceivedEvent
{
add => _dataReceivedEvent.Add(value, value.Invoke);
remove => _dataReceivedEvent.Remove(value);
}
public bool IsOpen => _serialPort != null && _serialPort.IsOpen;
private CustomSerialPort _serialPort;
/// <summary>
/// 設置結尾標識符
/// </summary>
/// <param name="end"></param>
public void SetEndIdentifier(byte[] end)
{
if (_serialPort != null)
{
_serialPort.EndIdentifier = end;
}
}
/// <summary>
/// 設置開始標識符
/// </summary>
/// <param name="start"></param>
public void SetStartIdentifier(byte[] start)
{
if (_serialPort != null)
{
_serialPort.StartIdentifier = start;
}
}
/// <summary>
/// 延遲接收數據。
/// 默認不設置幀頭、幀尾,根據實際情況判斷數據完整性!
/// </summary>
/// <param name="millionsecond">默認500(ms)</param>
public void SetDelayDataReceived(int millionsecond = 500)
{
if (_serialPort != null)
{
_serialPort.StartIdentifier = null;
_serialPort.EndIdentifier = null;
_serialPort.DelayRecived(millionsecond);
}
}
public bool Init(string portName, int baudRate = 9600, Parity parity = Parity.None, int dataBits = 8, StopBits stopBits = StopBits.One)
{
try
{
_serialPort = new CustomSerialPort(portName, baudRate, parity, dataBits, stopBits);
_serialPort.DataReceivedEvent += SerialPort_DataReceivedEvent;
return _serialPort.IsOpen;
}
catch (Exception ex)
{
LogFactory.GetInstance().Info(ex.Message);
}
return false;
}
/// <summary>
/// 串口數據寫(帶數據異或校驗)
/// </summary>
/// <param name="data"></param>
/// <param name="identifier">通信標識</param>
/// <param name="version">版本</param>
public void WriteXORCheck(byte[] data, WatchdogIdentifiers identifier, int version = 1)
{
if (IsOpen)
{
// 通信命令格式: 起始符(FA FA) + 版本 + 通信標識 + 數據長度(mod 255) + 數據內容(DATA) + 數據校驗 + 結束符(F5 F5)
int len = data.Length % 255;
byte xor = WSCommFunc.GetXOR(data);
List<byte> tmp = new List<byte>(data.Length + 4) { (byte)version, (byte)identifier, (byte)len };
tmp.AddRange(data);
tmp.Add(xor);
_serialPort.WritePort(tmp.ToArray());
}
}
/// <summary>
/// 獲取的數據異或校驗
/// </summary>
/// <param name=""></param>
/// <returns>true校驗成功</returns>
public bool DataXORCheck(byte[] data)
{
// 數據格式: 版本 + 通信標識 + 數據長度(mod 255) + 數據內容(DATA) + 數據校驗
int length = data.Length;
if (length <= 4)
{
return false;
}
// 長度不一致,異常數據
if (data[2] != length - 4)
{
return false;
}
byte[] temp = new byte[length - 4];
Array.Copy(data, 3, temp, 0, length - 4);
byte xor = WSCommFunc.GetXOR(temp);
return xor == data[length - 1];
}
/// <summary>
/// 串口數據寫
/// </summary>
/// <param name="data"></param>
public void Write(byte[] data)
{
if (IsOpen)
{
_serialPort.WritePort(data);
}
}
/// <summary>
/// 串口數據寫
/// </summary>
/// <param name="data"></param>
public void Write(string data)
{
if (IsOpen)
{
_serialPort.WritePort(data);
}
}
public void Close()
{
if (_serialPort != null)
{
_serialPort.DataReceivedEvent -= SerialPort_DataReceivedEvent;
_serialPort.Close();
_serialPort = null;
}
}
private void SerialPort_DataReceivedEvent(object sender, EventArgs e)
{
_dataReceivedEvent.Invoke(this, e);
}
}
其中,CustomSerialPort是一般串口通信的基本功能,可自行實現。