自定義串口通訊類的實現

  前面寫串口通訊是有界面的,後面的項目感覺串口通訊只是輔助的作用,應該專門寫一個不可視的類來做,這樣的好處是通訊模塊是獨立的,要用的時候直接引用就行了。

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

namespace YBDW
{
    class SerialPortCommunication
    {
        //聲明變量
        public SerialPort sp = new SerialPort();
        public bool isOpen = false;//串口是否被打開
        public bool SetSetPropertyOK = false;//屬性是否設置好
        public bool isDataFormatHex = false;//數據格式是否是16進制
        List<byte> ReceiveDataList = new List<byte>();//定義一個泛型數組來接收數據
        string sDataChar;//轉換成的字符串
        //聲明事件
        public delegate void OnReceiveMsgHandler(string s1);
        public event OnReceiveMsgHandler OnReceiveMsg;//接收數據事件

        public struct isCommPortPropertys
        {
            public string sPort;//串口號
            public string sBaudRate;//波特率
            public string sDataBit;//數據位
            public string sParity;//校驗位
            public string sStopBit;//停止位
            public string sDataFormat;//數據格式
            public string sReadTimeout;//超時讀取時間
        }

        public isCommPortPropertys CommPortProperty = new isCommPortPropertys();

        //構造函數
        public SerialPortCommunication()
        {
            //
            //sp.sp_DataReceived += OnReceiveMsg;
        }

        public void SetCommPortProperty()
        {
            //設置串口屬性
            sp.PortName = CommPortProperty.sPort;
            sp.BaudRate = Convert.ToInt32(CommPortProperty.sBaudRate);
            sp.DataBits = Convert.ToInt16(CommPortProperty.sDataBit);
            switch (CommPortProperty.sParity)
            {
                case "無":
                    sp.Parity = Parity.None;
                    break;
                case "奇校驗":
                    sp.Parity = Parity.Odd;
                    break;
                case "偶校驗":
                    sp.Parity = Parity.Even;
                    break;
                default:
                    sp.Parity = Parity.None;
                    break;
            }
            switch (CommPortProperty.sDataFormat)
            {
                case "ASCII":
                    isDataFormatHex = false;
                    break;
                case "HEX":
                    isDataFormatHex = true;
                    break;
                default:
                    isDataFormatHex = false;
                    break;
            }
            sp.ReadTimeout = Convert.ToInt32(CommPortProperty.sReadTimeout);
            sp.RtsEnable = true;
            //掛接DataReceived數據接收事件,當串口收到數據後觸發該事件
            sp.DataReceived += new SerialDataReceivedEventHandler(sp_DataReceived);
            SetSetPropertyOK = true;
        }

        public void Close()
        {
            sp.DataReceived -= sp_DataReceived;
            sp.Close();
            isOpen = false;
        }

        public void Start()
        {
            if (SetSetPropertyOK)
            {
                try
                {
                    sp.Open();
                    isOpen = true;
                }
                catch (Exception e)
                {
                    sp.Close();
                    isOpen = false;
                    MessageBox.Show("屬性沒有設置好!"+e.ToString());
                }
            }
        }

        private void sp_DataReceived(object sender,SerialDataReceivedEventArgs e)
        {
            Thread.Sleep(100);//休眠100毫秒
            byte[] ReceiveDataByte = new byte[sp.BytesToRead];//創建接收字節數組          
            sp.Read(ReceiveDataByte, 0, ReceiveDataByte.Length);//讀取接收到的數據
            ReceiveDataList.Clear();
            sDataChar = "";
            ReceiveDataList.AddRange(ReceiveDataByte);
            if (isDataFormatHex)
            {
                //16進制
                for (int i=0;i<ReceiveDataByte.Length;i++)
                {
                    sDataChar += ReceiveDataByte[i].ToString("X2") + " ";
                }
            }
            else
            {
                //ASCII
                sDataChar = Encoding.Default.GetString(ReceiveDataList.ToArray());
            } 
            if (this.OnReceiveMsg != null) OnReceiveMsg(sDataChar);//通過事件傳遞接收到的數據
        } 

        public void SendData(string sSendData)
        {
            bool CanSend = true;
            if (string.IsNullOrEmpty(sSendData)) CanSend = false;
            if (!isOpen) CanSend = false;
            if (CanSend) sp.WriteLine(sSendData);
        }
    }
}

這樣的好處是通訊只負責接收或者發送數據,處理數據有專門的類來完成,代碼是相互獨立分開的。
引用:

        //創建串口對象
        SerialPortCommunication YBDWCommPort =new SerialPortCommunication();//串口通訊
  //設置串口屬性
  FrmSetCommPort Frm1 = new FrmSetCommPort();
  Frm1.TransmitEvent += Transmit;
  if (Frm1.ShowDialog() == DialogResult.OK)
  {
      YBDWCommPort.CommPortProperty.sPort = DawnCommPortProperty.sPort;//串口號
      YBDWCommPort.CommPortProperty.sBaudRate = DawnCommPortProperty.sBaudRate;//波特率
      YBDWCommPort.CommPortProperty.sStopBit = DawnCommPortProperty.sStopBit;//停止位
      YBDWCommPort.CommPortProperty.sDataBit = DawnCommPortProperty.sDataBit;//數據位
      YBDWCommPort.CommPortProperty.sParity = DawnCommPortProperty.sParity;//奇偶校驗位
      YBDWCommPort.CommPortProperty.sDataFormat = DawnCommPortProperty.sDataFormat;//數據格式
      YBDWCommPort.CommPortProperty.sReadTimeout = DawnCommPortProperty.sReadTimeout;//超時讀取時間
      YBDWCommPort.SetCommPortProperty();
      //啓動偵聽,接收串口數據
      YBDWCommPort.OnReceiveMsg += OnReceiveMsg;
      YBDWCommPort.Start();
      this.button1.Text = "關閉串口";
  }

  //數據處理

        private void OnReceiveMsg(string s1)
        {
            if (string.IsNullOrEmpty(s1))
            {
                //跳過
            }
            else
            {
                //接收數據的處理
                this.BeginInvoke(new Action(() => {
                //異步處理,不影響其他的進程,關閉串口也不會出現錯誤
                }));
            {
        }
自定義串口通訊類的實現

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