Qt 串口发送接收数据(拆包处理)

.h文件

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QDebug>  
#include <QQueue>
#include <QTimer>
#include <QtSerialPort/QSerialPort>  
#include <QtSerialPort/QSerialPortInfo>  
#include "ConfigFileXiaoNiao.h"
/************************************************************************/
/* 串口通道,向转发客户端发送                                                                     */
/************************************************************************/

class MsgSendBySerialPortPass : public QObject
{
    Q_OBJECT

public:
    MsgSendBySerialPortPass(const SERIALPASSLIST&);
    MsgSendBySerialPortPass(QObject * ptr = NULL);
    void initPass();
    static MsgSendBySerialPortPass *GetInstance();
    ~MsgSendBySerialPortPass();
    void setSerialInfo(SERIALPASSLIST);
    void manageRecvMsg(QByteArray msg);//指令处理
    void callBackSendData(QByteArray strData);
    void sendMsgToTarget(QByteArray);//往目标发送指令
    QString getPassID() { return m_passId; }//获取通道ID

private slots:
    void slotSengDealMsg(QByteArray);//发送处理数据
    void slotRecvData();//接收指令
    void startTimers();
signals:
    void sigUpdateWidget(QString);
private:
    QSerialPort *serial;//串口通信
    QString m_passId;//通道ID
    int iBagNum;//包个数
    QQueue<QByteArray> m_MessageQueue;//控制命令消息队列
    QTimer *timer;

}; 

#endif // MAINWINDOW_H
 

.cpp文件

#include "MsgSendBySerialPortPass.h"
#include <windows.h>
MsgSendBySerialPortPass::MsgSendBySerialPortPass(const SERIALPASSLIST& info)
{
     
}

MsgSendBySerialPortPass::MsgSendBySerialPortPass(QObject * ptr /*= NULL*/)
{

}
void MsgSendBySerialPortPass::initPass()
{
    timer = new QTimer(this);
    timer->setTimerType(Qt::PreciseTimer);
    connect(timer, SIGNAL(timeout()), this, SLOT(startTimers()));
    timer->start(150);
    SERIALPASSLIST serialInfo = ConfigFile::GetInstance()->getSerialPass();//读取串口配置信息
    setSerialInfo(serialInfo);
}
MsgSendBySerialPortPass *MsgSendBySerialPortPass::GetInstance()
{
    static MsgSendBySerialPortPass* pInstance = NULL;
    if (pInstance == NULL)
    {
        pInstance = new MsgSendBySerialPortPass();
    }
    return pInstance;
}
MsgSendBySerialPortPass::~MsgSendBySerialPortPass()
{
    if (serial->isOpen())
    {
        serial->close();
    }
    delete serial;
}

void MsgSendBySerialPortPass::setSerialInfo(SERIALPASSLIST info)
{
    serial = new QSerialPort;
    //设置串口名  
    serial->setPortName(info.passName);
    //打开串口  
    bool bopen = serial->open(QIODevice::ReadWrite);
    if (!bopen)
    {
        //串口打开失败
        return;
    }
    //设置波特率  
    serial->setBaudRate(info.passBaud.toInt());
    //设置数据位数  
    if (info.passData == "5")
    {
        serial->setDataBits(QSerialPort::Data5);
    }
    else if (info.passData == "6")
    {
        serial->setDataBits(QSerialPort::Data6);
    }
    else if (info.passData == "6")
    {
        serial->setDataBits(QSerialPort::Data7);
    }
    else
    {
        serial->setDataBits(QSerialPort::Data8);
    }

    //设置奇偶校验  
    if (info.passParity == "None")
    {
        serial->setParity(QSerialPort::NoParity);
    }
    //设置停止位  
    if (info.passStop == "1")
    {
        serial->setStopBits(QSerialPort::OneStop);
    }
    else if (info.passStop == "2")
    {
        serial->setStopBits(QSerialPort::TwoStop);
    }
    //设置流控制  
    serial->setFlowControl(QSerialPort::NoFlowControl);
    //连接信号槽  
    connect(serial, &QSerialPort::readyRead, this, &MsgSendBySerialPortPass::slotRecvData);
}

void MsgSendBySerialPortPass::manageRecvMsg(QByteArray msg)
{
    if (msg.size() > 4096)
    {
        callBackSendData(msg);
    }
    else
    {
        sendMsgToTarget(msg);
    }
}
void MsgSendBySerialPortPass::callBackSendData(QByteArray strData)
{
    QByteArray msg = strData.left(4096);
    sendMsgToTarget(msg);

    //延时发送,防止丢包
    QByteArray rightdata = strData.remove(0,4096);
    if (rightdata.size() > 4096)
    {
        callBackSendData(rightdata);
    }
    else
    {
        sendMsgToTarget(rightdata);
    }
}

void MsgSendBySerialPortPass::sendMsgToTarget(QByteArray array)
{
    serial->write(array,array.length());
    serial->flush();
}

//发送数据  
void MsgSendBySerialPortPass::slotSengDealMsg(QByteArray array)
{
    if (m_MessageQueue.size() < 10)
    {
        m_MessageQueue.enqueue(array);
    }
}
//读取接收到的数据  
void MsgSendBySerialPortPass::slotRecvData()
{
    QByteArray buf;
    buf = serial->readAll();
    if (!buf.isEmpty())
    {
        QString str = QString::fromLocal8Bit(buf);
        sigUpdateWidget(str);
    }
    buf.clear();
}

void MsgSendBySerialPortPass::startTimers()
{
    if (m_MessageQueue.size()>0)
    {
        QByteArray array = m_MessageQueue.dequeue();
        manageRecvMsg(array);
    }
}
 

Qt 中,可以使用 `QSerialPort` 类来发送和接收串口数据。下面是一个简单的例子: ```cpp #include <QtSerialPort/QSerialPort> #include <QtSerialPort/QSerialPortInfo> // 打开串口,设置波特率、数据位、校验位、停止位等参数 QSerialPort serial; serial.setPortName("COM1"); serial.setBaudRate(QSerialPort::Baud9600); serial.setDataBits(QSerialPort::Data8); serial.setParity(QSerialPort::NoParity); serial.setStopBits(QSerialPort::OneStop); if (serial.open(QIODevice::ReadWrite)) { // 读取串口数据 connect(&serial, &QSerialPort::readyRead, [=]() { QByteArray data = serial.readAll(); // 处理接收到的数据 }); // 发送串口数据 QByteArray data = "Hello, world!"; serial.write(data); } ``` 在上面的例子中,首先创建了一个 `QSerialPort` 对象,并设置了串口参数。然后使用 `open` 函数打开串口。如果打开成功,则会建立信号与槽连接,当串口收到数据时,就会触发 `QSerialPort::readyRead` 信号,然后使用 `readAll` 函数读取接收到的数据,并进行处理。最后使用 `write` 函数发送数据。 需要注意的是,串口通信是一种异步通信方式,因此你需要在应用程序的事件循环中处理串口数据。如果你使用的是 Qt 的 GUI 应用程序,则不需要担心这个问题,因为 Qt 的事件循环会自动处理。但如果你使用的是非 GUI 应用程序,则需要手动处理事件循环,例如可以使用 `QCoreApplication::processEvents()` 函数来处理事件循环。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值