QT上位机串口+STM32单片机项目

news2024/11/18 11:41:14

第一个自己的上位机小项目,嘿嘿,还是有些成绩感的。

目录

1.先看QT上位机部分

1.首先写一个页面

2.mainwindow.cpp主要函数。

2.form.cpp主要函数

3.STM32部分

1.main函数

3.QT完整代码

1.shangwei.pro

2.form.h

3.mainwindow.h

4.form.cpp

5.main.cpp

6.mainwindow.cpp


1.先看QT上位机部分

1.首先写一个页面

 点击隐藏BOSS后弹出第二个页面

 因为我的语音模块里面是周杰伦反方向的钟,所以我把歌词加进去了,你可以自由更改;

要想QT实现串口,需要两个头文件,加到mainwindow.cpp中

#include <QtSerialPort/QSerialPort>         // 提供访问串口的功能
#include <QtSerialPort/QSerialPortInfo>     // 提供系统中存在的串口信息

此时会报错,因为工程文件(shangwei.pro)还需要添加

QT       +=serialport

此时就可以正常使用头文件内部的函数了。首先我们要配置串口。

2.mainwindow.cpp主要函数。

配置串口函数:

void MainWindow::on_pushButton_5_clicked()  //打开,关闭
   {    //是OPEN时,代表没有打开串口
        if(ui->pushButton_5->text() == QString("OPEN")) {
            //检查串口是否被占用,再次检查一遍

            //串口配置
            //清空缓冲区
            serial = new QSerialPort;                       //申请内存,并设置父对象
            // 获取计算机中有效的端口号,然后将端口号的名称给端口选择控件
            //QSerialPortInfo::availablePorts()的返回值为QList<QSerialPortInfo> 每一个可用端口组成的容器
            foreach(const QSerialPortInfo &info,QSerialPortInfo::availablePorts())
            {
                serial->setPort(info);
                if(serial->open(QIODevice::ReadWrite))      // 以读写方式打开串口
                {
                                        // 在对象中设置串口
                    qDebug() << "串口打开成功";
                    serial->close();                        // 关闭
                } else
                {
                    qDebug() << "串口打开失败,请重试";
                }
            }

            //设置波特率
            serial->setBaudRate( static_cast<QSerialPort::BaudRate> (ui->comboBox_2->currentText().toInt()) );
            //设置停止位
            serial->setStopBits( static_cast<QSerialPort::StopBits> (ui->comboBox_3->currentText().toInt()));
            //设置数据位
            serial->setDataBits( static_cast<QSerialPort::DataBits> (ui->comboBox_6->currentText().toInt()) );
            //设置校验
            serial->setParity  ( static_cast<QSerialPort::Parity>   (ui->comboBox_4->currentIndex()));
            //设置流控
            serial->setFlowControl(QSerialPort::NoFlowControl);


            //改变按钮上的文本
            ui->pushButton_5->setText("CLOSE");
            //输出通道的端口名字
            ui->lineEdit->setText(serial->portName());

            isSerialOpen = serial->open(QIODevice::ReadWrite);
            serial->setDataTerminalReady(true);
            serial->setReadBufferSize(3);
            if (!isSerialOpen) {
                 qDebug()<< QString("Failed to open serial port:")  << serial->errorString();
                 serial->clearError();

              }else {
                    qDebug()<< QString("The serial port is open: ") ;

              }

       }else{

             ui->pushButton_5->setText("OPEN");
             serial->close();
        }

}

我这个波特率,停止位等串口设置依赖于窗口的选择;

 选择参数函数:

void MainWindow::initConfig() {


//        //创建对象,并建立信号槽
        serial = new QSerialPort(this);
//        //读函数的信号槽
        QObject::connect(serial, &QSerialPort::readyRead, this, &MainWindow::serial_readyRead);
        //添加波特率
        QStringList baudList;
        baudList << "115200" << "57600" << "9600" ;
        ui->comboBox_2->addItems(baudList);
        ui->comboBox_2->setCurrentText("115200");

        //添加停止位
        QStringList baudList1;
        baudList1 << "0.5" << "1" << "1.5"<<"2" ;
        ui->comboBox_3->addItems(baudList1);
        ui->comboBox_3->setCurrentText("1");

        //添加数据位
        QStringList baudList2;
        baudList2 << "8" << "9"  ;
        ui->comboBox_6->addItems(baudList2);
        ui->comboBox_6->setCurrentText("8");

        //奇偶校验
        QStringList baudList3;
        baudList3 << "NO" << "EVEN"  ;
        ui->comboBox_4->addItems(baudList3);
        ui->comboBox_4->setCurrentText("NO");

}

配置完串口函数后需要书写发串口发送数据和接受数据;

发送数据:

void MainWindow::on_pushButton_3_clicked() //发送
{
    if(ui->pushButton_5->text() == QString("CLOSE")) {

            QByteArray data = ui->textEdit_2->toPlainText().toUtf8();
            serial->write(data);
            qDebug() <<serial ;

    }else{
        ui->textEdit->append("请打开串口!!!!!");

    }

}

