qt 串口收发(完整版)

看过好几篇有关于串口收发的博客,通过学习,写了一个较完整功能的串口,包含16进制的发送、接受和换行插入(有些上位机的奇偶校验和停止位都写死了,实际使用中都需要用到,我加入了选择)
、新建工程后在mainwindow.ui界面隐藏菜单栏,并放入Containers中Tab Widget。再在工程新建文件类型widget,命名为serial,串口功能函数都写在这(这样如果想加入新功能再新建Widget窗口把功能函数写在相应cpp文件中即可)

在这里插入图片描述
接着在mainwindow.cpp中添加代码

    serial *interface1;
    interface1 = new serial();
    //移除原先的两个tab
    const int originalTabNum = ui->tabWidget->count();
    for(int i=0; i<originalTabNum; i++)
    {
        ui->tabWidget->removeTab(0);
    }
    //增加新的tabWidget窗口
    ui->tabWidget->addTab(interface1, "串口助手");

、qt5集成了串口的功能函数,为了调用,在工程pro文件中添加代码serialport(pro文件中 TARGET = serial 这行可以更改生成app的名字)

QT += core gui serialport

在serial.h头文件中添加代码

#include "QSerialPort" //串口访问 
#include "QSerialPortInfo" //串口端口信息访问 

在头文件public中添加代码

void Init();//串口初始化主函数中调用

在头文件private slots中添加代码

void serial_Read();//串口数据读取显示

在头文件private中添加代码

QSerialPort SerialPort;

三、搜索端口(打开上位机后插入串口设备时使用)

void serial::on_searchBtn_clicked()
{
    ui->portBox->clear();
    //通过QSerialPortInfo查找可用串口
    foreach(const QSerialPortInfo &info,QSerialPortInfo::availablePorts())
    {   //在portBox中显示可用串口
        ui->portBox->addItem(info.portName());
    }
}

四、串口初始化

void serial::Init()
{
    //读取串口信息
    foreach(const QSerialPortInfo &info, QSerialPortInfo::availablePorts())
    {
        // 自动读取串口号添加到端口portBox中
        QSerialPort serial;
        serial.setPort(info);
        if(serial.open(QIODevice::ReadWrite))
        {
            ui->portBox->addItem(info.portName());
            serial.close();
        }
    }
    QStringList baudList;   //波特率
    QStringList parityList; //校验位
    QStringList dataBitsList;   //数据位
    QStringList stopBitsList;   //停止位
    // 波特率    //波特率默认选择下拉第三项:9600
    baudList<<"1200"<<"2400"<<"4800"<<"9600"
           <<"14400"<<"19200"<<"38400"<<"56000"
          <<"57600"<<"115200";
    ui->rateBox->addItems(baudList);
    ui->rateBox->setCurrentIndex(3);
    // 校验      //校验默认选择无
    parityList<<"无"<<"奇"<<"偶";
    ui->checkBox->addItems(parityList);
    ui->checkBox->setCurrentIndex(0);
    // 数据位      //数据位默认选择8位
    dataBitsList<<"5"<<"6"<<"7"<<"8";
    ui->dataBox->addItems(dataBitsList);
    ui->dataBox->setCurrentIndex(3);
    // 停止位      //停止位默认选择1位
    stopBitsList<<"1"<<"2";
    ui->stopBox->addItems(stopBitsList);
    ui->stopBox->setCurrentIndex(0);
}

五、打开串口

