C#串口開發輔助類

f627 9年前發布 | 1K 次閱讀 C#

    using System;
using System.Collections.Generic;
using System.Text;
using System.IO.Ports;
using System.Windows.Forms;

namespace TestSerialPort  
{  
    /// <summary>  
    /// 串口開發輔助類  
    /// </summary>  
    public class SerialPortUtil  
    {  
        /// <summary>  
        /// 接收事件是否有效 false表示有效  
        /// </summary>  
        public bool ReceiveEventFlag = false;  
        /// <summary>  
        /// 結束符比特  
        /// </summary>  
        public byte EndByte = 0x23;//string End = "#";  

        /// <summary>  
        /// 完整協議的記錄處理事件  
        /// </summary>  
        public event DataReceivedEventHandler DataReceived;  
        public event SerialErrorReceivedEventHandler Error;  

        #region 變量屬性  
        private string _portName = "COM1";//串口號,默認COM1  
        private SerialPortBaudRates _baudRate = SerialPortBaudRates.BaudRate_57600;//波特率  
        private Parity _parity = Parity.None;//校驗位  
        private StopBits _stopBits = StopBits.One;//停止位  
        private SerialPortDatabits _dataBits = SerialPortDatabits.EightBits;//數據位  

        private SerialPort comPort = new SerialPort();  

        /// <summary>  
        /// 串口號  
        /// </summary>  
        public string PortName  
        {  
            get { return _portName; }  
            set { _portName = value; }  
        }  

        /// <summary>  
        /// 波特率  
        /// </summary>  
        public SerialPortBaudRates BaudRate  
        {  
            get { return _baudRate; }  
            set { _baudRate = value; }  
        }  

        /// <summary>  
        /// 奇偶校驗位  
        /// </summary>  
        public Parity Parity  
        {  
            get { return _parity; }  
            set { _parity = value; }  
        }  

        /// <summary>  
        /// 數據位  
        /// </summary>  
        public SerialPortDatabits DataBits  
        {  
            get { return _dataBits; }  
            set { _dataBits = value; }  
        }  

        /// <summary>  
        /// 停止位  
        /// </summary>  
        public StopBits StopBits  
        {  
            get { return _stopBits; }  
            set { _stopBits = value; }  
        }  

        #endregion  

        #region 構造函數  

        /// <summary>  
        /// 參數構造函數(使用枚舉參數構造)  
        /// </summary>  
        /// <param name="baud">波特率</param>  
        /// <param name="par">奇偶校驗位</param>  
        /// <param name="sBits">停止位</param>  
        /// <param name="dBits">數據位</param>  
        /// <param name="name">串口號</param>  
        public SerialPortUtil(string name, SerialPortBaudRates baud, Parity par, SerialPortDatabits dBits, StopBits sBits)  
        {  
            _portName = name;  
            _baudRate = baud;  
            _parity = par;  
            _dataBits = dBits;  
            _stopBits = sBits;  

            comPort.DataReceived += new SerialDataReceivedEventHandler(comPort_DataReceived);  
            comPort.ErrorReceived += new SerialErrorReceivedEventHandler(comPort_ErrorReceived);  
        }  

        /// <summary>  
        /// 參數構造函數(使用字符串參數構造)  
        /// </summary>  
        /// <param name="baud">波特率</param>  
        /// <param name="par">奇偶校驗位</param>  
        /// <param name="sBits">停止位</param>  
        /// <param name="dBits">數據位</param>  
        /// <param name="name">串口號</param>  
        public SerialPortUtil(string name, string baud, string par, string dBits, string sBits)  
        {  
            _portName = name;  
            _baudRate = (SerialPortBaudRates)Enum.Parse(typeof(SerialPortBaudRates), baud);  
            _parity = (Parity)Enum.Parse(typeof(Parity), par);  
            _dataBits = (SerialPortDatabits)Enum.Parse(typeof(SerialPortDatabits), dBits);  
            _stopBits = (StopBits)Enum.Parse(typeof(StopBits), sBits);  

            comPort.DataReceived += new SerialDataReceivedEventHandler(comPort_DataReceived);  
            comPort.ErrorReceived += new SerialErrorReceivedEventHandler(comPort_ErrorReceived);  
        }  