接收函数:

void MainWindow::serial_readyRead()
{

       //从接收缓冲区中读取数据
        QByteArray buffer = serial->readAll();
        //从界面中读取以前收到的数据
        QString recv = ui->textEdit->toPlainText();
        recv += QString(buffer);
        //清空以前的显示
        ui->textEdit->clear();
        //重新显示
        ui->textEdit->append(recv);
         qDebug() <<recv<<"cxc" ;
}

清空函数:

void MainWindow::on_pushButton_2_clicked()  //清除  接收
{
    //清除显示
        ui->textEdit->clear();
}

主要函数就这么多,后面会给出完整代码;

2.form.cpp主要函数

其实和上一个函数类型差不多,只是利用槽函数进行发送数据而已

初始化函数:

void Form::on_pushButton_10_clicked()
{
    if(ui->pushButton_10->text() == QString("打开串口")) {

        //串口配置
        //清空缓冲区
        serial = new QSerialPort;                       //申请内存,并设置父对象
        // 获取计算机中有效的端口号,然后将端口号的名称给端口选择控件
        //QSerialPortInfo::availablePorts()的返回值为QList<QSerialPortInfo> 每一个可用端口组成的容器
        foreach(const QSerialPortInfo &info,QSerialPortInfo::availablePorts())
        {
            serial->setPort(info);
            if(serial->open(QIODevice::ReadWrite))      // 以读写方式打开串口
            {
                                    // 在对象中设置串口
                qDebug() << "串口打开成功";
                serial->close();                        // 关闭
            } else
            {
                qDebug() << "串口打开失败,请重试";
            }
        }

        // 参数配置,波特率V
        serial->setBaudRate(QSerialPort::Baud115200);
        // 校验位,校验默认选择无
        serial->setParity(QSerialPort::NoParity);
        // 数据位,数据位默认选择8位
        serial->setDataBits(QSerialPort::Data8);
        // 停止位,停止位默认选择1位
        serial->setStopBits(QSerialPort::OneStop);
        // 控制流,默认选择无
        serial->setFlowControl(QSerialPort::NoFlowControl);


        //改变按钮上的文本
        ui->pushButton_10->setText("关闭串口");
        //输出通道的端口名字


        bool isSerialOpen = serial->open(QIODevice::ReadWrite);
        serial->setDataTerminalReady(true);
        serial->setReadBufferSize(3);
        if (!isSerialOpen) {
             qDebug()<< QString("Failed to open serial port:")  << serial->errorString();
             serial->clearError();
              configSetEnable1(false);
          }else {
                qDebug()<< QString("The serial port is open: ") ;
                configSetEnable1(true);

          }

   }else{
          configSetEnable1(false);
         ui->pushButton_10->setText("打开串口");
         serial->close();
    }
}

发送函数:

void Form::on_pushButton_13_clicked()
{
    QByteArray data ="55";
    serial->write(data);
    qDebug() <<serial ;
}

我只列举了主要函数,后面会给出完整的代码。

3.STM32部分

我使用的是信盈达的STM32F103ZET6,JQ8900N-16P 语音模块,MQ135模块,MQ2模块以及DHT11温湿度模块和一块LED屏幕。

STM32部分代码太多,后面会打包成压缩文件,先看一下主函数。

1.main函数

#include "stm32f10x.h"
#include "stm32f10x_conf.h"
#include <stdio.h>
#include <string.h>
#include "delay.h"
#include "usart.h"
#include "sys.h"
#include "led.h"
#include "key.h"
#include "relay.h"
#include "beep.h"
#include "time.h"
#include "lcd_gui.h"
#include "pic.h"
#include "touch.h"
#include "dht11.h"
#include "adc.h"


