C# SerialPort 串口的基本使用


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);


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM