C#基於SerialPort實現串口通訊服務類-SerialPortService
背景
在工控軟件開發時,除了與PLC通訊外,還會與許多串口通訊設備進行通訊,比如掃碼槍、電子大屏等,甚至一個系統可能會同時通過多個串口與多個設備進行通訊。爲了方面串口對象的創建,與基本參數設置,我對創建串口對象進行了簡單封裝,本文就分享一下代碼。
代碼實現
SerialPortService.cs代碼如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO.Ports;
namespace Mesnac.Communication
{
/// <summary>
/// 串口通訊服務類
/// </summary>
public class SerialPortService
{
#region 單例實現
private static SerialPortService instance = null;
private Dictionary<int, SerialPort> _dicSerialPort = null; //保存串口對象的集合
private SerialPortService()
{
if (this._dicSerialPort == null)
{
this._dicSerialPort = new Dictionary<int, SerialPort>();
}
}
public static SerialPortService Instance
{
get
{
if (instance == null)
{
instance = new SerialPortService();
}
return instance;
}
}
#endregion
#region 獲取串口對象
/// <summary>
/// 獲取串口對象
/// </summary>
/// <param name="portName">串口名稱</param>
/// <param name="baudRate">波特率</param>
/// <returns>返可用的串口對象</returns>
public SerialPort GetSerialPort(string portName, int baudRate)
{
SerialPort currSerialPort = null;
foreach (SerialPort sp in this._dicSerialPort.Values)
{
if (sp.PortName == portName && sp.BaudRate == baudRate)
{
currSerialPort = sp;
break;
}
}
if (currSerialPort == null)
{
currSerialPort = new SerialPort();
currSerialPort.PortName = portName;
currSerialPort.BaudRate = baudRate;
currSerialPort.ReadTimeout = 3000;
currSerialPort.Handshake = Handshake.None;
currSerialPort.ReceivedBytesThreshold = 1;
currSerialPort.RtsEnable = true;
currSerialPort.Encoding = System.Text.Encoding.Default;
this._dicSerialPort.Add(currSerialPort.GetHashCode(), currSerialPort);
}
try
{
if (currSerialPort.IsOpen)
{
currSerialPort.Close();
currSerialPort.Open();
}
else
{
currSerialPort.Open();
}
}
catch (Exception ex)
{
ICSharpCode.Core.LoggingService.Warn(String.Format("串口{0}關閉或打開失敗,重新創建串口對象,詳情:{1}", portName, ex.Message));
this._dicSerialPort.Remove(currSerialPort.GetHashCode());
currSerialPort = new SerialPort();
currSerialPort.PortName = portName;
currSerialPort.BaudRate = baudRate;
currSerialPort.ReadTimeout = 3000;
currSerialPort.Handshake = Handshake.None;
currSerialPort.ReceivedBytesThreshold = 1;
currSerialPort.RtsEnable = true;
currSerialPort.Encoding = System.Text.Encoding.Default;
this._dicSerialPort.Add(currSerialPort.GetHashCode(), currSerialPort);
currSerialPort.Open();
}
return currSerialPort;
}
#endregion
}
}
關於串口數據讀取說明
關於從SerialPort讀取數據一般有2中方式,一是通過訂閱SerialPort的DataReceived事件,通過寫事件處理程序實現對SerialPort的數據獲取。二是寫一個定時器任務(通常是起一個單獨的線程,線程任務是一個死循環,或者通過開關變量控制循環),在定時任務中通過調用SerialPort的Read相關的方法實現讀取,這種方式通常處理定長或有規律的數據。