int main()
{
    
    u8 T,H;
	int num=0,i=0,X=0,Y=0;
	u8 ledflag =1;
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	Delay_Init();                                                  
	USART_Config(115200); 
    BEEPGpioInit();	
	LEDInit();
	KEYGpioInit();
	RELAYInit();
	LCD_Init();
    Adc_Init();	
    Voice_Config(9600);
    int count=5;
	Set_Song_Volume(5);
    
    
    
    
       
        int bo=2;
        char MQ[11]={'#','M','Q','1','3','5',':'};
        char WEN[5];
        char SHI[6];
        char MQ22[10]={'#','M','Q','2',':'};
        SHI[5]='\0';
        WEN[4]='\0';
		WEN[0]='T';
        SHI[0]='H';
        WEN[1]=':';
        SHI[1]=':';
        MQ[10]='\0';
        MQ22[9]='\0';
        
     
     

//	LCD_Dis_String(0,0,"棒打林渊!",0x0000, 0xffff, 2,0);
//	LCD_Dis_String(0,32,"Hello Tomorrow",0x0000, 0xffff, 2,0);
	while(1)
		{
            
            if(uart1_finish_flage)
               {
                  
 
                 if(strcmp(USART1_Rcv_Buff,"11") == 0){
                      LCD_Clear(0,239,0,319,0xffff);
                     //处理数据 USART1_Rcv_Buff
                     LED1_ON;
                     //处理结束将数组进行清空
       
                     LCD_Dis_String(0,0,"LED1_ON",0x0000, 0xffff, 2,0);
               
                 }else if(strcmp(USART1_Rcv_Buff,"12") == 0){
                      LCD_Clear(0,239,0,319,0xffff);
                      LED1_OFF;
                      LCD_Dis_String(0,0,"LED1_OFF",0x0000, 0xffff, 2,0);
               
                 }else if(strcmp(USART1_Rcv_Buff,"21") == 0){
                      LCD_Clear(0,239,0,319,0xffff);
                      LED2_ON;
                      LCD_Dis_String(0,0,"LED2_ON",0x0000, 0xffff, 2,0);
               
                 }else if(strcmp(USART1_Rcv_Buff,"22") == 0){
                      LCD_Clear(0,239,0,319,0xffff);
                      LED2_OFF;
                      LCD_Dis_String(0,0,"LED2_OFF",0x0000, 0xffff, 2,0);
               
                 }else if(strcmp(USART1_Rcv_Buff,"31") == 0){
                      LCD_Clear(0,239,0,319,0xffff);
                      LED3_ON;
                      LCD_Dis_String(0,0,"LED3_ON",0x0000, 0xffff, 2,0);
               
                 }else if(strcmp(USART1_Rcv_Buff,"32") == 0){
                      LCD_Clear(0,239,0,319,0xffff);
                      LED3_OFF;
                      LCD_Dis_String(0,0,"LED3_OFF",0x0000, 0xffff, 2,0);
               
                 }else if(strcmp(USART1_Rcv_Buff,"41") == 0){
                      LCD_Clear(0,239,0,319,0xffff);
                      LED4_ON;
                      LCD_Dis_String(0,0,"LED4_ON",0x0000, 0xffff, 2,0);
               
                 }else if(strcmp(USART1_Rcv_Buff,"42") == 0){
                      LCD_Clear(0,239,0,319,0xffff);
                      LED4_OFF;
                      LCD_Dis_String(0,0,"LED4_OFF",0x0000, 0xffff, 2,0);
               
                 }else if(strcmp(USART1_Rcv_Buff,"55") == 0){
                     
                        Set_Song_Volume(count++);
                 }else if(strcmp(USART1_Rcv_Buff,"66") == 0){
                     
                        Set_Song_Volume(count--);
                 }else if(strcmp(USART1_Rcv_Buff,"77") == 0){
                     
                      Appoint_Song_Name("00001");
                 }else if(strcmp(USART1_Rcv_Buff,"88") == 0){
                     
                     Stop_Song();
                 }else if(strcmp(USART1_Rcv_Buff,"99") == 0){
                     
                    Xiayi_Song();
                 }else if(strcmp(USART1_Rcv_Buff,"98") == 0){
                     
                     Shangyi_Song();
                     
                 }else if(strcmp(USART1_Rcv_Buff,"13") == 0){
                     
                     bo=1;
                 }else if(strcmp(USART1_Rcv_Buff,"14") == 0){
                     
                     BEEP_ON;
                 }else if(strcmp(USART1_Rcv_Buff,"15") == 0){
                     
                     BEEP_OFF;
                 }else if(strcmp(USART1_Rcv_Buff,"16") == 0){
                     
                     bo=0;
                 }
                 
                 
                 memset(USART1_Rcv_Buff,0,sizeof(USART1_Rcv_Buff));
                 uart1_count = 0;
                 uart1_finish_flage =0;
             }
               
             
                 if(bo==1){
                     dht11_read_ht(&T,&H);
                     LCD_Clear(0,239,0,319,0xffff);

//                     if(H>80)BEEP_ON ;else BEEP_OFF;
                     WEN[2]=T/10+'0';
                     WEN[3]=T%10+'0';
                    
                     SHI[2]=H/100+'0';
                     SHI[3]=H/10%10+'0';
                     SHI[4]=H%10+'0';
                    
                     int m=ADC_Val_Disp(Mq135);
                     int m2=ADC_Val_Disp(Mq2);
                     MQ[7]=m/100+'0';
                     MQ[8]=m/10%10+'0';
                     MQ[9]=m%10+'0';
                     
                     MQ22[5]=m2/1000+'0';
                     MQ22[6]=m2/100%10+'0';
                     MQ22[7]=m2/10%10+'0';
                     MQ22[8]=m2%10+'0';
                     
                     LCD_Clear(0,239,0,319,0xffff);
                     LCD_Dis_String(0,0,WEN,0x0000, 0xffff, 2,0);
                     LCD_Dis_String(0,32,SHI,0x0000, 0xffff, 2,0);
                     LCD_Dis_String(0,64,MQ,0x0000, 0xffff, 2,0);
                     LCD_Dis_String(0,32*3,MQ22,0x0000, 0xffff, 2,0);
               
                     Delay_ms(500);
                   
                     
                 }else if(bo==0){
                      LCD_Clear(0,239,0,319,0xffff);
                      bo=2;
                 }
                
                 
               }
           
		return 0;
}



