Qt 串口上位机开发《Rice 上位机 学习开发》

2022-05-09 21:02:42 浏览数 (1)

前几天分享了一个使用C#开发的串口上位机,那么今天教你如何100行QT代码实现一个串口上位机。如果你学习过C ,那么使用QT开发软件,就不是什么大问题了,QT很多时候使用在linux上。所以使用QT开发还是挺不过的选择,QT兼容Linux和Windows,跨平台语言。话不多说,接下来说说他是怎么实现的。首先直接上软件效果图(温馨提示:代码没写完,哪有脸睡觉)。

源代码我放在我的github上:

git@github.com:RiceChen/SerialDemo.git

这个分享的软件也是实现基本功能,大家可以在这个基础上扩展自己想要的功能。

第一步,确定自己的需求,然后设计自己梦寐以求&华丽的UI。QT 的UI也是很容易设计的,通过拖拉控件即可。这是QT的控件栏,要什么控件就拖拉什么控件。

第二步,实现功能。这个串口软件我使用别人的API来实现,需要三个源文件(win_qextserialport.cpp/qextserialport.cpp/qextserialbase.cpp)和三个头文件(win_qextserialport.h/qextserialport.h/qextserialbase.h)

① 头文件(mainwindow.h)内容:通过Win_QextSerialPort定义串口对象myCom,定义一个串口是否打开标志,然后定义读数据信号槽函数readMyCom(),打开or关闭串口按键信号槽函数openOrCloseBtn(),发送数据按键信号槽函数sendMsgBtn()。

代码语言:javascript复制
class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

private:
    Ui::MainWindow *ui;
    Win_QextSerialPort *myCom; //声明对象

    bool flag;
private slots:
    void readMyCom();
    void openOrCloseBtn();
void sendMsgBtn();
};

① 源文件(mainwindow.cpp)内容:

1、构造函数的实现:通过API函数setWindowTitle()设置软件的标题,通过函数connect()连接按键信号,与信号槽函数的关联。

代码语言:javascript复制
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    setWindowTitle(tr("QT Serial-<Rice DIY> Wechat:wueroo1314"));
    ui->radioButton->setEnabled(false);
    connect(ui->pushButton_2,SIGNAL(clicked(bool)),this,SLOT(openOrCloseBtn()));
    //信号和槽函数关联,当按键按下时,进行串口打开关闭操作
    connect(ui->pushButton,SIGNAL(clicked(bool)),this,SLOT(sendMsgBtn()));
    //信号和槽函数关联,当按键按下时,进行数据发送操作
    flag=false;
}

2、析构函数的实现:直接把窗体给杀了就可以。

代码语言:javascript复制
MainWindow::~MainWindow()
{
    delete ui;
}

3、打开or关闭信号槽函数的实现:如果是打开串口:首先获取UI上的串口号,然后实例化串口对象myCom,然后通过API函数open()打开串口,比设置为可读可写。然后设置串口参数。

其中:波特率设置API函数:setBaudRate();

校验位设置API函数:setParity();

数据位设置API函数:setDataBits();

停止位设置API函数:setStopBits();

数据流控制设置API函数:setFlowControl();

这个Demo串口定时器的方式读取串口数据,通过setTimeout()设置定时器时间,通过connect()连接串口读信号与读数据槽函数。

如果是关闭串口:通过API函数close()关闭串口。

代码语言:javascript复制
void MainWindow::openOrCloseBtn()
{
    if(flag==false)
    {
        QString portName=ui->comboBox->currentText();
        myCom=new Win_QextSerialPort(portName,QextSerialBase::EventDriven);
        myCom->open(QIODevice::ReadWrite);

        //设置波特率
        if(ui->comboBox_2->currentText()==tr("9600"))
            myCom->setBaudRate(BAUD9600);
        else if(ui->comboBox_2->currentText()==tr("115200"))
            myCom->setBaudRate(BAUD115200);
        //设置奇偶校验位
        if(ui->comboBox_3->currentText()==QStringLiteral("无"))
            myCom->setParity(PAR_NONE);
        else if(ui->comboBox_3->currentText()==QStringLiteral("奇"))
            myCom->setParity(PAR_ODD);
        else if(ui->comboBox_3->currentText()==QStringLiteral("偶"))
            myCom->setParity(PAR_EVEN);
        //设置数据位
        if(ui->comboBox_4->currentText()==tr("8"))
            myCom->setDataBits(DATA_8);
        else if(ui->comboBox_4->currentText()==tr("7"))
            myCom->setDataBits(DATA_7);
        //设置停止位
        if(ui->comboBox_5->currentText()==tr("1"))
            myCom->setStopBits(STOP_1);
        else if(ui->comboBox_5->currentText()==tr("2"))
            myCom->setStopBits(STOP_2);

        myCom->setFlowControl(FLOW_OFF);//设置数据流控制,我们使用无数据流控制的默认设置
        myCom->setTimeout(500); //设置延时
        connect(myCom,SIGNAL(readyRead()),this,SLOT(readMyCom()));
        //信号和槽函数关联,当串口缓冲区有数据时,进行读串口操作
        ui->pushButton_2->setText(tr("关闭串口"));
        ui->radioButton->setChecked(true);
        ui->comboBox->setEnabled(false);
        ui->comboBox_2->setEnabled(false);
        ui->comboBox_3->setEnabled(false);
        ui->comboBox_4->setEnabled(false);
        ui->comboBox_5->setEnabled(false);
        flag=true;
    }
    else
    {
        myCom->close();
        ui->pushButton_2->setText(tr("打开串口"));
        ui->radioButton->setChecked(false);
        ui->comboBox->setEnabled(true);
        ui->comboBox_2->setEnabled(true);
        ui->comboBox_3->setEnabled(true);
        ui->comboBox_4->setEnabled(true);
        ui->comboBox_5->setEnabled(true);
        flag=false;
    }
}

4、读串口信号槽函数的实现:通过调取API函数readAll()去读串口的数据。然后将其数据设置到UI的receive控件上

代码语言:javascript复制
//读串口
void MainWindow::readMyCom()
{
    QByteArray temp = myCom->readAll();
    ui->textBrowser->insertPlainText(temp);
}

5、发送信号槽函数的实现:通过调取API函数write()将发送控件的内容通过串口发送出去。

代码语言:javascript复制
//写串口
void MainWindow::sendMsgBtn()
{
    myCom->write(ui->lineEdit->text().toLatin1());
}

第三步,软件测试:下位机采用stm32通过串口发数据到上位机。演示如下:

0 人点赞