void serial::on_openBtn_clicked()
{
    // 打开串口
    if(ui->openBtn->text() == "打开串口")
    {
        // 设置串口号
        SerialPort.setPortName(ui->portBox->currentText());
        // 打开串口
        if(SerialPort.open(QIODevice::ReadWrite))
        {
            // 设置波特率
            SerialPort.setBaudRate(ui->rateBox->currentText().toInt());
            //设置数据位数
            switch(ui->dataBox->currentIndex())
            {
            case 5: SerialPort.setDataBits(QSerialPort::Data5); break;
            case 6: SerialPort.setDataBits(QSerialPort::Data6); break;
            case 7: SerialPort.setDataBits(QSerialPort::Data7); break;
            case 8: SerialPort.setDataBits(QSerialPort::Data8); break;
            default: break;
            }
            // 设置校验位
            //SerialPort->setParity(QSerialPort::NoParity);
            //设置奇偶校验
            switch(ui->checkBox->currentIndex())
            {
            case 0: SerialPort.setParity(QSerialPort::NoParity); break;
            case 1: SerialPort.setParity(QSerialPort::OddParity); break;
            case 2: SerialPort.setParity(QSerialPort::EvenParity); break;
            default: break;
            }
            // 设置流控制
            SerialPort.setFlowControl(QSerialPort::NoFlowControl);
            //设置停止位
            switch(ui->stopBox->currentIndex())
            {
            case 1: SerialPort.setStopBits(QSerialPort::OneStop); break;
            case 2: SerialPort.setStopBits(QSerialPort::TwoStop); break;
            default: break;
            }
        }
        //打开串口
        else
        {
            QMessageBox::about(NULL, "提示", "串口无法打开\r\n不存在或已被占用");
            return;
        }
        ui->openBtn->setText("关闭串口");
        //下拉菜单控件使能
        ui->portBox->setEnabled(false);
        ui->rateBox->setEnabled(false);
        ui->dataBox->setEnabled(false);
        ui->checkBox->setEnabled(false);
        ui->stopBox->setEnabled(false);
        //搜索串口按键使能
        ui->searchBtn->setEnabled(false);
        //发送按键使能
        ui->sendBox->setEnabled(true);
    }
    // 关闭串口
    else
    {
        SerialPort.close();
        ui->openBtn->setText("打开串口");
        //下拉按键使能
        ui->portBox->setEnabled(true);
        ui->rateBox->setEnabled(true);
        ui->dataBox->setEnabled(true);
        ui->checkBox->setEnabled(true);
        ui->stopBox->setEnabled(true);
        //搜索串口按键使能
        ui->searchBtn->setEnabled(true);
        //发送按键使能
        ui->sendBox->setEnabled(false);
    }
}

六、接受显示代码

void serial::serial_Read()
{   QString buffer_1;
    //从缓冲区中读取数据
    QByteArray buffer = SerialPort.readAll();
    if(!buffer.isEmpty())//如果非空说明有数据接收
    {   //转换成16进制大写
        QString str=buffer.toHex().data();
        str=str.toUpper()
        //一个16进制占4位,8位为一字节,所以每两位16进制空一格
        for(int i=0;i<str.length();i+=2)
        {
               QString str_1 = str.mid (i,2);
               buffer_1 += str_1;
               buffer_1 += " ";
        }
    //读取之前显示数据
    QString receive = ui->receiveData->toPlainText();
    //清空显示
    ui->receiveData->clear();
    //重新显示
    if(a==0){
            receive += QString(buffer);
            ui->receiveData->append(receive);
            }//直接显示
    else    {
            receive += QString(buffer_1);
            ui->receiveData->append(receive);
            }//16进制显示
    }
    buffer.clear();
}

七、发送代码

void serial::on_sendBox_clicked()
{   QByteArray Data_1;
    //获取输入窗口sendData的数据
    QString Data = ui->sendData->toPlainText();
    if(c)       {Data+='\r';Data+='\n';}//插入换行
    if(b==0)    Data_1 = Data.toUtf8();//转换成utf8格式的字节流发送
    else        Data_1 = QByteArray::fromHex (Data.toLatin1().data());//按十六进制编码发送
    // 写入发送缓存区
    SerialPort.write(Data_1);
}

八、测试串口接法rx tx短接

在这里插入图片描述

九、效果显示

在这里插入图片描述

  • 96
    点赞
  • 724
    收藏
    觉得还不错? 一键收藏
  • 32
    评论
Qt串口接收超时是指在使用Qt库进行串口通信时,当接收数据的时间超过了设定的超时时间,系统无法获取到有效的数据。 在Qt中使用串口通信,可以通过使用QSerialPort类来实现。在接收数据时,可以设置一个超时时间,当超过这个时间还未接收到数据时,系统会触发接收超时信号,开发者可以根据需要进行相关处理。 导致Qt串口接收超时的原因可能有以下几种情况: 1. 串口通信速率设置过慢:如果串口通信的速率设置得过低,数据传输速度会变慢,导致在设置的超时时间内无法接收到足够的数据,从而触发接收超时。可以适当调整串口通信的速率,确保数据传输速度与设置的超时时间相匹配。 2. 接收数据缓冲区未及时读取:当缓冲区中存在大量未读取的数据时,系统无法继续接收新的数据,导致接收超时。可以使用QSerialPort的readAll函数来读取所有的数据,或者使用QSerialPort的waitForReadyRead函数来等待缓冲区有足够的数据可读取。 3. 设备故障或通信异常:如果串口设备或通信线路存在故障或异常,可能导致数据接收超时。可以检查串口设备、通信线路以及连接的外部设备是否正常工作,并确保数据的正确传输。 总结起来,解决Qt串口接收超时问题的方法是:适当调整串口通信的速率、及时读取数据缓冲区中的数据以及检查设备和通信线路的正常工作情况。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 32
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值