先通过QT给单片机发送指令,单片机收到后会判断是哪一种指令,实行相应的操作。

3.QT完整代码

我的文件是这样的

1.shangwei.pro

QT       += core gui

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

CONFIG += c++11

# The following define makes your compiler emit warnings if you use
# any Qt feature that has been marked deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS

# You can also make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0

SOURCES += \
    form.cpp \
    main.cpp \
    mainwindow.cpp

HEADERS += \
    form.h \
    mainwindow.h

FORMS += \
    form.ui \
    mainwindow.ui
#串口通信
QT       +=serialport

# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target

RESOURCES += \
    rec.qrc

2.form.h

#ifndef FORM_H
#define FORM_H

#include <QWidget>
#include <QtSerialPort/QSerialPort>         // 提供访问串口的功能
#include <QtSerialPort/QSerialPortInfo>     // 提供系统中存在的串口信息

namespace Ui {
class Form;
}

class Form : public QWidget
{
    Q_OBJECT

public:
    explicit Form(QWidget *parent = nullptr);
    ~Form();

private slots:
    void on_pushButton_clicked();

    void on_pushButton_9_clicked();

    void on_pushButton_2_clicked();

    void on_pushButton_3_clicked();

    void on_pushButton_4_clicked();

    void on_pushButton_5_clicked();

    void on_pushButton_6_clicked();

    void on_pushButton_7_clicked();

    void on_pushButton_8_clicked();

    void on_pushButton_10_clicked();

    void on_pushButton_13_clicked();

    void on_pushButton_14_clicked();

    void on_pushButton_11_clicked();

    void on_pushButton_12_clicked();

    void on_pushButton_16_clicked();

    void on_pushButton_15_clicked();

    void on_pushButton_19_clicked();

    void on_pushButton_20_clicked();

    void on_pushButton_21_clicked();

    void on_pushButton_22_clicked();

private:
    Ui::Form *ui;
    QSerialPort     *serial;              //定义全局的串口对象
    void configSetEnable1(bool b1);


};

#endif // FORM_H

3.mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
//串口通信
#include "form.h"
#include <QtSerialPort/QSerialPort>         // 提供访问串口的功能
#include <QtSerialPort/QSerialPortInfo>     // 提供系统中存在的串口信息


QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private slots:
    void on_pushButton_clicked();

    void on_pushButton_2_clicked();

    void on_pushButton_3_clicked();

    void on_pushButton_4_clicked();

    void on_pushButton_5_clicked();


private:
    Ui::MainWindow *ui;
    void SerialPortInit(void);
    void initConfig();
    void serial_readyRead();
    void configSetEnable(bool b);
    //串口变量↓
    QSerialPort     *serial;              //定义全局的串口对象
    QStringList     baudList;             //波特率
    QStringList     parityList;           //校验位
    QStringList     dataBitsList;         //数据位
    QStringList     stopBitsList;         //停止位
    QStringList     flowControlList;      //控制流
    bool isSerialOpen;
    Form *form;
};
#endif // MAINWINDOW_H

4.form.cpp

#include "form.h"
#include "ui_form.h"
#include <QDebug>
#include "mainwindow.h"
#include "QLabel"
#include "QMovie"
Form::Form(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Form)
{
    ui->setupUi(this);
     configSetEnable1(false);
     QMovie *movie = new QMovie(":/new/prefix1/image/83686B74CD2AF08B32BC013618CD188F.gif");
     ui->label->setMovie(movie);
     movie->start();

     connect(ui->pushButton_17,&QPushButton::clicked,this,[=](){
         movie->stop();
     });
     connect(ui->pushButton_18,&QPushButton::clicked,this,[=](){
         movie->start();
     });

}

Form::~Form()
{
    delete ui;
}

void Form::on_pushButton_clicked()   //点亮LED1
{
            QByteArray data ="11";
            serial->write(data);
            qDebug() <<serial ;
}


void Form::on_pushButton_9_clicked()
{
    serial->close();
    MainWindow *w=new MainWindow;
    w->show();
    this->close();
}

void Form::on_pushButton_2_clicked()   //熄灭LED1
{
    QByteArray data ="12";
    serial->write(data);
    qDebug() <<serial ;
}

void Form::on_pushButton_3_clicked()  //点亮LED2
{
    QByteArray data ="21";
    serial->write(data);
    qDebug() <<serial ;
}

void Form::on_pushButton_4_clicked()  //熄灭LED2
{
    QByteArray data ="22";
    serial->write(data);
    qDebug() <<serial ;
}


void Form::on_pushButton_5_clicked()  //点亮LED3
{
    QByteArray data ="31";
    serial->write(data);
    qDebug() <<serial ;
}