        /// <summary>  
        /// 默認構造函數  
        /// </summary>  
        public SerialPortUtil()  
        {  
            _portName = "COM1";  
            _baudRate = SerialPortBaudRates.BaudRate_9600;  
            _parity = Parity.None;  
            _dataBits = SerialPortDatabits.EightBits;  
            _stopBits = StopBits.One;  

            comPort.DataReceived += new SerialDataReceivedEventHandler(comPort_DataReceived);  
            comPort.ErrorReceived += new SerialErrorReceivedEventHandler(comPort_ErrorReceived);  
        }   

        #endregion  

        /// <summary>  
        /// 端口是否已經打開  
        /// </summary>  
        public bool IsOpen  
        {  
            get  
            {  
                return comPort.IsOpen;  
            }  
        }  

        /// <summary>  
        /// 打開端口  
        /// </summary>  
        /// <returns></returns>  
        public void OpenPort()  
        {  
            if (comPort.IsOpen) comPort.Close();  

            comPort.PortName = _portName;  
            comPort.BaudRate = (int)_baudRate;  
            comPort.Parity = _parity;  
            comPort.DataBits = (int)_dataBits;  
            comPort.StopBits = _stopBits;  

            comPort.Open();  
        }  

        /// <summary>  
        /// 關閉端口  
        /// </summary>  
        public void ClosePort()  
        {  
            if (comPort.IsOpen) comPort.Close();  
        }  

        /// <summary>  
        /// 丟棄來自串行驅動程序的接收和發送緩沖區的數據  
        /// </summary>  
        public void DiscardBuffer()  
        {  
            comPort.DiscardInBuffer();  
            comPort.DiscardOutBuffer();  
        }  

        /// <summary>  
        /// 數據接收處理  
        /// </summary>  
        void comPort_DataReceived(object sender, SerialDataReceivedEventArgs e)  
        {  
            //禁止接收事件時直接退出  
            if (ReceiveEventFlag) return;  

            #region 根據結束字節來判斷是否全部獲取完成  
            List<byte> _byteData = new List<byte>();  
            bool found = false;//是否檢測到結束符號  
            while (comPort.BytesToRead > 0 || !found)  
            {  
                byte[] readBuffer = new byte[comPort.ReadBufferSize + 1];  
                int count = comPort.Read(readBuffer, 0, comPort.ReadBufferSize);  
                for (int i = 0; i < count; i++)  
                {  
                    _byteData.Add(readBuffer[i]);  

                    if (readBuffer[i] == EndByte)  
                    {  
                        found = true;  
                    }  
                }  
            }   
            #endregion  

            //字符轉換  
            string readString = System.Text.Encoding.Default.GetString(_byteData.ToArray(), 0, _byteData.Count);  

            //觸發整條記錄的處理  
            if (DataReceived != null)  
            {  
                DataReceived(new DataReceivedEventArgs(readString));  
            }  
        }  

        /// <summary>  
        /// 錯誤處理函數  
        /// </summary>  
        void comPort_ErrorReceived(object sender, SerialErrorReceivedEventArgs e)  
        {  
            if (Error != null)  
            {  
                Error(sender, e);  
            }  
        }  

        #region 數據寫入操作  

        /// <summary>  
        /// 寫入數據  
        /// </summary>  
        /// <param name="msg"></param>  
        public void WriteData(string msg)  
        {  
            if (!(comPort.IsOpen)) comPort.Open();  

            comPort.Write(msg);  
        }  

        /// <summary>  
        /// 寫入數據  
        /// </summary>  
        /// <param name="msg">寫入端口的字節數組</param>  
        public void WriteData(byte[] msg)  
        {  
            if (!(comPort.IsOpen)) comPort.Open();  

            comPort.Write(msg, 0, msg.Length);  
        }  

        /// <summary>  
        /// 寫入數據  
        /// </summary>  
        /// <param name="msg">包含要寫入端口的字節數組</param>  
        /// <param name="offset">參數從0字節開始的字節偏移量</param>  
        /// <param name="count">要寫入的字節數</param>  
        public void WriteData(byte[] msg, int offset, int count)  
        {  
            if (!(comPort.IsOpen)) comPort.Open();  

            comPort.Write(msg, offset, count);  
        }  

