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

QT Creator读取STM32数据时自动拆分字符串的原因排查

串口接收数据拆分问题的解决方案

问题原因

串口通信属于字节流传输,底层不会保证一次发送的数据能被一次性完整接收。哪怕STM32一次性发送完所有内容,QT的readAll()也只能读取到当前串口缓冲区中已有的部分字节,剩余数据会触发下一次readyRead信号。

你的QT代码存在两个关键问题:

  • 每次接收数据就调用textEdit->clear(),然后用当前收到的片段覆盖显示,导致只保留最后一次收到的部分内容
  • 没有对接收的数据进行缓存和分帧处理,无法拼接拆分的数据包

解决方案

1. 修改QT代码,添加缓存与分帧逻辑

首先在MainWindow类中添加一个成员变量用于缓存未处理的数据:

// 在mainwindow.h的private区域添加
QByteArray m_receivedBuffer;

然后修改readData函数,改为缓存数据并按换行符(需要STM32配合添加)分割完整帧:

void MainWindow::readData()
{
    QByteArray newData = COMPORT->readAll();
    qDebug() << "Received Data Size:" << newData.size();
    
    // 将新收到的数据追加到缓存
    m_receivedBuffer.append(newData);

    // 循环处理所有完整的行(以换行符为结束标志)
    while (m_receivedBuffer.contains('\n')) {
        int newlinePos = m_receivedBuffer.indexOf('\n');
        // 提取完整的一行内容
        QString completeLine = QString::fromUtf8(m_receivedBuffer.left(newlinePos + 1)).trimmed();
        // 从缓存中移除已处理的部分
        m_receivedBuffer.remove(0, newlinePos + 1);

        // 方式1:追加显示所有历史数据
        ui->textEdit->append(completeLine);
        // 方式2:只显示最新的两行温度数据(替换原有内容)
        // QStringList lines = ui->textEdit->toPlainText().split('\n');
        // lines.append(completeLine);
        // if (lines.size() > 2) lines.removeFirst();
        // ui->textEdit->setText(lines.join('\n'));
        
        qDebug() << "Processed Line:" << completeLine;
    }
}

2. 优化STM32发送代码,添加结束符

在STM32发送数据时,给每一行内容添加换行符\n,方便QT识别完整的帧:

char buffer[16]; // 扩大缓冲区以容纳温度字符串
if (input == '1')
{
    // 测试字符串添加换行符
    sprintf(buffer, "Test\n");
    HAL_UART_Transmit(&huart2, (uint8_t*)buffer, strlen(buffer), 200);
    
    // 温度数据发送示例(每行加换行)
    // sprintf(buffer, "%.2f °C\n", temp1);
    // HAL_UART_Transmit(&huart2, (uint8_t*)buffer, strlen(buffer), 200);
    // sprintf(buffer, "%.2f °C\n", temp2);
    // HAL_UART_Transmit(&huart2, (uint8_t*)buffer, strlen(buffer), 200);
}

注意:原STM32代码中sprintf语句末尾缺少分号,需要补上。

关键说明

  • 缓存机制解决了数据拆分的问题,所有收到的字节会被暂存,直到出现结束符(换行)才会处理完整内容
  • 换行符作为帧结束标志是串口通信中最常用的分帧方式,你也可以根据需求自定义其他标志(如\r\n\r\n表示一组数据结束)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 15:07:22