void Form::on_pushButton_6_clicked()  //熄灭LED3
{
    QByteArray data ="32";
    serial->write(data);
    qDebug() <<serial ;
}



void Form::on_pushButton_7_clicked()  //点亮LED4
{
    QByteArray data ="41";
    serial->write(data);
    qDebug() <<serial ;
}


void Form::on_pushButton_8_clicked()  //熄灭LED4
{
    QByteArray data ="42";
    serial->write(data);
    qDebug() <<serial ;
}

void Form::on_pushButton_10_clicked()
{
    if(ui->pushButton_10->text() == QString("打开串口")) {

        //串口配置
        //清空缓冲区
        serial = new QSerialPort;                       //申请内存,并设置父对象
        // 获取计算机中有效的端口号,然后将端口号的名称给端口选择控件
        //QSerialPortInfo::availablePorts()的返回值为QList<QSerialPortInfo> 每一个可用端口组成的容器
        foreach(const QSerialPortInfo &info,QSerialPortInfo::availablePorts())
        {
            serial->setPort(info);
            if(serial->open(QIODevice::ReadWrite))      // 以读写方式打开串口
            {
                                    // 在对象中设置串口
                qDebug() << "串口打开成功";
                serial->close();                        // 关闭
            } else
            {
                qDebug() << "串口打开失败,请重试";
            }
        }

        // 参数配置,波特率V
        serial->setBaudRate(QSerialPort::Baud115200);
        // 校验位,校验默认选择无
        serial->setParity(QSerialPort::NoParity);
        // 数据位,数据位默认选择8位
        serial->setDataBits(QSerialPort::Data8);
        // 停止位,停止位默认选择1位
        serial->setStopBits(QSerialPort::OneStop);
        // 控制流,默认选择无
        serial->setFlowControl(QSerialPort::NoFlowControl);


        //改变按钮上的文本
        ui->pushButton_10->setText("关闭串口");
        //输出通道的端口名字


        bool isSerialOpen = serial->open(QIODevice::ReadWrite);
        serial->setDataTerminalReady(true);
        serial->setReadBufferSize(3);
        if (!isSerialOpen) {
             qDebug()<< QString("Failed to open serial port:")  << serial->errorString();
             serial->clearError();
              configSetEnable1(false);
          }else {
                qDebug()<< QString("The serial port is open: ") ;
                configSetEnable1(true);

          }

   }else{
          configSetEnable1(false);
         ui->pushButton_10->setText("打开串口");
         serial->close();
    }
}

void Form::on_pushButton_13_clicked()
{
    QByteArray data ="55";
    serial->write(data);
    qDebug() <<serial ;
}

void Form::on_pushButton_14_clicked()
{
    QByteArray data ="66";
    serial->write(data);
    qDebug() <<serial ;
}

void Form::on_pushButton_11_clicked()
{
    QByteArray data ="77";
    serial->write(data);
    qDebug() <<serial ;
}

void Form::on_pushButton_12_clicked()
{
    QByteArray data ="88";
    serial->write(data);
    qDebug() <<serial ;
}


void Form::on_pushButton_16_clicked()
{
    QByteArray data ="99";
    serial->write(data);
    qDebug() <<serial ;
}

void Form::on_pushButton_15_clicked()
{
    QByteArray data ="98";
    serial->write(data);
    qDebug() <<serial ;
}


void Form::configSetEnable1(bool b1)
{

    ui->pushButton->setEnabled(b1);
    ui->pushButton_2->setEnabled(b1);
    ui->pushButton_3->setEnabled(b1);
    ui->pushButton_4->setEnabled(b1);
    ui->pushButton_5->setEnabled(b1);
    ui->pushButton_6->setEnabled(b1);
    ui->pushButton_7->setEnabled(b1);
    ui->pushButton_8->setEnabled(b1);
    ui->pushButton_11->setEnabled(b1);
    ui->pushButton_12->setEnabled(b1);
    ui->pushButton_13->setEnabled(b1);
    ui->pushButton_14->setEnabled(b1);
    ui->pushButton_16->setEnabled(b1);
    ui->pushButton_15->setEnabled(b1);
    ui->pushButton_19->setEnabled(b1);
    ui->pushButton_20->setEnabled(b1);
    ui->pushButton_21->setEnabled(b1);
    ui->pushButton_22->setEnabled(b1);

   // ui->pushButton_9->setEnabled(b1);

}

void Form::on_pushButton_19_clicked()   //启动蜂鸣器
{
    QByteArray data ="14";
    serial->write(data);
    qDebug() <<serial ;
}

void Form::on_pushButton_20_clicked()   //关闭蜂鸣器
{
    QByteArray data ="15";
    serial->write(data);
    qDebug() <<serial ;
}


void Form::on_pushButton_21_clicked()
{
    QByteArray data ="13";
    serial->write(data);
    qDebug() <<serial ;
}

void Form::on_pushButton_22_clicked()
{
    QByteArray data ="16";
    serial->write(data);
    qDebug() <<serial ;
}

5.main.cpp

#include "mainwindow.h"

