C#基於SerialPort實現串口通訊服務類-SerialPortService

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相關的方法實現讀取,這種方式通常處理定長或有規律的數據。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章