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);
posted @   double64  阅读(4715)  评论(1编辑  收藏  举报
编辑推荐:
· [.NET]调用本地 Deepseek 模型
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· .NET Core 托管堆内存泄露/CPU异常的常见思路
· PostgreSQL 和 SQL Server 在统计信息维护中的关键差异
· C++代码改造为UTF-8编码问题的总结
阅读排行:
· 【.NET】调用本地 Deepseek 模型
· CSnakes vs Python.NET:高效嵌入与灵活互通的跨语言方案对比
· DeepSeek “源神”启动!「GitHub 热点速览」
· 我与微信审核的“相爱相杀”看个人小程序副业
· Plotly.NET 一个为 .NET 打造的强大开源交互式图表库
点击右上角即可分享
微信分享提示