        /// <summary>  
        /// 發送串口命令  
        /// </summary>  
        /// <param name="SendData">發送數據</param>  
        /// <param name="ReceiveData">接收數據</param>  
        /// <param name="Overtime">重復次數</param>  
        /// <returns></returns>  
        public int SendCommand(byte[] SendData, ref  byte[] ReceiveData, int Overtime)  
        {  
            if (!(comPort.IsOpen)) comPort.Open();  

            ReceiveEventFlag = true;        //關閉接收事件  
            comPort.DiscardInBuffer();      //清空接收緩沖區                   
            comPort.Write(SendData, 0, SendData.Length);  

            int num = 0, ret = 0;  
            while (num++ < Overtime)  
            {  
                if (comPort.BytesToRead >= ReceiveData.Length) break;  
                System.Threading.Thread.Sleep(1);  
            }  

            if (comPort.BytesToRead >= ReceiveData.Length)  
            {  
                ret = comPort.Read(ReceiveData, 0, ReceiveData.Length);  
            }  

            ReceiveEventFlag = false;       //打開事件  
            return ret;  
        }  

        #endregion  

        #region 常用的列表數據獲取和綁定操作  

        /// <summary>  
        /// 封裝獲取串口號列表  
        /// </summary>  
        /// <returns></returns>  
        public static string[] GetPortNames()  
        {  
            return SerialPort.GetPortNames();  
        }  

        /// <summary>  
        /// 設置串口號  
        /// </summary>  
        /// <param name="obj"></param>  
        public static void SetPortNameValues(ComboBox obj)  
        {  
            obj.Items.Clear();  
            foreach (string str in SerialPort.GetPortNames())  
            {  
                obj.Items.Add(str);  
            }  
        }  

        /// <summary>  
        /// 設置波特率  
        /// </summary>  
        public static void SetBauRateValues(ComboBox obj)  
        {  
            obj.Items.Clear();  
            foreach (SerialPortBaudRates rate in Enum.GetValues(typeof(SerialPortBaudRates)))  
            {  
                obj.Items.Add(((int)rate).ToString());  
            }  
        }  

        /// <summary>  
        /// 設置數據位  
        /// </summary>  
        public static void SetDataBitsValues(ComboBox obj)  
        {  
            obj.Items.Clear();  
            foreach (SerialPortDatabits databit in Enum.GetValues(typeof(SerialPortDatabits)))  
            {  
                obj.Items.Add(((int)databit).ToString());  
            }  
        }  

        /// <summary>  
        /// 設置校驗位列表  
        /// </summary>  
        public static  void SetParityValues(ComboBox obj)  
        {  
            obj.Items.Clear();  
            foreach (string str in Enum.GetNames(typeof(Parity)))  
            {  
                obj.Items.Add(str);  
            }  
            //foreach (Parity party in Enum.GetValues(typeof(Parity)))  
            //{  
            //    obj.Items.Add(((int)party).ToString());  
            //}  
        }  

        /// <summary>  
        /// 設置停止位  
        /// </summary>  
        public static void SetStopBitValues(ComboBox obj)  
        {  
            obj.Items.Clear();  
            foreach (string str in Enum.GetNames(typeof(StopBits)))  
            {  
                obj.Items.Add(str);  
            }  
            //foreach (StopBits stopbit in Enum.GetValues(typeof(StopBits)))  
            //{  
            //    obj.Items.Add(((int)stopbit).ToString());  
            //}     
        }  

        #endregion  

        #region 格式轉換  
        /// <summary>  
        /// 轉換十六進制字符串到字節數組  
        /// </summary>  
        /// <param name="msg">待轉換字符串</param>  
        /// <returns>字節數組</returns>  
        public static byte[] HexToByte(string msg)  
        {  
            msg = msg.Replace(" ", "");//移除空格  

            //create a byte array the length of the  
            //divided by 2 (Hex is 2 characters in length)  
            byte[] comBuffer = new byte[msg.Length / 2];  
            for (int i = 0; i < msg.Length; i += 2)  
            {  
                //convert each set of 2 characters to a byte and add to the array  
                comBuffer[i / 2] = (byte)Convert.ToByte(msg.Substring(i, 2), 16);  
            }  

            return comBuffer;  
        }  

