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

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

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给单片机发送指令,单片机收到后会判断是哪一种指令,实行相应的操作。

相关实践学习
消息队列RocketMQ版:基础消息收发功能体验
本实验场景介绍消息队列RocketMQ版的基础消息收发功能,涵盖实例创建、Topic、Group资源创建以及消息收发体验等基础功能模块。
消息队列 MNS 入门课程
1、消息队列MNS简介 本节课介绍消息队列的MNS的基础概念 2、消息队列MNS特性 本节课介绍消息队列的MNS的主要特性 3、MNS的最佳实践及场景应用 本节课介绍消息队列的MNS的最佳实践及场景应用案例 4、手把手系列:消息队列MNS实操讲 本节课介绍消息队列的MNS的实际操作演示 5、动手实验:基于MNS,0基础轻松构建 Web Client 本节课带您一起基于MNS,0基础轻松构建 Web Client
相关文章
|
3天前
|
网络协议 容器
【qt】 TCP编程小项目
【qt】 TCP编程小项目
9 0
|
1月前
stm32f407探索者开发板(十七)——串口寄存器库函数配置方法
stm32f407探索者开发板(十七)——串口寄存器库函数配置方法
168 0
|
5天前
|
NoSQL Linux iOS开发
Clion STM32CubeMX 项目
Clion STM32CubeMX 项目
14 2
|
4天前
【qt】项目移植
【qt】项目移植
5 0
【qt】项目移植
|
11天前
【Qt项目专栏】贪吃蛇小游戏1.0
【Qt项目专栏】贪吃蛇小游戏1.0
28 5
|
3天前
|
数据安全/隐私保护
【qt】考试系统项目
【qt】考试系统项目
10 0
|
4天前
【qt】平面CAD(计算机辅助设计 )项目 上
【qt】平面CAD(计算机辅助设计 )项目 上
5 0
|
6天前
|
XML Linux 程序员
【Qt】项目代码
【Qt】项目代码
|
1月前
STM32CubeMX 串口收发一帧数据
STM32CubeMX 串口收发一帧数据
33 9
|
1月前
|
芯片
STM32CubeMX 串口数据收发
STM32CubeMX 串口数据收发
23 2

推荐镜像

更多