#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.show();
    return a.exec();
}

6.mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"
//串口通信
#include <QDebug>
#include <QString>


MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    initConfig();
    form=new Form;
    QObject::connect(serial, &QSerialPort::readyRead, this, &MainWindow::serial_readyRead);
    //固定大小

}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::SerialPortInit()
{
    serial = new QSerialPort;                       //申请内存,并设置父对象

    // 获取计算机中有效的端口号,然后将端口号的名称给端口选择控件
    //QSerialPortInfo::availablePorts()的返回值为QList<QSerialPortInfo> 每一个可用端口组成的容器
    foreach(const QSerialPortInfo &info,QSerialPortInfo::availablePorts())
    {
        serial->setPort(info);
        if(serial->open(QIODevice::ReadWrite))      // 以读写方式打开串口
        {
                                // 在对象中设置串口
            qDebug() << "串口打开成功";
            serial->close();                        // 关闭
        } else
        {
            qDebug() << "串口打开失败,请重试";
        }
    }

    // 参数配置,波特率V
    serial->setBaudRate(QSerialPort::Baud19200);
    // 校验位,校验默认选择无
    serial->setParity(QSerialPort::NoParity);
    // 数据位,数据位默认选择8位
    serial->setDataBits(QSerialPort::Data8);
    // 停止位,停止位默认选择1位
    serial->setStopBits(QSerialPort::OneStop);
    // 控制流,默认选择无
    serial->setFlowControl(QSerialPort::NoFlowControl);

}

void MainWindow::on_pushButton_clicked()
{
   form->show();
   serial->close();
   this->close();
}

void MainWindow::on_pushButton_2_clicked()  //清除  接收
{
    //清除显示
        ui->textEdit->clear();
}

void MainWindow::on_pushButton_3_clicked() //发送
{
    if(ui->pushButton_5->text() == QString("CLOSE")) {

            QByteArray data = ui->textEdit_2->toPlainText().toUtf8();
            serial->write(data);
            qDebug() <<serial ;

    }else{
        ui->textEdit->append("请打开串口!!!!!");

    }

}

void MainWindow::on_pushButton_4_clicked() //清除发送
{
    //清除显示
    ui->textEdit_2->clear();
}

void MainWindow::on_pushButton_5_clicked()  //打开,关闭
   {    //是OPEN时,代表没有打开串口
        if(ui->pushButton_5->text() == QString("OPEN")) {
            //检查串口是否被占用,再次检查一遍

            //串口配置
            //清空缓冲区
            serial = new QSerialPort;                       //申请内存,并设置父对象
            // 获取计算机中有效的端口号,然后将端口号的名称给端口选择控件
            //QSerialPortInfo::availablePorts()的返回值为QList<QSerialPortInfo> 每一个可用端口组成的容器
            foreach(const QSerialPortInfo &info,QSerialPortInfo::availablePorts())
            {
                serial->setPort(info);
                if(serial->open(QIODevice::ReadWrite))      // 以读写方式打开串口
                {
                                        // 在对象中设置串口
                    qDebug() << "串口打开成功";
                    serial->close();                        // 关闭
                } else
                {
                    qDebug() << "串口打开失败,请重试";
                }
            }

            //设置波特率
            serial->setBaudRate( static_cast<QSerialPort::BaudRate> (ui->comboBox_2->currentText().toInt()) );
            //设置停止位
            serial->setStopBits( static_cast<QSerialPort::StopBits> (ui->comboBox_3->currentText().toInt()));
            //设置数据位
            serial->setDataBits( static_cast<QSerialPort::DataBits> (ui->comboBox_6->currentText().toInt()) );
            //设置校验
            serial->setParity  ( static_cast<QSerialPort::Parity>   (ui->comboBox_4->currentIndex()));
            //设置流控
            serial->setFlowControl(QSerialPort::NoFlowControl);


            //改变按钮上的文本
            ui->pushButton_5->setText("CLOSE");
            //输出通道的端口名字
            ui->lineEdit->setText(serial->portName());

            isSerialOpen = serial->open(QIODevice::ReadWrite);
            serial->setDataTerminalReady(true);
            serial->setReadBufferSize(3);
            if (!isSerialOpen) {
                 qDebug()<< QString("Failed to open serial port:")  << serial->errorString();
                 serial->clearError();

              }else {
                    qDebug()<< QString("The serial port is open: ") ;

              }

       }else{

             ui->pushButton_5->setText("OPEN");
             serial->close();
        }

}

