溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

C#串口通信工具類的封裝方法

發(fā)布時間:2022-02-17 16:05:55 來源:億速云 閱讀:128 作者:iii 欄目:開發(fā)技術(shù)

本篇內(nèi)容介紹了“C#串口通信工具類的封裝方法”的有關(guān)知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細閱讀,能夠?qū)W有所成!

 1、SerialPortHelper串口工具類封裝

using System;
using System.Collections.Generic;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Timers;
 
namespace public.Util
{
 
    /// <summary>
    /// 串口操作助手類
    /// </summary>
    class SerialPortHelper
    {
         /// <summary>
        /// 串口是否已打開
        /// </summary>
        public bool IsOpen { get; set; }
 
        /// <summary>
        /// 初始化 串行端口資源
        /// </summary>
        private SerialPort mySerialPort = new SerialPort();
 
        /// <summary>
        /// 串口接收數(shù)據(jù) 位置
        /// </summary>
        private static int pSerialPortRecv = 0;
 
        /// <summary>
        /// 緩存區(qū)大小的長度
        /// 緩沖區(qū)可調(diào)大
        /// (接收數(shù)據(jù)處理定時器 內(nèi)接收數(shù)據(jù)量 小于下面設(shè)置的值即可)
        /// </summary>
        private static int byteLength = 40960;
 
        /// <summary>
        /// 串口接收字節(jié) 緩存區(qū)大小
        /// </summary>
        private byte[] byteSerialPortRecv = new byte[byteLength];
 
        /// <summary>
        /// 串口 接收數(shù)據(jù)處理定時器
        /// </summary>
        private Timer SerialPortRecvTimer;
 
        /// <summary>
        /// 廣播 收到的數(shù)據(jù) 事件
        /// </summary>
        public event EventHandler<SerialPortRecvEventArgs> ReceivedDataEvent;
 
        /// <summary>
        /// 廣播 收到的數(shù)據(jù)
        /// </summary>
        public class SerialPortRecvEventArgs : EventArgs
        {
            /// <summary>
            /// 廣播 收到的串口數(shù)據(jù)
            /// </summary>
            public readonly byte[] RecvData = new byte[byteLength];
 
            /// <summary>
            /// 收到數(shù)據(jù) 的 長度
            /// </summary>
            public readonly int RecvDataLength;
 
            /// <summary>
            /// 將 收到的數(shù)據(jù) 轉(zhuǎn)化成 待廣播的數(shù)據(jù)
            /// </summary>
            public SerialPortRecvEventArgs(byte[] recvData, int recvDataLength)
            {
                recvData.CopyTo(RecvData, 0);
                RecvDataLength = recvDataLength;
            }
        }
 
        /// <summary>
        /// 初始化
        /// </summary>
        public SerialPortHelper()
        {
            IsOpen = false;
        }
 
        /// <summary>
        /// 設(shè)置 串口配置
        /// </summary>
        /// <param name="portName">串口號</param>
        /// <param name="baudRate">波特率</param>
        /// <param name="parity">校驗位</param>
        /// <param name="dataBits">數(shù)據(jù)位</param>
        /// <param name="stopBits">停止位</param>
        private void SetSerialPortConfig(string portName, int baudRate, int parity, int dataBits, int stopBits)
        {
            // 串口 參數(shù)設(shè)置
            mySerialPort.PortName = portName;
            mySerialPort.BaudRate = baudRate;
            switch (parity)
            {
                case 0:
                default:
                    mySerialPort.Parity = Parity.None;
                    break;
 
                case 1:
                    mySerialPort.Parity = Parity.Odd;
                    break;
 
                case 2:
                    mySerialPort.Parity = Parity.Even;
                    break;
 
                case 3:
                    mySerialPort.Parity = Parity.Mark;
                    break;
 
                case 4:
                    mySerialPort.Parity = Parity.Space;
                    break;
            }
            mySerialPort.DataBits = ((4 < dataBits) && (dataBits < 9)) ? dataBits : 8;
            switch (stopBits)
            {
                case 0:
                    mySerialPort.StopBits = StopBits.None;
                    break;
 
                case 1:
                default:
                    mySerialPort.StopBits = StopBits.One;
                    break;
 
                case 2:
                    mySerialPort.StopBits = StopBits.OnePointFive;
                    break;
 
                case 3:
                    mySerialPort.StopBits = StopBits.Two;
                    break;
            }
            mySerialPort.ReadTimeout = -1;
            mySerialPort.RtsEnable = true;
            mySerialPort.DataReceived += new SerialDataReceivedEventHandler(DataReceived);
 
            // 串口 接收數(shù)據(jù)處理定時器 參數(shù)設(shè)置
            SerialPortRecvTimer = new System.Timers.Timer();
            SerialPortRecvTimer.Interval = 100;
            SerialPortRecvTimer.AutoReset = false;
            SerialPortRecvTimer.Elapsed += new ElapsedEventHandler(SPRecvTimer_Tick);
        }
 
