前面寫串口通信是有界面的,後面的項目感受串口通信只是輔助的做用,應該專門寫一個不可視的類來作,這樣的好處是通信模塊是獨立的,要用的時候直接引用就好了。數組
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;//接收數據事件ide
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();this
//構造函數
public SerialPortCommunication()
{
//
//sp.sp_DataReceived += OnReceiveMsg;
}spa
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;
}orm
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(() => {
//異步處理,不影響其餘的進程,關閉串口也不會出現錯誤
}));
{
}