void MainWindow::initConfig() {


//        //创建对象,并建立信号槽
        serial = new QSerialPort(this);
//        //读函数的信号槽
        QObject::connect(serial, &QSerialPort::readyRead, this, &MainWindow::serial_readyRead);
        //添加波特率
        QStringList baudList;
        baudList << "115200" << "57600" << "9600" ;
        ui->comboBox_2->addItems(baudList);
        ui->comboBox_2->setCurrentText("115200");

        //添加停止位
        QStringList baudList1;
        baudList1 << "0.5" << "1" << "1.5"<<"2" ;
        ui->comboBox_3->addItems(baudList1);
        ui->comboBox_3->setCurrentText("1");

        //添加数据位
        QStringList baudList2;
        baudList2 << "8" << "9"  ;
        ui->comboBox_6->addItems(baudList2);
        ui->comboBox_6->setCurrentText("8");

        //奇偶校验
        QStringList baudList3;
        baudList3 << "NO" << "EVEN"  ;
        ui->comboBox_4->addItems(baudList3);
        ui->comboBox_4->setCurrentText("NO");

}

void MainWindow::serial_readyRead()
{

       //从接收缓冲区中读取数据
        QByteArray buffer = serial->readAll();
        //从界面中读取以前收到的数据
        QString recv = ui->textEdit->toPlainText();
        recv += QString(buffer);
        //清空以前的显示
        ui->textEdit->clear();
        //重新显示
        ui->textEdit->append(recv);
         qDebug() <<recv<<"cxc" ;
}


void MainWindow::configSetEnable(bool b)
{

//    ui->comboBox_2->setEnabled(b);
//    ui->comboBox_3->setEnabled(b);
//    ui->comboBox_6->setEnabled(b);
//    ui->comboBox_4->setEnabled(b);

//    //
//    ui->pushButton_3->setEnabled(!b);
}

4.STM32完整代码

代码太多,后面会打包成压缩文件。

资源文件审核中,审核成功后补上。

5.实现效果

实现效果就是和按钮名字相同,电脑点击播放音乐单片机会播放音乐,点击点亮LED1,LED1会点亮。点击刷新数据,LCD会显示收集的温湿度数据和MQ135数据,以及MQ2的数据。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/546055.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

从零入门激光SLAM(十一)——如何求解SLAM问题

大家好呀&#xff0c;我是一个SLAM方向的在读博士&#xff0c;深知SLAM学习过程一路走来的坎坷&#xff0c;也十分感谢各位大佬的优质文章和源码。随着知识的越来越多&#xff0c;越来越细&#xff0c;我准备整理一个自己的激光SLAM学习笔记专栏&#xff0c;从0带大家快速上手激…

(转载)从0开始学matlab(第9天)—第一阶段总结

1.编程实例 下面的例子将向大家介绍如何用 MATLAB 解决问题。 例1 温度转换程序 问题&#xff1a; 设计一个 MATLAB 程序&#xff0c;读取一个华氏温度的输入&#xff0c;输出开尔文温度。 答案&#xff1a; 华氏温度和开尔文温度的转换关系式可在物理学课本中找到。其关系式…

HCIP-RIP双向重发布综合实验

拓扑结构&#xff1a; 要求&#xff1a; 1、两个协议间进行多点双向重发布 2、R7的环回没有宣告在OSPF协议中&#xff0c;而是在后期重发布进入的 3、解决环路&#xff0c;所有路径选择最优&#xff0c;且存在备份 4、R2的环回要在RIP中宣告&#xff0c;R3的环回要在OSPF中宣…

如何优雅的写C#,使用Visual studio

免责声明 本人接触C#,.Net一年时间&#xff0c;本文内容基于我平时对于C#语法的积累&#xff0c;如有问题请多包涵。以下内容除了C#之外&#xff0c;还有Visual studio编译器相关的内容。 在使用C#的一年多里面&#xff0c;我发现C#的语法糖真的很不错&#xff0c;Visual Stu…

SaaS系统用户权限设计

SaaS系统用户权限设计 学习目标&#xff1a; 理解RBAC模型的基本概念及设计思路 了解SAAS-HRM中权限控制的需求及表结构分析完成组织机构的基本CRUD操作 完成用户管理的基本CRUD操作完成角色管理的基本CRUD操作 组织机构管理 需求分析 需求分析 实现企业组织结构管理&#xff0…

PCB 基础~典型的PCB设计流程,典型的PCB制造流程

典型的PCB设计流程 典型的PCB制造流程 • 从客户手中拿到Gerber&#xff0c; Drill以及其它PCB相关文件 • 准备PCB基片和薄片 – 铜箔的底片会被粘合在基材上 • 内层图像蚀刻 – 抗腐蚀的化学药水会涂在需要保留的铜箔上&#xff08;例如走线和过孔&#xff09; – 其他药水…

如何封装React无限滚动加载列表组件【含源码】

前言 由于需要考虑后端接口的性能问题&#xff0c;我们在请求业务数据列表的时候并不能直接请求全量数据。所以我们在请求数据时常见的方式是做分页查询。 对于前端交互而言&#xff0c;我们需要考虑如何优雅的让用户触发请求下一页数据的接口。常用的方法有两种&#xff1a;…

i春秋春季赛2023

只有两道逆向和一道misc&#xff0c;其他的有时间再写 wordle 不断筛有什么和没什么字母猜就行了 [6x] Guess a 5-letter word : first first [5x] Guess a 5-letter word : ideas Please enter a real English word that exists. [5x] Guess a 5-letter word : icily first…

