使用QT实现串口收发和波形显示

功能介绍

HI,大家好,今天给大家分享一个最近做的小项目,一个使用QT实现类似串口调试助手功能的作品。不过相对于常见的串口调试助手,增加了波形显示的功能。波形显示部分借鉴了这篇博客链接: link.非常感谢这位大佬,写得很详细。还有也借鉴了一些其他博主的经验,非常感谢。

代码实现

首先在工程文件.pro中添加serialport和charts,就可以使用QT集成的串口和图表绘制的功能函数

     QT += core gui serialport charts

接着对UI界面进行一个简单的设计
UI界面设计
在Widget构造函数中添加以下代码`

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

    QStringList serialNamePort;
    serialPort = new QSerialPort(this);

    connect(serialPort,SIGNAL(readyRead()),this,SLOT(serilaPortReadyRead_Slot()));   /*手动关联读取函数*/

    /*获取存在的串口名*/
    foreach (const QSerialPortInfo &info,QSerialPortInfo::availablePorts()) {
        serialNamePort<<info.portName();
    }
    ui->seialCb->addItems(serialNamePort);

    /*关联定时器和绘图函数*/
    timer = new QTimer(this);
    connect(timer , SIGNAL(timeout()) , this , SLOT(DrawLine()));
}

串口初始化以及绘图初始化函数的调用(包括了定时器初始化,定时器用于绘制数据的动态更新)

/*串口初始化配置*/
void Widget::on_openBT_clicked()
{
    QSerialPort::BaudRate baudRate;
    QSerialPort::DataBits dataBits;
    QSerialPort::StopBits stopBits;
    QSerialPort::Parity checkBits;

    /*波特率*/
    if(ui->baundrateCb->currentText() == "9600")
    {
        baudRate = QSerialPort::Baud9600;
    }
    else if(ui->baundrateCb->currentText() == "115200")
    {
        baudRate = QSerialPort::Baud115200;
    }

    /*数据位*/
    if(ui->dataCb->currentText() == "6")
    {
        dataBits = QSerialPort::Data6;
    }
   else if(ui->dataCb->currentText() == "7")
    {
        dataBits = QSerialPort::Data7;
    }
    else if(ui->dataCb->currentText() == "8")
    {
        dataBits = QSerialPort::Data8;
    }

    /*停止位*/
    if(ui->stopCb->currentText() == "1")
    {
        stopBits = QSerialPort::OneStop;
    }
    else if(ui->stopCb->currentText() == "1.5")
    {
        stopBits = QSerialPort::OneAndHalfStop;
    }
    else if(ui->stopCb->currentText() == "2")
    {
        stopBits = QSerialPort::TwoStop;
    }

    /*校验位*/
    if(ui->checkCb->currentText() == "none")
    {
        checkBits = QSerialPort::NoParity;
    }
    
    //设置
    serialPort->setPortName(ui->seialCb->currentText());
    serialPort->setBaudRate(baudRate);
    serialPort->setDataBits(dataBits);
    serialPort->setStopBits(stopBits);
    serialPort->setParity(checkBits);

    if(serialPort->open(QIODevice::ReadWrite) == true)
    {
        QMessageBox::information(this,"提示","成功");
    }
    else
    {
        QMessageBox::critical(this,"提示","失败");
    }

    //画图初始化
    initDraw();
    timer->start();  //初始化定时器
    timer->setInterval(1000);
}

画图初始化函数

/*画图初始化*/
void Widget::initDraw()
{
    QPen peny(Qt::darkRed , 3 , Qt::SolidLine , Qt::RoundCap , Qt::RoundJoin);
    chart = new QChart();
    series = new QSplineSeries();
    axisX = new QDateTimeAxis();
    axisY = new QValueAxis();

    chart->legend()->hide();        //隐藏图例
    chart->addSeries(series);       //将线添加到chart中
    axisX->setTickCount(10);   //设置x坐标轴格数
    axisY->setTickCount(5);     //设置y坐标轴格数

    axisX->setFormat("hh:mm:ss");       //设置显示格式
    axisY->setMin(0);       //设置y轴范围
    axisY->setMax(1000);
    axisX->setTitleText("T");    //设置x轴名称
    axisY->setLinePenColor(QColor(Qt::darkBlue));       //设置坐标轴颜色样式
    axisY->setGridLineColor(QColor(Qt::darkBlue));
    //axisY->setGridLineColor(QColor(Qt::darkBlue));
    axisY->setGridLineVisible(false);        //设置y轴网格不显示
    axisY->setLinePen(peny);
    axisX->setLinePen(peny);

    chart->addAxis(axisX , Qt::AlignBottom);    //设置坐标轴位于chart中的位置
    chart->addAxis(axisY , Qt::AlignLeft);

    series->attachAxis(axisX);          //把数据添加到坐标轴上
    series->attachAxis(axisY);

    axisY->setTitleText("Y");

    //把chart显示到窗口上
    ui->widget->setChart(chart);
    ui->widget->setRenderHint(QPainter::Antialiasing);   //设置抗锯尺

}

串口接收槽函数,下位机发送格式需为 abc数据\r\n 才能正常接收

/*串口接收槽函数*/
void Widget::serilaPortReadyRead_Slot()
{
    QString num;
    QString recv_buf;  //接收缓存
    QString buf;
    int recv_pos = 0;  //移位
    
    recv_buf = QString(serialPort->readAll());  //接收数据
    buf = recv_buf.mid(4);
    if( recv_buf.indexOf("abc") != -1)   //判断是否有abc
    {  
        num=recv_buf.mid(recv_pos,recv_buf.length()); //截取出字符大小
        recv_pos=num.indexOf("\r\n");   //找出数据尾部标志的recv_pos值
        num=num.mid(3,recv_pos-3);      //截取数据
        number=num.toInt();  //将char型数据转为int型数据
        qDebug()<<number;
    }
}

串口发送槽函数,发送格式为字符发送+发送新行

/*串口发送槽函数*/
void Widget::on_sendBt_clicked()
{
    QByteArray Data_1 = ui->sendEdit->text().toUtf8();
    Data_1.append("\r\n");
    serialPort->write(Data_1);

}

画图函数

/*画图函数*/
void Widget::DrawLine()
{

    QDateTime currentTime = QDateTime::currentDateTime();     //设置坐标轴显示范围

    chart->axisX()->setMin(QDateTime::currentDateTime().addSecs(-60*1));    //系统当前时间的前一秒
    chart->axisX()->setMax(QDateTime::currentDateTime().addMSecs(0));       //系统当前时间

    series->append(currentTime.toMSecsSinceEpoch() , number);     //将数据在坐标轴中画成曲线

}

经过测试,能够正常收发并显示数据。

  • 6
    点赞
  • 99
    收藏
    觉得还不错? 一键收藏
  • 9
    评论
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值