原创 使用QT做串口通信上位机

2023-3-29 12:01 1299 5 4 分类: MCU/ 嵌入式 文集: QT学习

以前使用VB做串口上位机,现在试用QT来做,顺便学习一下,入个门。看看有多大区别。

QT上编程用的是C++,所以Class(类)的概念(公有、私有、继承、多态、构造、析构、重载这些名词)一定要搞明白。 QT专有的信号和槽的概念。

开发用的是开源的QT Creator,具体下载,安装方法可以上B站看看大牛们的讲解。界面和使用方法,新建一个工程的方法,同样也可以看B站。

 

串口编程在VB中使用comm控件。在现在的这个QT版本中没有这个comm控件。不过可以使用两个类来完成同样的工作。

  1. #include <QtSerialPort/QSerialPort>
  2. #include <QtSerialPort/QSerialPortInfo>

MainWindow 的类定义中,私有成员增加QSerialPort *serial;

  1. class MainWindow : public QMainWindow
  2. {
  3. Q_OBJECT
  4. public:
  5. MainWindow(QWidget *parent = nullptr);
  6. ~MainWindow();
  7. private slots:
  8. void on_pbConnect_clicked();
  9. void readData();
  10. private:
  11. Ui::MainWindow *ui;
  12. QSerialPort *serial; // 私有QSerialPort成员
  13. };

 记得一定要在MainWindow的构造函数中对serial进行实例化。也就是需要让serial指向的一个实体,用于操作。

serial = new QSerialPort;      //new的作用相当于malloc,分配一个实体QSerialPort需要的内存。

严格的说,在析构函数中应该 delete serial; 以释放内存。

第一次编程时,没有实例化serial,空指针操作serial,结果程序一运行就崩溃退出。 

MainWindow::MainWindow(QWidget *parent)

    : QMainWindow(parent)

    , ui(new Ui::MainWindow)

{

    ui->setupUi(this);

    const auto infos = QSerialPortInfo::availablePorts();

    for(const QSerialPortInfo &info : infos){

        ui->cbCom->addItem(info.portName());

    }

    serial = new QSerialPort;  //实例化 serial

    connect(serial, &QSerialPort::readyRead, this, &MainWindow::readData);

}

 

在连接用的按键点击可以打开或关闭串口了。方法是判断按键上的文字。神奇的是,经常用的strcmp不存在,不过可以这样用:

if(ui->pbConnect->text() == QString("连接")) 直接判断字符串相等,不比strcmp香么?判断字符串相等肯定还是得一个字节一个字节比较。我想这个QString类一定把 “ == ”  做了重载(新定义了 == 作为字符串比较的运算符)。

 

void MainWindow::on_pbConnect_clicked()

{

    if(ui->pbConnect->text()==QString("连接")){

        serial->setPortName(ui->cbCom->currentText());

        serial->setBaudRate(QSerialPort::Baud115200);

        serial->setDataBits(QSerialPort::Data8);

        serial->setStopBits(QSerialPort::OneStop);

        serial->setParity(QSerialPort::NoParity);

        if(!serial->open(QIODevice::ReadWrite)){

            QMessageBox::information(this,"错误提示","不能打开串口",QMessageBox::Ok);

        }

        else{

            ui->cbCom->setEnabled(false);

            ui->pbConnect->setText("关闭");

        }

    }

    else{

        serial->close();

        ui->cbCom->setEnabled(true);

        ui->pbConnect->setText("连接");

    }

}

 

关于串口号的获取,在用VB时,用的是穷举法,捕获错误,非法的COM号会产生错误剔除,获得合法串口号。在QT里可以用QSerialPortInfo类,获取可用串口。这个for 循环也很有意思。不是常规的;;结构,感觉像是使用:对集合里的元素做一个遍历。可以在窗口构造函数中,或者其它地方把可用串口号送到combox里,方便选取。

    const auto infos = QSerialPortInfo::availablePorts();

    for(const QSerialPortInfo &info : infos){

        ui->cbCom->addItem(info.portName());

}

 

为了从串口获取数据,需要连接一个串口取数的槽函数。

connect(serial, &QSerialPort::readyRead, this, &MainWindow::readData); 当串口产生readyRead信号时,调用readData函数处理。而 readData,当然需要定义到private slots里面。

class MainWindow : public QMainWindow

{

    Q_OBJECT

 

public:

    MainWindow(QWidget *parent = nullptr);

    ~MainWindow();

 

private slots:

    void on_pbConnect_clicked();

    void readData();

private:

    Ui::MainWindow *ui;

    QSerialPort *serial;

};

 

每产生一次readyRead readData就被执行,程序中直接把所有接收到的内容存放到QString data里面。对于格式化数据,先前可以用sscanf读取分别放到数据或字符串里。QT里面没有sscanf感觉不爽是吧。

QStringList datlist = data.split(",",QString::SkipEmptyParts); 这个split 一下就把字符串分好了,直接使用 datlist[],就能引用。   

void MainWindow::readData()

{

    QString data = serial->readAll();

    QStringList datlist = data.split(",",QString::SkipEmptyParts);

    ui->lineEdit->setText(data);

    ui->lcdNumber1->display(datlist[0]);

    ui->lcdNumber2->display(datlist[1]);

}

 

程序运行,结果满意。效率又提升了。So easy!


好文赏现金!2023面包板社区原创奖励活动进行中:

https://mbb.eet-china.com/forum/topic/125238_1_1.html

作者: southcreek, 来源:面包板社区

链接: https://mbb.eet-china.com/blog/uid-me-408807.html

版权声明:本文为博主原创,未经本人允许,禁止转载!

给作者打赏,鼓励TA抓紧创作!

赞赏支持
点赞 5
赞赏2

文章评论2条评论)

登录后参与讨论

southcreek 2023-5-9 16:50

这个得天天用。有一阵不用,又忘记了。得重新来。

southcreek 2023-3-31 16:29

项目文件中需要
QT  += serialport
不然与serial port 相关的内容不能编译
相关推荐阅读
southcreek 2023-04-11 08:38
光隔离 SPI的设计和调试
制作一个SPI光隔离电路,用于读取24位ΣΔADC,隔离的目的是防止数字部分的噪声影响ADC采集。SPI设计速度希望达到2M以上。图中MASTER端产生 CS SCLK MOSI信号驱动SLAVE(...
southcreek 2023-04-10 11:49
QT 串口数据折线图显示
串口将接收到的数据,进行解析后,使用QT绘图,动态刷新显示。先将项目文件中增加charts支持 QT += charts 在主窗口定义中增加 QT_CHARTS_USE_NAMESP...
southcreek 2023-04-04 15:16
EMC 辐射抗扰故障的整改和分析
机器进行辐射抗扰实验。实验条件是: 80M~2.5G 1Khz正弦信号AM调制 80%调制深度,频率步长小于1%,驻停1S。对数方式递进。 实验天线以垂直或水平极化,到达被测机器位置的强度...
southcreek 2023-03-23 16:39
用AD读取编码开关设置的考虑
这个想法来源于一个组合使用的机器,机器可以插到组合箱,得到供电,同时要读取组合箱上的EEPROM内的数据,确认处于组合箱的位置。实际工作时组合箱上的EEPROM需要供电。拔插接口需要有保护电路。否则烧...
我要评论
2
5
1
2
3
4
5
6
7
8
9
0
关闭 热点推荐上一条 /4 下一条