View的基础与滑动

View的基础与滑动 1.View的基础知识 1.1View是什么 View是一种界面层的控件的一种抽象 ,我们知道的大多数控件都是直接或间接继承自View 如EditText,TextView等等 注意: EditText在compose中并没有相关控件,而是通过TextField来进行组合 Android中View本身就可以是单个控…

rt-thread启动流程(最详细教程)

资料下载 RT-Thread Simulator 例程 操作流程 将上面的仿真例程下载并解压&#xff0c;通过MDK打开&#xff0c;编译&#xff0c;调试&#xff0c;并打开串口点击运行&#xff0c;就可以看到如下输出了&#xff1a; 添加自己的 thread&#xff1a;在main()函数中添加即可&am…

【5.19】四、性能测试—流程

4.4 性能测试的流程 性能测试也遵循测试需求分析→测试计划制订→测试用例设计→测试执行→编写测试报告的基本过程&#xff0c;但在实现细节上&#xff0c;性能测试有单独一套流程&#xff1a; 1. 分析性能测试需求 在性能测试需求分析阶段&#xff0c;测试人员需要收集有关…

【AI Earth试玩】权限配置与openAPI调用工具库

前言 AI earth是阿里达摩院出的遥感云计算平台&#xff0c;我简单体验下来感觉像是GEE的python版本遥感深度学习计算平台&#xff0c;整体体验还是挺不错的&#xff0c;尤其是多分类的结果还是挺惊艳的。 平台提供工具箱和notebook两种模式&#xff0c;工具箱整个交互简单易用…

DJ 5-4 以太网 Ethernet

目录 一、以太网的物理拓扑结构 二、以太网物理层标准 1、以太网技术&#xff1a;10Base-T 和 100Base-T 2、以太网技术&#xff1a;1000Base 系列 3、曼彻斯特编码* 4、差分曼彻斯特编码机制* 三、以太网链路层控制技术 四、以太网的帧结构 1、前同步码 2、MAC 地址…

Spring Boot 项目【前后端分离】之后端实现加 LambdaQueryWrapper实现源码分析和手动模拟

目录 Spring Boot 项目【前后端分离】 之架子搭建 技术栈 实现功能03-创建Spring Boot 后端项目 需求分析/图解 思路分析 代码实现 1. 创建springboot_furn 项目 2. 修改pom.xml , 引入mybatis-plus 等相关依赖 3. 创建application.yml 配置port & 配置DB 连接信息…

【数据结构】KMP算法:计算next与nextval函数值(图解)

例&#xff1a;计算模式串"abaabcac"的KMP算法中next函数值 由函数定义 n e x t [ j ] { 0 , j 1 M a x { k ∣ 1 < k < j 且 " t 1 t 2 ⋅ ⋅ ⋅ t k − 1 " " t j − k 1 t j − k 2 ⋅ ⋅ ⋅ t j − 1 " } 1 , k 1 next[j]\left…

asp.net高校运动会管理系统的设计与实现

本高校运动会管理系统是针对我院当前运动会工作需要而开发的B/S模式的网络系统&#xff0c;涉及到运动会赛前的报名录入准备与分组编排、赛中的成绩处理、赛后的成绩汇总与团体总分的统计。它将是一个完整统一、技术先进、高效稳定、安全可靠的基于Internet/Intranet的高校运动…

一、Git安装(Git+TortoiseGit图形化)

Git 是一个开源的分布式版本控制系统&#xff0c;用于敏捷高效地处理任何或小或大的项目。 Git 是 Linus Torvalds 为了帮助管理 Linux 内核开发而开发的一个开放源码的版本控制软件。 Git 与常用的版本控制工具 CVS, Subversion 等不同&#xff0c;它采用了分布式版本库的方式…

《计算机网络—自顶向下方法》 Wireshark实验(八):ICMP 协议分析

ICMP&#xff08;Internet Control Message Protocol&#xff09;网络控制报文协议。它是 TCP/IP 协议簇的一个子协议&#xff0c;用于在 IP 主机、路由器之间传递控制消息。控制消息是指网络通不通、主机是否可达、路由是否可用等网络本身的消息。这些控制消息虽然并不传输用户…

进程概念

目录 冯诺依曼体系结构 操作系统OS 系统调用和库函数概念 进程 task_struct内容分类 组织进程 初识fork 进程状态 Z(zombie)-僵尸进程 孤儿进程 进程优先级 环境变量 和环境变量相关的命令 环境变量的组织方式 程序地址空间 冯诺依曼体系结构 关于冯诺依曼&…

Linux 防火墙 iptables

iptables概述 Linux 系统的防火墙 &#xff1a;IP信息包过滤系统&#xff0c;它实际上由两个组件netfilter 和 iptables组成。 主要工作在网络层&#xff0c;针对IP数据包。体现在对包内的IP地址、端口、协议等信息的处理上。 iptables是Linux系统防火墙的一种&#xff0c;是Ce…