SerialPort 是 C# 的串口類。
先創建一個串口實例對象:
_serialPort = new SerialPort();
基本的串口參數屬性
BaudRate // 波特率
Parity // 校驗位:奇校驗,偶校驗,無校驗
DataBits // 數據位:6,7,8
StopBits // 停止位:StopBits.One StopBits.Two
打開關閉串口
獲取可用的端口名稱:
public string[] PortNames
{
get { return System.IO.Ports.SerialPort.GetPortNames(); }
}
通過 GetPortNames()
靜態函數獲取。
打開串口:
_serialPort.PortName; // 先賦值哪一個端口
_serialPort.Open(); // 打開
多次打開同一個端口,會拋出異常,需要做好異常處理。
關閉串口:
_serialPort.Close();
獲取串口打開狀態:
_serialPort.IsOpen;
串口發送數據
_serialPort.Write(byteData, 0, byteData.Length);//發送數據(數據,從0開始,結束位置)
public void Write(byte[] buffer, int offset, int count); // 函數原型,可以看下重載
串口接受數據
需要先綁定串口監聽事件:
// 綁定數據接受監聽事件
_serialPort.DataReceived += SerialPort_DataReceived;
private void SerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
// 數據接收后需要干的活
}
/// <summary>
/// 串口接收數據
/// </summary>
public byte[] ReceiveData()
{
//定義一個接收數組,獲取接收緩沖區數據的字節數
byte[] byteData = new byte[_serialPort.BytesToRead];
//讀取數據
this.serialPort.Read(byteData, 0, _serialPort.BytesToRead);
return byteData;
}
另一種方式讀取,循環讀取 BytesToRead:
_serialPort.Write(byteData, 0, byteData.Length); // 先發送數據
// ...
// 循環讀取,等待返回的數據
while(true)
{
if (_port.BytesToRead > 0)
{
_recivedData.Add((byte)_port.ReadByte()); // 一個字節一個字節的讀取
}
// 這里可以對字節計數,如果多少字節之后,然后 Break;
// 也可以,做一個超時,比如 1s 鍾之后,還沒調出,直接 Break.
}
上面這種方式可以避免,有些硬件的數據不是一次性返回的,讀取數據不完整的情況。
串口通信中的一些數據轉換和驗證
判斷十六進制字符串hex是否正確:
private bool IsIIlegalHex(string hex)
{
return System.Text.RegularExpressions.Regex.IsMatch(hex, @"([^A-Fa-f0-9]|\s+?)+");
}
去除十六進制字符串的中間間隔符,十六進制字符串轉化成字節數組:
/// <summary>
/// 去掉16進制字符串中的隔離符【 如:" ", "0x", "0X"】
/// </summary>
/// <param name="inString">需要轉換的字符串數據</param>
/// <returns></returns>
private string DeleteSplitString(string inString)
{
string outString = string.Empty;
string[] delArray = { " ", "0x", "0X" };
if (inString.Contains(" ") || inString.Contains("0x") || inString.Contains("0X"))//存在隔離符
{
string[] str = inString.Split(delArray,
System.StringSplitOptions.RemoveEmptyEntries);//以隔離符進行轉換數組,去掉隔離符,去掉空格。
for (int i = 0; i < str.Length; i++)
{
outString += str[i].ToString();
}
return outString;
}
else//不存在隔離符就直接返回
{
return inString;
}
}
/// <summary>
/// 把16進制字符串轉換成byte[]
/// </summary>
/// <param name="inString"></param>
/// <returns></returns>
public byte[] From16ToBtyes(string inString)
{
inString = DeleteSplitString(inString);//去掉16進制中的隔離符
byte[] stringByte = new byte[inString.Length / 2];
for (int a = 0, b = 0; a < inString.Length; a = a + 2, b++)
{
try
{
string str = inString.Substring(a, 2);
stringByte[b] = (byte)Convert.ToInt16(str, 16);
}
catch (Exception ex)
{
throw new Exception("輸入的數據不是純16進制數! 參考錯誤信息:" + ex.Message);
}
}
return stringByte;
}
字符串轉字節數組:
string outString = "";
byte[] bytes = Encoding.Default.GetBytes(inString);