QT从零开始作单片机上位机-串口调试助手+波形显示-实现串口模块的配置

 

目录

实现串口模块的配置(1)

一、先列举需要思考的问题:

二、所有的问题要由简单到复杂逐一解决


实现串口模块的配置(1)

       完成了基本的界面设计后,我们就要着手实现功能。下来的几章我们看串口数据收发的功能怎么实现。

首先我需要阐明的是,由于做嵌入式开发,相信大部分人学习的是C语言,而QT用的是C++,那么用C语言的知识能否完成这个上位机的工作呢?我的回答是可以的。

逐步来分析整个实现过程:

一、先列举需要思考的问题:

  1. 怎么实现点击刷新按钮后,串口工具可以自动发现可用的COM口,并将com口显示在Combobox1?
  2. 如何添加所有可用的波特率?同样给其他Combobox添加相关的值?
  3. 如何在点击“打开”按钮后,串口 即可使用,同时所有Combobox置为不可用状态,按钮字体转变为“关闭”?
  4. 如何在点击“清空接收区”按钮后,将接收区的数据清除?
  5. 如何在点击“暂停接收区”按钮后,接收不再接收数据?
  6. 如何实现自动清除功能?十六进制显示功能?
  7. 如何实现十六进制发送功能?自动发送功能,发送可按照间隔时间发送?
  8. 如何在点击“清空”按钮后,将Rx:Tx:的值显示为0?

 

二、所有的问题要由简单到复杂逐一解决

         1、先从Combobox入手,选中后双击,点击左下角“+”号,就可以直接在界面添加参数列表,所有Combobox操作方式一样。

 

2、处理简单的按钮问题:怎么实现点击“打开”按钮后变为“关闭”:

这里就要从代码入手,怎么办?通过网络大概可以了解到对按钮的动作要进行事件响应,QT通过“槽”机制实现,选中按钮,转到槽,在弹出的窗口中我们可以看到关于槽的函数:

可以推断按钮的点击可以是clicked();确定后看会是什么结果。

 

QT自动帮我们定义了一个函数:
void MainWindow::on_pB_Open_clicked()

{

}

为了便于调用函数,我们对所有控件进行重命名,它跟生成的函数名是相关的。

至于MainWindow:: 部分显然是C++的语法,暂时不需要去理解,只知道人家就是这样用的,不乱该改就行。

那么on_pB_Open_clicked()这个函数的声明在哪里,搜一下,就知道:

 

class MainWindow : public QMainWindow

{

    Q_OBJECT

   

public:

    explicit MainWindow(QWidget *parent = 0);

    ~MainWindow();

private slots:


void on_pB_Open_clicked();

}

 

       整个结构还是C++的用法,那么可以推知:其他生成的函数也是在private slots:槽部分声明的。如果我们自定义一个槽函数也可以放到这里,知道这些足够。

      我们的功能必然在这个函数体内来是实现,通过网络得知QT对空间的操作是通过ui变量来操作的,输入“ui->”QT编译器自动获取按钮的对象名称。下来的问题就是如何获取按钮的text属性“打开”,然后再改为“关闭”, ui->pB_Open->text()就可以。

if(ui->pB_Open->text()==tr("打开")) 这样就可以实现,

if(ui->pB_Open->text()==tr("打开"))

{

    ui->pB_Open->setText(tr("关闭"));

}

else

{

    ui->pB_Open->setText(tr("打开"));

}

以上就是最简单的实现代码,可以运行看看效果。

Combobox的操作就是 …->setEnabled(false);   …->setEnabled(true);

其他一些简单的槽函数都可以实现,比如清零、清空等操作。

 

3、串口调试工具要实现串口操作,就需要Qserialport 模块,这个直接可以通过网络知道。

如何在系统上获取可用串行端口的列表呢?

实现步骤:

1)打开.pro文件;添加一行:QT       += serialport

2)mainwindow.h 头文件里边添加

#include <QtSerialPort/QSerialPort>
#include <QtSerialPort/QSerialPortInfo>
3)在private:创建串口对象比如QSerialPort *my_serialport;
和ui对象在同一个作用域。ui能在哪调用my_serialport就能在哪调用。
有了串口对象就可以使用它的资源。
4)去“打开”按钮的槽函数void MainWindow::on_pB_Open_clicked()

加入一下两句:

my_serialport= new QSerialPort();

my_serialport->setPortName(ui->cB_COM->currentText());

就可以获取当前可用的串口列表。

但是在这之前我们先要通过“刷新”按钮查找系统里的串口。去它的槽函数通过foreach()实现查找

foreach (const QSerialPortInfo &info, QSerialPortInfo::availablePorts())

{

        QSerialPort serial;

        serial.setPort(info);

        if (serial.open(QIODevice::ReadWrite))

        {

            ui->cB_COM->clear();

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

            ui->textBrowser->append(tr("检测到端口列表:"));

            ui->textBrowser->append(info.portName());

            ui->textBrowser->append(info.description());

            ui->textBrowser->append(info.manufacturer());


            ui->cb_BaudRate->setCurrentIndex(Baud9600);//默认9600

            serial.close();

        }

        else

        {

            ui->textBrowser->append(tr("未检测端口列表:"));

        }

  }

 

