Qt 和 MCU 的串口通讯(完整帧)

前言:

        最近一段时间在做有关串口通讯的Qt项目,其中与MCU STM32那部分的通讯比较令人头疼,因为MCU处理的是HEX16进制数,而Qt应用更多的倾向于对字符串的处理,经过这段时间的痛苦而又煎熬的摸索,也算是有所新的认识。在这中秋佳节即将来临之际,也得空写点关于这方面的心得,算是一个记录笔记吧。

介绍:

项目情况

MCU STM32控制端:

几个控制按键挂在MCU上,随着按键的动作相应地发出指定数据帧,通过串口RX/TX传给ARM板端,Qt应用作出相应动作。

ARM Qt显示应用端:

需要Qt的应用能够接受到MCU 发出的数据帧,并且解析出有用的数据,进行相应动作。

MCU那边的串口通讯我就不说了,应该比较常见。我着重讲一下Qt这边怎么处理一个完整的数据帧。

相关知识点

一个完整的数据帧,包括帧头、标识符、数据长度、数据块、校验和帧尾等,比如:

帧头 各种标识 ... 数据长度 数据块 校验 帧尾
FF EE ... 12 数据长度个字节 ** AA

串口通讯中,以商议好的数据帧形式发送和接受数据,能够有效的避免数据接受不完整,接受错误。使用指定形式的数据帧是一种有效、准确的通讯方式。

校验

数据在传输过程中,可能会存在数据出错的情况。为了保证数据传输的正确性,因此会采取一些方法来判断数据是否正确,或者在数据出错的时候及时发现进行改正。常用的几种数据校验方式有奇偶校验、CRC校验、LRC校验、格雷码校验、和校验、异或校验等。

一般串口通讯中常用到的校验有CRC32、CRC16、和校验或是异或校验等。如果大家有兴趣可以多找一找这方面的资料看看,我在这里就不多做赘述。讲的比较详细:

https://blog.csdn.net/zhengqijun_/article/details/53150749

划重点————————————————————————————————————————————————————

Qt 解析完整数据帧

MCU发出的是16进制数据帧,Qt善于处理QString的字符串。

我先说一下Qt 解析部分大概思路:1. 串口读取为二进制字节组---QByteArray;2. 将QByteArray 写入数据流QDataStream,而后从中按一个一个字节读取出,直到结束;3. 按数据帧协议处理一个字节一个字节,环环相扣,引入状态机机制,解析完整帧。

直接上代码。Talk is cheap, show me the code.

头文件声明:

    QString buffer;//串口接受数据缓冲区
    QString bufferdatalen;//数据长度两字节字符串缓存
    QString frameData;//
    uint8_t checkSum, SendBuf[200];//校验异或和
    ushort TxNum;

    int num;
    int state_machine;//协议解析状态机
    int lencnt, datalen;
    bool stopped;
    bool ok;

 

CPP文件解析函数一览:

//读取串口数据帧并处理
void SerialPortA::readMyComA(QByteArray temp)
{
    QDataStream out(&temp, QIODevice::ReadWrite);
//    qDebug()<<"MyComA temp hex"<>outChar;
        QString byte = QString("%1").arg(outChar&0xFF, 2, 16, QLatin1Char('0'));
//        qDebug()<<"byte"<> outchar;//每字节填充一次,直到结束
                SendBuf[TxNum] = (uint8_t)(outchar & 0xff);
                TxNum++;
            }
            checkSum = (uint8_t)(myAlgorithm->Sum_Calculate(SendBuf, TxNum));//求帧头以外所有数据的校验和
            QString strSum = QString("%1").arg(checkSum&0xFF, 2, 16, QLatin1Char('0'));
            strSum = strSum.toUpper();
            byte = byte.toUpper();

//            qDebug()<<"Check SUM is :"<

校验计算函数

uint8_t Algorithm::Sum_Calculate(uint8_t *puchMsg, uint16_t usDataLen)
{
     uint8_t CRCValue=0;
     uint16_t i=0;
     for ( i=0; i

解析部分,按照自身协商的数据帧,实际情况进行处理分析。大概的思路已经给出。

在此,也感特别谢@yuxiangs的转发博客给予的思路:

https://blog.csdn.net/yilongdashi/article/details/80449315#comments

 

以上仅是个人对qt中串口使用的大概了解,各位有补充的欢迎留言指导及斧正,谢谢大家,预祝大家中秋佳节快乐。

你可能感兴趣的:(qt笔记,qt,STM32)