        /// <summary>
        /// 打開串口
        /// </summary>
        /// <param name="portName">串口號</param>
        /// <param name="baudRate">波特率</param>
        /// <param name="parity">校驗位</param>
        /// <param name="dataBits">數(shù)據(jù)位</param>
        /// <param name="stopBits">停止位</param>
        public void OpenSerialPort(string portName, int baudRate, int parity, int dataBits, int stopBits)
        {
            try
            {
                SetSerialPortConfig(portName, baudRate, parity, dataBits, stopBits);
                mySerialPort.Open();
                IsOpen = true;
            }
            catch (System.Exception)
            {
                IsOpen = false;
                throw;
            }
        }
 
        /// <summary>
        /// 關(guān)閉串口
        /// </summary>
        public void CloseSerialPort()
        {
            try
            {
                mySerialPort.Close();
                IsOpen = false;
            }
            catch (System.Exception)
            {
                IsOpen = false;
                throw;
            }
        }
 
        /// <summary>
        /// 串口數(shù)據(jù)發(fā)送
        /// </summary>
        /// <param name="content">byte類型數(shù)據(jù)</param>
        public void SendData(byte[] content)
        {
            try
            {
                mySerialPort.Write(content, 0, content.Length);
            }
            catch (System.Exception)
            {
                throw;
            }
        }
 
        /// <summary>
        /// 串口數(shù)據(jù)發(fā)送
        /// </summary>
        /// <param name="strContent">字符串?dāng)?shù)據(jù)</param>
        /// <param name="encoding">編碼規(guī)則</param>
        public void SendData(string strContent, Encoding encoding)
        {
            try
            {
                byte[] content = encoding.GetBytes(strContent);
                mySerialPort.Write(content, 0, content.Length);
            }
            catch (System.Exception)
            {
                throw;
            }
        }
 
        /// <summary>
        /// 數(shù)據(jù)處理定時器
        /// 定時檢查緩沖區(qū)是否有數(shù)據(jù),如果有數(shù)據(jù)則將數(shù)據(jù)處理并廣播。
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void SPRecvTimer_Tick(object sender, EventArgs e)
        {
            byte[] TemporaryData = new byte[byteLength];
            int TemporaryDataLength = 0;
 
            if (ReceivedDataEvent != null)
            {
                byteSerialPortRecv.CopyTo(TemporaryData, 0);
                TemporaryDataLength = pSerialPortRecv;
 
                ReceivedDataEvent.Invoke(this, new SerialPortRecvEventArgs(TemporaryData, TemporaryDataLength));
                // 數(shù)據(jù)處理完后,將指針指向數(shù)據(jù)頭,等待接收新的數(shù)據(jù)
                pSerialPortRecv = 0;
            }
        }
 
        /// <summary>
        /// 數(shù)據(jù)接收事件
        /// 串口收到數(shù)據(jù)后,關(guān)閉定時器,將收到的數(shù)據(jù)填入緩沖區(qū),數(shù)據(jù)填入完畢后,開啟定時器,等待下一次數(shù)據(jù)接收
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            try
            {
                SerialPortRecvTimer.Stop();
 
                byte[] ReadBuf = new byte[mySerialPort.BytesToRead];
                mySerialPort.Read(ReadBuf, 0, ReadBuf.Length);
                ReadBuf.CopyTo(byteSerialPortRecv, pSerialPortRecv);
                pSerialPortRecv += ReadBuf.Length;
 
                SerialPortRecvTimer.Start();
            }
            catch (System.Exception)
            {
                throw;
            }
        }
 