打开串口之后就可以做一些其他操作:

 

if (my_serialport->open(QIODevice::ReadWrite))

 {

     ui->cB_COM->clear(); // 清除列表

     ui->cB_COM->addItem(my_serialport->portName()); //添加端口

     ui->textBrowser->append(tr("检测到端口:")); // 在接收文本区显示信息

     ui->pB_Open->setText(tr("关闭")); // 将按钮的“打开”改为“关闭”

     

 }

 else

 {

     ui->textBrowser->append(tr("未检测端口:"));

 }

 

其余的就是 设置波特率的值,数据位,校验位等。

 

my_serialport->setBaudRate(ui->cb_BaudRate->currentText().toInt());


  switch(ui->cB_Parity->currentIndex())

  {


        case 0: my_serialport->setParity(QSerialPort::NoParity);break;

        case 1: my_serialport->setParity(QSerialPort::OddParity);break;

        case 2: my_serialport->setParity(QSerialPort::EvenParity);break;

        case 3: my_serialport->setParity(QSerialPort::SpaceParity);break;

        case 4: my_serialport->setParity(QSerialPort::MarkParity);break;


        default: break;


  }

        switch(ui->cB_Data->currentIndex())

        {


            case 0: my_serialport->setDataBits(QSerialPort::Data8);break;

            case 1: my_serialport->setDataBits(QSerialPort::Data7);break;

            case 2: my_serialport->setDataBits(QSerialPort::Data6);break;

            case 3: my_serialport->setDataBits(QSerialPort::Data5);break;

            case 4: my_serialport->setDataBits(QSerialPort::Data4);break;


            default: break;


        }


        switch(ui->cb_stop->currentIndex())

        {


            case 0: my_serialport->setStopBits(QSerialPort::OneStop);break;

            case 1: my_serialport->setStopBits(QSerialPort::OneAndHalfStop);break;

            case 2: my_serialport->setStopBits(QSerialPort::TwoStop);break;


            default: break;


        }

 

其余的流控制、RTS、DTR等以后根据需要可以添加。

运行一下,看看结果.

 刷新

打开

 

下一章我们继续其他问题的处理。【没有C币可用,希望大大们打赏打赏,在此答谢!!!】

  • 12
    点赞
  • 82
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
这个需求可以通过连接单片机上位机串口,来实现数据的传输和处理。具体实现步骤如下: 1. 在单片机程序中,设置串口的波特率、数据位、停止位等参数,并开启串口接收中断。 2. 在串口接收中断中,将接收到的数据进行加5处理,并通过串口发送函数将处理后的数据发送给上位机。 3. 在上位机程序中,打开串口并设置相应的参数,接收串口数据。 4. 对接收到的数据进行解码和处理,并在上位机界面上进行显示。 下面是一个简单的示例程序(使用STC89C52单片机Qt串口调试助手): 单片机程序: ```c #include <reg52.h> #define uchar unsigned char #define uint unsigned int uchar code baud[] = {0xFD, 0x00}; // 波特率为9600 void init_serial() { TMOD |= 0x20; // 设置计数器1为模式2 SCON = 0x50; // 串口在模式1,允许接收 TH1 = baud[0]; // 设置波特率 TL1 = baud[1]; TR1 = 1; // 启动计数器1 ES = 1; // 允许串口中断 EA = 1; // 允许总中断 } void serial_send(uchar dat) { SBUF = dat + 5; // 发送数据加5 while (!TI); // 等待发送完成 TI = 0; // 清除发送标志 } void serial_isr() interrupt 4 { if (RI) { // 接收到数据 RI = 0; // 清除接收标志 serial_send(SBUF); // 发送数据 } } void main() { init_serial(); // 初始化串口 while (1); } ``` 上位机程序: ```c++ #include <QtSerialPort/QSerialPort> #include <QtSerialPort/QSerialPortInfo> #include <QCoreApplication> #include <QDebug> QSerialPort serial; int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); // 查找可用串口 QList<QSerialPortInfo> portList = QSerialPortInfo::availablePorts(); if (portList.isEmpty()) { qDebug() << "No available serial port."; return 1; } // 打开串口 serial.setPortName(portList.first().portName()); serial.setBaudRate(QSerialPort::Baud9600); serial.setDataBits(QSerialPort::Data8); serial.setStopBits(QSerialPort::OneStop); serial.setParity(QSerialPort::NoParity); if (!serial.open(QIODevice::ReadWrite)) { qDebug() << "Failed to open serial port."; return 1; } // 接收串口数据 QObject::connect(&serial, &QSerialPort::readyRead, [&](){ QByteArray data = serial.readAll(); for (int i = 0; i < data.size(); i++) { qDebug() << data.at(i); } }); return a.exec(); } ``` 在上述示例程序中,单片机接收到数据后,将数据加5后发送给上位机上位机接收到数据后,在控制台上输出接收到的数据。你可以根据具体需求,修改程序实现自己的功能。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值