        /// <summary>  
        /// 轉換字節數組到十六進制字符串  
        /// </summary>  
        /// <param name="comByte">待轉換字節數組</param>  
        /// <returns>十六進制字符串</returns>  
        public static string ByteToHex(byte[] comByte)  
        {  
            StringBuilder builder = new StringBuilder(comByte.Length * 3);  
            foreach (byte data in comByte)  
            {  
                builder.Append(Convert.ToString(data, 16).PadLeft(2, '0').PadRight(3, ' '));  
            }  

            return builder.ToString().ToUpper();  
        }  
        #endregion  

        /// <summary>  
        /// 檢查端口名稱是否存在  
        /// </summary>  
        /// <param name="port_name"></param>  
        /// <returns></returns>  
        public static bool Exists(string port_name)  
        {  
            foreach (string port in SerialPort.GetPortNames()) if (port == port_name) return true;  
            return false;  
        }  

        /// <summary>  
        /// 格式化端口相關屬性  
        /// </summary>  
        /// <param name="port"></param>  
        /// <returns></returns>  
        public static string Format(SerialPort port)  
        {  
            return String.Format("{0} ({1},{2},{3},{4},{5})",   
                port.PortName, port.BaudRate, port.DataBits, port.StopBits, port.Parity, port.Handshake);  
        }  
    }  

    public class DataReceivedEventArgs : EventArgs  
    {  
        public string DataReceived;  
        public DataReceivedEventArgs(string m_DataReceived)  
        {  
            this.DataReceived = m_DataReceived;  
        }  
    }  

    public delegate void DataReceivedEventHandler(DataReceivedEventArgs e);  


    /// <summary>  
    /// 串口數據位列表(5,6,7,8)  
    /// </summary>  
    public enum SerialPortDatabits : int  
    {  
        FiveBits = 5,  
        SixBits = 6,  
        SeventBits = 7,  
        EightBits = 8  
    }  

    /// <summary>  
    /// 串口波特率列表。  
    /// 75,110,150,300,600,1200,2400,4800,9600,14400,19200,28800,38400,56000,57600,  
    /// 115200,128000,230400,256000  
    /// </summary>  
    public enum SerialPortBaudRates : int  
    {  
        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  
    }  
}  </pre> 


    //使用方法
private void btnConnect_Click(object sender, EventArgs e)
{
try
{
if (serial == null)
{
try
{
string portname = this.txtPort.Text;
SerialPortBaudRates rate = (SerialPortBaudRates)Enum.Parse(typeof(SerialPortBaudRates), this.txtBaudRate.Text);//int.Parse(this.txtBaudRate.Text);
SerialPortDatabits databit = (SerialPortDatabits)int.Parse(this.txtDataBits.Text);
Parity party = (Parity)Enum.Parse(typeof(Parity), this.txtParity.Text);
StopBits stopbit = (StopBits)Enum.Parse(typeof(StopBits), this.txtStopBit.Text);

                //使用枚舉參數構造  
                //serial = new SerialPortUtil(portname, rate, party, databit, stopbit);  

                //使用字符串參數構造  
                serial = new SerialPortUtil(portname, this.txtBaudRate.Text, this.txtParity.Text, this.txtDataBits.Text, this.txtStopBit.Text);  
                serial.DataReceived += new DataReceivedEventHandler(serial_DataReceived);  

            }  
            catch (Exception ex)  
            {  
                MessageBox.Show(ex.Message);  
                serial = null;  
                return;  
            }  
        }  

        if (!isOpened)  
        {                      
            serial.OpenPort();  
            btnConnect.Text = "斷開";  
        }  
        else  
        {  
            serial.ClosePort();  
            serial = null;  

            btnConnect.Text = "連接";  
        }  

        isOpened = !isOpened;  
        this.btnSend.Enabled = isOpened;  
        this.lblTips.Text = isOpened ? "已連接" : "未連接";  
    }  
    catch (Exception ex)  
    {  
        this.lblTips.Text = ex.Message;  
        MessageBox.Show(ex.Message);  
    }  
}  

void serial_DataReceived(DataReceivedEventArgs e)  
{  
    this.txtReceived.Invoke(new MethodInvoker(delegate  
    {  
        this.txtReceived.AppendText(e.DataReceived + Environment.NewLine);  
    }));  
}  </pre> 


 本文由用戶 f627 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!