        /// <summary>
        /// 獲取當(dāng)前可用PortName
        /// </summary>
        /// <returns></returns>
        public static List<SerialPortParam<string>> GetPortList()
        {
            try
            {
                List<SerialPortParam<string>> lst_sParameterClass = new List<SerialPortParam<string>>();
                foreach (string data in SerialPort.GetPortNames())
                {
                    SerialPortParam<string> i_sParameterClass = new SerialPortParam<string>();
                    i_sParameterClass.Name = data;
                    i_sParameterClass.Value = data;
                    lst_sParameterClass.Add(i_sParameterClass);
                }
 
                return lst_sParameterClass;
            }
            catch (Exception)
            {
                
                throw;
            }
        }
 
        /// <summary>
        /// 設(shè)置波特率
        /// </summary>
        /// <returns></returns>
        public static List<SerialPortParam<int>> SetBaudRateValues()
        {
            try
            {
                List<SerialPortParam<int>> lst_sParameterClass = new List<SerialPortParam<int>>();
                foreach (SerialPortBaudRates rate in Enum.GetValues(typeof(SerialPortBaudRates)))
                {
                    SerialPortParam<int> i_sParameterClass = new SerialPortParam<int>();
                    i_sParameterClass.Name = ((int)rate).ToString();
                    i_sParameterClass.Value = (int)rate;
                    lst_sParameterClass.Add(i_sParameterClass);
                }
 
                return lst_sParameterClass;
            }
            catch (Exception)
            {
                throw;
            }
        }
    }
 
 
 
    /// <summary>
    /// 設(shè)置串口助手參數(shù)類,如:波特率
    /// </summary>
    public class SerialPortParam<T> {
        /// <summary>
        /// 顯示值
        /// </summary>
        string name;
 
        /// <summary>
        /// 顯示值
        /// </summary>
        public string Name
        {
            get { return name; }
            set { name = value; }
        }
 
        /// <summary>
        /// 值
        /// </summary>
        T value;
 
        /// <summary>
        /// 值
        /// </summary>
        public T Value
        {
            get { return this.value; }
            set { this.value = value; }
        }
 
    }
 
 
    /// <summary>
    /// 串口波特率列表。
    /// 75,110,150,300,600,1200,2400,4800,9600,14400,19200,28800,38400,56000,57600,
    /// 115200,128000,230400,256000
    /// </summary>
    public enum SerialPortBaudRates
    {
        BaudRate_75 = 75,
        BaudRate_110 = 110,
        BaudRate_150 = 150,
        BaudRate_300 = 300,
        BaudRate_600 = 600,
        BaudRate_1200 = 1200,
        BaudRate_2400 = 2400,
        BaudRate_4800 = 4800,
        BaudRate_9600 = 9600,
        BaudRate_14400 = 14400,
        BaudRate_19200 = 19200,
        BaudRate_28800 = 28800,
        BaudRate_38400 = 38400,
        BaudRate_56000 = 56000,
        BaudRate_57600 = 57600,
        BaudRate_115200 = 115200,
        BaudRate_128000 = 128000,
        BaudRate_230400 = 230400,
        BaudRate_256000 = 256000
    }
}

2、串工工具類的使用方法

//模擬一個點擊事件 
SerialPortHelper serialPortHelper = new SerialPortHelper();
private void button1_Click(object sender, EventArgs e)
 {
           
            serialPortHelper.OpenSerialPort("COM2"/*串口號*/, 115200/*波特率*/, 0/*校驗位*/, 8/*數(shù)據(jù)位*/, 1/*停止位*/);
 
            // 訂閱事件 可以放在 Form_Load 中 或者其他函數(shù)中,但必須執(zhí)行
            serialPortHelper.ReceivedDataEvent += new EventHandler<SerialPortHelper.SerialPortRecvEventArgs>(serialPortHelper_ReceivedDataEvent);
 
            serialPortHelper.SendData(new byte[] { 0x0D });//send
 
 
            serialPortHelper.CloseSerialPort();//close
 
        }
 
/// <summary>
/// 接收串口數(shù)據(jù)
/// </summary>
/// <param name="sender"></param>
/// <param name="args"></param>
private void serialPortHelper_ReceivedDataEvent(object sender, SerialPortHelper.SerialPortRecvEventArgs args)
  {
            // 數(shù)據(jù)內(nèi)容
            Console.Write(args.RecvData);
            // 數(shù)據(jù)長度
            Console.Write(args.RecvDataLength);
}

“C#串口通信工具類的封裝方法”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識可以關(guān)注億速云網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實用文章!

向AI問一下細節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI