QT-创建串口-处理数据-计算串口数据校验和-QByteArray校验和及数据求和

        在QT中,当我们编写的程序需要和硬件通讯时,一般常用串口的方式处理数据,别管是RS232还是RS485,对QT来说都是一样的,需要建立QSerialPort对象,至少需要包含#include <QtSerialPort/QtSerialPort>,然后建立对象,设置对象参数。

     
     m_serial = new QSerialPort();                              //m_serial 是对象名称,需要New出来
     m_serial->setPortName(portName);                           //设置端口号,比如com3
     m_serial->setBaudRate(baudRate);                           //设置波特率,常用9600/19200/38400/115200这几种,现在设备越来越先进,默认用115200的越来越多
     m_serial->setParity(QSerialPort::NoParity);                //设置奇偶校验,一般不设,用QSerialPort::NoParity参数
     m_serial->setDataBits(QSerialPort::Data8);                 //数据位5、6、7、8,一般用Data8
     m_serial->setStopBits(QSerialPort::OneStop);               //停止位,常用1位,也有1.5和2位的,比较少
     m_serial->setFlowControl(QSerialPort::NoFlowControl);      //没有流控
     m_serial->setReadBufferSize(1024);                         //设置一个最大缓存1024字节,其实如果你数据处理的过来,设置成你最大数据包的两三倍就够了

        参数设置完成后,需要打开串口,这样才算完成串口的创建。

m_serial->open(QSerialPort::ReadWrite)  // bool QSerialPort::open(QIODevice::OpenMode mode)

        可以根据open函数的返回值是true或者false判断端口建否建立成功,如果系统含有该串口并且该串口没有被其他程序绑定,那么一般会绑定成功的。

        QT接收串口数据可以存在char数组或者QByteArray里边,接收数据一般用QSerialPort::readyRead信号,然后绑定槽函数,利用m_serial->readAll()接收数据,readAll函数默认返回的是QByteArray类型,所以常用QByteArray接收和处理串口传过来的数据,

connect(m_serial,&QSerialPort::readyRead,this,&MainSerial::receiveData);
void MySerial::receiveData()
{
    QByteArray data;
    data = m_serial->readAll();
    //然后根据项目需要,处理data数据
}

         然后进入正题,如果是公司开发的单片机程序,在数据传输稳定且数据量不是太大的情况下,好多都是用和校验的方式校验数据的完整性,虽然没有CRC16那么严格,但是也算比较简单好用的一种校验方式,下面直接上代码,说一下串口发过来的QByteArray数据,如何进行和校验确认数据完整性:

bool sumCheck(QByteArray data)
{
    int sum = 0;
    for(int i = 0; i < data.size()-1; i++)
    {
        sum += data.at(i);
    }
    quint8 lastSum = sum;
    return (lastSum == (quint8)(data.at(data.size()-1))) ? true : false;
}

        发送过来的数据,存到一个QByteArray之后,可以传入上边的函数进行和校验,返回值为true,则校验成功,false为检验失败,数据不是完整数据,一般校验失败后数据废弃不用。

        这个方法是QByteArray最后一位数据前边的所有数据for循环加和,求得的和sum为4位的int类型,而校验和一般为1位数据,所以一般只取int的最低位,然后求得的和lastSum和data的最后一位数据比较大小,两个数值相同返回true,表明校验成功。

        同样,在我们给单片机通过串口发送消息时,我们也要把数据的最后一位加上校验和,然后发送出去,校验和计算和上边很像,也是通过一个for循环计算出QByteArray所有数据的和,和校验通常大于255,我们只取最后一位数据,直接把int赋值给quint8就行了,参考下边的代码:

quint8 addSum(QByteArray data)
{
    int i_sum = 0;
    for(int i = 0; i < data.size()-1; i++)
    {
        i_sum += data.at(i);
    }
    quint8 b_sum = i_sum;
    return b_sum;
}

        返回值直接是一个一位的quint8类型数据, 可以用memcpy函数复制到待发送数据QByteArray的最后一位上边去,然后直接用建立好的串口对象write出去就算完成串口数据发送了。

Qt中,你可以使用QTcpSocket或QUdpSocket来处理TCP或UDP网络通信。以下是一个简单的例子,展示了如何创建一个基础的网络通信类,用于接收和发送`QByteArray`数据: ```cpp #include <QObject> #include <QHostAddress> #include <QTcpSocket> #include <QByteArray> class NetworkCommunicator : public QObject { Q_OBJECT public: explicit NetworkCommunicator(QHostAddress address, quint16 port, QObject *parent = nullptr) : QObject(parent), socket(address, Qt::DirectConnection, port) { connect(&socket, &QTcpSocket::connected, this, &NetworkCommunicator::connected); connect(&socket, &QTcpSocket::readyRead, this, &NetworkCommunicator::readData); connect(&socket, &QTcpSocket::disconnected, this, &NetworkCommunicator::disconnected); } ~NetworkCommunicator() { if (isConnected()) disconnectFromHost(); } void sendData(QByteArray data) { if (!socket.isOpen()) { qDebug() << "Socket is not open. Opening..."; socket.open(QIODevice::WriteOnly); if (!socket.waitForConnected(5000)) { qWarning() << "Failed to connect"; return; } } qint64 bytesWritten = socket.write(data); if (bytesWritten == -1) { qWarning() << "Failed to write data"; } else { qDebug() << "Sent" << bytesWritten << "bytes"; } } QByteArray receiveData() { if (!socket.bytesAvailable()) { qDebug() << "No data available"; return QByteArray(); } QByteArray receivedData; qint64 bytesRead = socket.read(receivedData); if (bytesRead > 0) { qDebug() << "Received" << bytesRead << "bytes"; return receivedData; } else { qWarning() << "Failed to read data"; } return QByteArray(); } signals: void connectionEstablished(); void dataReceived(QByteArray data); private slots: void connected() { emit connectionEstablished(); } void disconnected() { emit dataReceived(QByteArray()); } private: QTcpSocket socket; bool isConnected() const { return socket.state() == SocketState::Open; } // Disconnection method void disconnectFromHost() { socket.disconnectFromHost(); } }; ``` 这个`NetworkCommunicator`类接受一个IP地址、端口作为参数,并维护一个`QTcpSocket`实例。它提供了`sendData`和`receiveData`方法用于传输数据。当连接建立时,会发出`connectionEstablished`信号;当接收到数据时,会发出`dataReceived`信号。 要使用这个类,你需要创建一个实例并连接到所需的服务器: ```cpp NetworkCommunicator communicator("127.0.0.1", 12345); connect(&communicator, &NetworkCommunicator::dataReceived, yourReceiverObject, &YourReceiverClass::handleDataReceived); ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

胖墩墩的小火苗子

创作不易,谢谢鼓励!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值