廢話少說,直接上干貨。感興趣的讀者自己去研究代碼吧。請見諒。
using System; using System.Collections.Generic; using System.IO.Ports; using System.Linq; using System.Text; using System.Threading; namespace SerialPortCom { public class SerialPortComImplement { public delegate void RecEventHandler(byte[] queueByte); public event RecEventHandler DataReceivedEvent; private SerialPort serialPort; private List<byte> buffer = new List<byte>(4096); /// <summary> /// 初始化 /// </summary> /// <param name="portName">端口名稱</param> /// <param name="baudRate">波特率</param> /// <param name="dataBits">數據位</param> public SerialPortComImplement(string portName, int baudRate, int dataBits) { serialPort = new SerialPort(portName, baudRate, Parity.None); serialPort.DataBits = dataBits; serialPort.StopBits = StopBits.One; serialPort.ReadTimeout = 2000; serialPort.WriteBufferSize = 1024; serialPort.ReadBufferSize = 1024; serialPort.RtsEnable = true; serialPort.DtrEnable = true; serialPort.ReceivedBytesThreshold = 1; serialPort.DataReceived += new SerialDataReceivedEventHandler(serialPort_DataReceivedEventHandler); } /// <summary> /// 串口數據接收事件 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void serialPort_DataReceivedEventHandler(object sender, SerialDataReceivedEventArgs e) { try { byte[] readBuffer = null; int n = serialPort.BytesToRead; byte[] buf = new byte[n]; serialPort.Read(buf, 0, n); //1.緩存數據 buffer.AddRange(buf); //2.完整性判斷 while (buffer.Count >= 7) { //至少包含標頭(1字節),長度(1字節),校驗位(2字節)等等 //2.1 查找數據標記頭 if (buffer[0] == 0x00) //傳輸數據有幀頭,用於判斷 { int len = buffer[1]; if (buffer.Count < len + 2) { //數據未接收完整跳出循環 break; } readBuffer = new byte[len + 2]; //得到完整的數據,復制到readBuffer中 buffer.CopyTo(0, readBuffer, 0, len + 2); //從緩沖區中清除 buffer.RemoveRange(0, len + 2); //觸發外部處理接收消息事件 } } else //開始標記或版本號不正確時清除 { buffer.RemoveAt(0); } } } catch (Exception ex) { SerialPortLog.Error(ex, ""); } } /// <summary> /// 打開端口 /// </summary> public bool Open() { try { if (!serialPort.IsOpen) { serialPort.Open(); return true; } else { return true; } } catch (Exception ex) { SerialPortLog.Error(ex, ""); return false; } } /// <summary> /// 發送字節 /// </summary> /// <param name="writeBytes">要發送的字節</param> /// <returns></returns> public bool Write(byte[] writeBytes) { if (Open()) { try { serialPort.Write(writeBytes, 0, writeBytes.Length); string mergeStr = "發送:"; for (int j = 0; j < writeBytes.Length; j++) { mergeStr = mergeStr + writeBytes[j].ToString("x") + " "; } SerialPortLog.Info(mergeStr); return true; } catch (Exception ex) { SerialPortLog.Error(ex, ""); return false; } } return false; } /// <summary> /// 發送字符串 /// </summary> /// <param name="writestrs"></param> /// <returns></returns> public bool Write(string writeStrs) { if (Open()) { try { serialPort.Write(writeStrs); Thread.Sleep(100); return true; } catch { return false; } } return false; } /// <summary> /// 讀取數據 /// </summary> /// <param name="NumBytes">讀取的字節數</param> /// <returns></returns> public byte[] Read(int NumBytes) { byte[] inbuffer = null; if (serialPort.IsOpen && serialPort.BytesToRead > 0) { if (NumBytes > serialPort.BytesToRead) { NumBytes = serialPort.BytesToRead; } try { inbuffer = new byte[NumBytes]; int count = serialPort.Read(inbuffer, 0, NumBytes); } catch (TimeoutException timeoutEx) { //超時異常 SerialPortLog.Error(timeoutEx, ""); } } return inbuffer; } public byte[] Read() { return Read(serialPort.BytesToRead); } public string ReadLine() { try { if (serialPort.IsOpen && serialPort.BytesToRead > 0) { string s = serialPort.ReadExisting(); return serialPort.ReadLine(); } return null; } catch (TimeoutException timeoutEx) { SerialPortLog.Error(timeoutEx, ""); return timeoutEx.Message; } } /// <summary> /// 關閉串口 /// </summary> public void Close() { try { if (serialPort.IsOpen) { serialPort.Close(); } } catch (Exception ex) { SerialPortLog.Error(ex, ""); } } public bool IsOpen { get { return serialPort.IsOpen; } } } }
原文鏈接:
using System;
using System.Collections.Generic;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Threading;
namespace SerialPortCom
{
public class SerialPortComImplement
{
public delegate void RecEventHandler(byte[] queueByte);
public event RecEventHandler DataReceivedEvent;
private SerialPort serialPort;
private List<byte> buffer = new List<byte>(4096);
/// <summary>
/// 初始化
/// </summary>
/// <param name="portName">端口名稱</param>
/// <param name="baudRate">波特率</param>
/// <param name="dataBits">數據位</param>
public SerialPortComImplement(string portName, int baudRate, int dataBits)
{
serialPort = new SerialPort(portName, baudRate, Parity.None);
serialPort.DataBits = dataBits;
serialPort.StopBits = StopBits.One;
serialPort.ReadTimeout = 2000;
serialPort.WriteBufferSize = 1024;
serialPort.ReadBufferSize = 1024;
serialPort.RtsEnable = true;
serialPort.DtrEnable = true;
serialPort.ReceivedBytesThreshold = 1;
serialPort.DataReceived += new SerialDataReceivedEventHandler(serialPort_DataReceivedEventHandler);
}
/// <summary>
/// 串口數據接收事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void serialPort_DataReceivedEventHandler(object sender, SerialDataReceivedEventArgs e)
{
try
{
byte[] readBuffer = null;
int n = serialPort.BytesToRead;
byte[] buf = new byte[n];
serialPort.Read(buf, 0, n);
//1.緩存數據
buffer.AddRange(buf);
//2.完整性判斷
while (buffer.Count >= 7)
{
//至少包含標頭(1字節),長度(1字節),校驗位(2字節)等等
//2.1 查找數據標記頭
if (buffer[0] == 0x00) //傳輸數據有幀頭,用於判斷
{
int len = buffer[1];
if (buffer.Count < len + 2)
{
//數據未接收完整跳出循環
break;
}
readBuffer = new byte[len + 2];
//得到完整的數據,復制到readBuffer中
buffer.CopyTo(0, readBuffer, 0, len + 2);
//從緩沖區中清除
buffer.RemoveRange(0, len + 2);
//觸發外部處理接收消息事件
}
}
else //開始標記或版本號不正確時清除
{
buffer.RemoveAt(0);
}
}
}
catch (Exception ex)
{
SerialPortLog.Error(ex, "");
}
}
/// <summary>
/// 打開端口
/// </summary>
public bool Open()
{
try
{
if (!serialPort.IsOpen)
{
serialPort.Open();
return true;
}
else
{
return true;
}
}
catch (Exception ex)
{
SerialPortLog.Error(ex, "");
return false;
}
}
/// <summary>
/// 發送字節
/// </summary>
/// <param name="writeBytes">要發送的字節</param>
/// <returns></returns>
public bool Write(byte[] writeBytes)
{
if (Open())
{
try
{
serialPort.Write(writeBytes, 0, writeBytes.Length);
string mergeStr = "發送:";
for (int j = 0; j < writeBytes.Length; j++)
{
mergeStr = mergeStr + writeBytes[j].ToString("x") + " ";
}
SerialPortLog.Info(mergeStr);
return true;
}
catch (Exception ex)
{
SerialPortLog.Error(ex, "");
return false;
}
}
return false;
}
/// <summary>
/// 發送字符串
/// </summary>
/// <param name="writestrs"></param>
/// <returns></returns>
public bool Write(string writeStrs)
{
if (Open())
{
try
{
serialPort.Write(writeStrs);
Thread.Sleep(100);
return true;
}
catch
{
return false;
}
}
return false;
}
/// <summary>
/// 讀取數據
/// </summary>
/// <param name="NumBytes">讀取的字節數</param>
/// <returns></returns>
public byte[] Read(int NumBytes)
{
byte[] inbuffer = null;
if (serialPort.IsOpen && serialPort.BytesToRead > 0)
{
if (NumBytes > serialPort.BytesToRead)
{
NumBytes = serialPort.BytesToRead;
}
try
{
inbuffer = new byte[NumBytes];
int count = serialPort.Read(inbuffer, 0, NumBytes);
}
catch (TimeoutException timeoutEx)
{
//超時異常
SerialPortLog.Error(timeoutEx, "");
}
}
return inbuffer;
}
public byte[] Read()
{
return Read(serialPort.BytesToRead);
}
public string ReadLine()
{
try
{
if (serialPort.IsOpen && serialPort.BytesToRead > 0)
{
string s = serialPort.ReadExisting();
return serialPort.ReadLine();
}
return null;
}
catch (TimeoutException timeoutEx)
{
SerialPortLog.Error(timeoutEx, "");
return timeoutEx.Message;
}
}
/// <summary>
/// 關閉串口
/// </summary>
public void Close()
{
try
{
if (serialPort.IsOpen)
{
serialPort.Close();
}
}
catch (Exception ex)
{
SerialPortLog.Error(ex, "");
}
}
public bool IsOpen
{
get
{
return serialPort.IsOpen;
}
}
}
}
------------恢復內容開始------------
廢話少說,直接上干貨。感興趣的讀者自己去研究代碼吧。請見諒。
using System; using System.Collections.Generic; using System.IO.Ports; using System.Linq; using System.Text; using System.Threading; namespace SerialPortCom { public class SerialPortComImplement { public delegate void RecEventHandler(byte[] queueByte); public event RecEventHandler DataReceivedEvent; private SerialPort serialPort; private List<byte> buffer = new List<byte>(4096); /// <summary> /// 初始化 /// </summary> /// <param name="portName">端口名稱</param> /// <param name="baudRate">波特率</param> /// <param name="dataBits">數據位</param> public SerialPortComImplement(string portName, int baudRate, int dataBits) { serialPort = new SerialPort(portName, baudRate, Parity.None); serialPort.DataBits = dataBits; serialPort.StopBits = StopBits.One; serialPort.ReadTimeout = 2000; serialPort.WriteBufferSize = 1024; serialPort.ReadBufferSize = 1024; serialPort.RtsEnable = true; serialPort.DtrEnable = true; serialPort.ReceivedBytesThreshold = 1; serialPort.DataReceived += new SerialDataReceivedEventHandler(serialPort_DataReceivedEventHandler); } /// <summary> /// 串口數據接收事件 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void serialPort_DataReceivedEventHandler(object sender, SerialDataReceivedEventArgs e) { try { byte[] readBuffer = null; int n = serialPort.BytesToRead; byte[] buf = new byte[n]; serialPort.Read(buf, 0, n); //1.緩存數據 buffer.AddRange(buf); //2.完整性判斷 while (buffer.Count >= 7) { //至少包含標頭(1字節),長度(1字節),校驗位(2字節)等等 //2.1 查找數據標記頭 if (buffer[0] == 0x00) //傳輸數據有幀頭,用於判斷 { int len = buffer[1]; if (buffer.Count < len + 2) { //數據未接收完整跳出循環 break; } readBuffer = new byte[len + 2]; //得到完整的數據,復制到readBuffer中 buffer.CopyTo(0, readBuffer, 0, len + 2); //從緩沖區中清除 buffer.RemoveRange(0, len + 2); //觸發外部處理接收消息事件 } } else //開始標記或版本號不正確時清除 { buffer.RemoveAt(0); } } } catch (Exception ex) { SerialPortLog.Error(ex, ""); } } /// <summary> /// 打開端口 /// </summary> public bool Open() { try { if (!serialPort.IsOpen) { serialPort.Open(); return true; } else { return true; } } catch (Exception ex) { SerialPortLog.Error(ex, ""); return false; } } /// <summary> /// 發送字節 /// </summary> /// <param name="writeBytes">要發送的字節</param> /// <returns></returns> public bool Write(byte[] writeBytes) { if (Open()) { try { serialPort.Write(writeBytes, 0, writeBytes.Length); string mergeStr = "發送:"; for (int j = 0; j < writeBytes.Length; j++) { mergeStr = mergeStr + writeBytes[j].ToString("x") + " "; } SerialPortLog.Info(mergeStr); return true; } catch (Exception ex) { SerialPortLog.Error(ex, ""); return false; } } return false; } /// <summary> /// 發送字符串 /// </summary> /// <param name="writestrs"></param> /// <returns></returns> public bool Write(string writeStrs) { if (Open()) { try { serialPort.Write(writeStrs); Thread.Sleep(100); return true; } catch { return false; } } return false; } /// <summary> /// 讀取數據 /// </summary> /// <param name="NumBytes">讀取的字節數</param> /// <returns></returns> public byte[] Read(int NumBytes) { byte[] inbuffer = null; if (serialPort.IsOpen && serialPort.BytesToRead > 0) { if (NumBytes > serialPort.BytesToRead) { NumBytes = serialPort.BytesToRead; } try { inbuffer = new byte[NumBytes]; int count = serialPort.Read(inbuffer, 0, NumBytes); } catch (TimeoutException timeoutEx) { //超時異常 SerialPortLog.Error(timeoutEx, ""); } } return inbuffer; } public byte[] Read() { return Read(serialPort.BytesToRead); } public string ReadLine() { try { if (serialPort.IsOpen && serialPort.BytesToRead > 0) { string s = serialPort.ReadExisting(); return serialPort.ReadLine(); } return null; } catch (TimeoutException timeoutEx) { SerialPortLog.Error(timeoutEx, ""); return timeoutEx.Message; } } /// <summary> /// 關閉串口 /// </summary> public void Close() { try { if (serialPort.IsOpen) { serialPort.Close(); } } catch (Exception ex) { SerialPortLog.Error(ex, ""); } } public bool IsOpen { get { return serialPort.IsOpen; } } } }