C#串口通信帮助类

C#串口通信帮助类

最近开发涉及到和下位机程序进行通信,采用RS485模式,之前也做过类似的开发,本次将封装的通信类进行公开,方便后续类似问题进行快速解决处理。

using System;
using System.Collections.Generic;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace Common
{
    public class SerialPortHelper:IDisposable
    {
        /// <summary>
        /// 串口实例
        /// </summary>
        private SerialPort serialPort;
        /// <summary>
        /// 默认数据编码格式
        /// </summary>
        private Encoding defaultEncoding = Encoding.UTF8;

        /// <summary>
        /// 串口数据返回
        /// </summary>
        public Action<byte[]> DataRecived;

        /// <summary>
        /// 初始化串口实例
        /// </summary>
        /// <param name="port">串口号</param>
        /// <param name="baudrate">波特率</param>
        /// <param name="parity">校验位</param>
        /// <param name="stopBits">停止位</param>
        /// <param name="dataBit">数据位</param>
        public SerialPortHelper(int port,int baudrate=115200, Parity parity= Parity.None, StopBits stopBits= StopBits.One,int dataBit=8)
        {
            serialPort = new SerialPort();
            serialPort.PortName = "COM"+port;//串口名给了串口类
            serialPort.BaudRate = baudrate; // 波特率
            serialPort.Parity = parity; //校验位
            //停止位
            serialPort.StopBits = stopBits;
            serialPort.DataBits = dataBit;//数据位
            serialPort.DataReceived += SerialPort_DataReceived;
        }

        private void SerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            Thread.Sleep(100);
            if (serialPort.BytesToRead > 0)
            {
                byte[] a = new byte[serialPort.BytesToRead];//读出缓冲区串口通信的字节                                              
                int readbytes = 0;
                while (serialPort.Read(a, readbytes, serialPort.BytesToRead - readbytes) <= 0) ;
                string str = defaultEncoding.GetString(a);

                Console.WriteLine("default 接收到的数据:"+str);
                
                Console.WriteLine($"{serialPort.PortName}接收数据:" + ByteHelper.ByteArrayToHexString(a));

                DataRecived?.Invoke(a);
            }
        }


        /// <summary>
        /// 打开串口
        /// </summary>
        /// <param name="encoding">数据编码</param>
        public void Open(Encoding encoding=null)
        {
            try
            {
                if (null!=encoding)
                {
                    defaultEncoding = encoding;
                }
                serialPort.Encoding = defaultEncoding;//串口通信的编码格式
                if (!serialPort.IsOpen)
                {
                    serialPort.Open();
                }
                else
                {
                    throw new Exception($"串口{serialPort.PortName}已经打开,请勿重复打开!");
                }
            }
            catch (Exception ex)
            {
                throw new Exception($"打开串口{serialPort.PortName}失败,如果已经开启,请先关闭!"+ex.Message);
            }
        }


        /// <summary>
        /// 关闭串口
        /// </summary>
        public void Close()
        {
            if (serialPort.IsOpen)
            {
                serialPort.DataReceived -= SerialPort_DataReceived;
                serialPort.DiscardInBuffer();
                serialPort.Dispose();
                serialPort.Close();
            }
        }

        /// <summary>
        /// 发送数据
        /// </summary>
        /// <param name="data"></param>
        public void Send(byte[] data)
        {
            Console.WriteLine($"{serialPort.PortName}发送数据:"+ByteHelper.ByteArrayToHexString(data));
            serialPort.Write(data,0,data.Length);//将数据写入串行端口输出缓冲区
        }

        public void Dispose()
        {
            this.Close();
        }
    }
}

posted @ 2022-12-03 09:09  星火燎猿*  阅读(149)  评论(0编辑  收藏  举报