You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

串口通信数据多次接收问题:如何实现整行数据接收?

串口整行接收实现方案

你的问题出在默认的DataReceived事件会在有单个字节到达时就触发,导致逐字符接收。要实现整行接收,可通过以下两种方式解决:

方法一:利用SerialPort内置的换行符缓冲(推荐)

通过配置NewLine属性指定换行符,配合ReadLine()方法实现整行读取,同时修复跨线程UI访问问题:

// 初始化串口时设置换行符(根据发送端实际使用的换行符调整,比如"\n"或"\r\n")
serialport.NewLine = "\r\n";
serialport.ReadTimeout = 500; // 设置超时避免无限阻塞

serialport.DataReceived += (sender, e) =>
{
    try
    {
        string fullLine = serialport.ReadLine();
        // 跨线程更新UI必须用Invoke
        readRichTextBox.Invoke(new Action(() =>
        {
            readRichTextBox.AppendText($"{fullLine}\n");
        }));
    }
    catch (TimeoutException)
    {
        // 可选:处理超时情况,比如数据未完整到达
    }
};

方法二:自定义缓冲区拼接字符

适合需要自定义分隔符的场景,手动维护缓冲区直到检测到换行符:

private readonly StringBuilder _receiveBuffer = new StringBuilder();

serialport.DataReceived += (sender, e) =>
{
    string receivedData = serialport.ReadExisting();
    _receiveBuffer.Append(receivedData);

    // 循环检查缓冲区中的换行符(这里以"\n"为例)
    while (_receiveBuffer.ToString().Contains("\n"))
    {
        int newlinePos = _receiveBuffer.ToString().IndexOf("\n");
        // 提取整行并去除可能的回车符"\r"
        string fullLine = _receiveBuffer.ToString(0, newlinePos).TrimEnd('\r');
        _receiveBuffer.Remove(0, newlinePos + 1);

        // 跨线程更新UI
        readRichTextBox.Invoke(new Action(() =>
        {
            readRichTextBox.AppendText($"{fullLine}\n");
        }));
    }
};

关键注意事项

  • 必须确保发送端在每一行数据末尾添加对应的换行符(比如\n或\r\n),否则无法触发整行逻辑。
  • 所有UI操作必须通过Invoke/BeginInvoke执行,避免跨线程访问控件的异常。

内容的提问来源于stack exchange,提问作者na_sacc

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 20:31:01