16
2025
06

编写QT串口上位机接收stm32串口发送的数据

QT串口上位机的代码

C++
#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    ui->pushButton->setEnabled(false);
    serial=new QSerialPort(this);
    updateSerialPortMenu();
    connect(ui->pushButton,&QPushButton::clicked,this,[=]()
    {
        if(serial->isOpen())
        {
            ui->pushButton->setText("打开串口");
             ui->label->setText("串口"+currentPortName+"已关闭");
            serial->close();
        }else
        {
           serialControl();
        }

    });
    QAction *refreshAction=new QAction("刷新串口",this);
    menuBar()->addAction(refreshAction);
    connect(refreshAction,&QAction::triggered,this,&MainWindow::refreshSerialPortList);
    connect(serial,&QSerialPort::readyRead,this,&MainWindow::readSerialData);
    connect(serial,SIGNAL(error(QSerialPort::SerialPortError)),this,SLOT(handleSerialError(QSerialPort::SerialPortError)));
}

//如果中途出现串口断开的处理槽函数
void MainWindow::handleSerialError(QSerialPort::SerialPortError error)
{

    if(error==QSerialPort::PermissionError)
    {
        ui->pushButton->setText("打开串口");
        ui->label->setText("串口"+currentPortName+"异常关闭");
        serial->close();
    }
}

void MainWindow::readSerialData()//处理单片机传过来的数据的槽函数
{
    QByteArray data =serial->readAll();
    ui->textEdit->append(QString::fromUtf8(data));

}
//刷新串口端口的槽函数
void MainWindow::refreshSerialPortList()
{
    //清除旧菜单项
    for(QAction*action: protactionGroup->actions())
    {
      ui->menuSerialPorts->removeAction(action);
      protactionGroup->removeAction(action);
      delete action;
    }
    //再重新添加扫描到的串口
    const auto ports=QSerialPortInfo::availablePorts();
    for(const QSerialPortInfo &info:ports )
    {
        QAction *protAction=new QAction(info.portName(),this);
        protAction->setCheckable(true);
        protactionGroup->addAction(protAction);
        ui->menuSerialPorts->addAction(protAction);
    }
    ui->menuSerialPorts->setEnabled(true);
    ui->label->setText("串口菜单已刷新");
    ui->pushButton->setText("打开串口");

}

void MainWindow::serialControl()
{
    if(serial->open(QIODevice::ReadWrite))
    {
        serial->clear(QSerialPort::AllDirections);//清除缓冲区,要不然一开始接收的字符可能是乱码
        ui->pushButton->setEnabled(true);
        ui->pushButton->setText("关闭串口");
        ui->textEdit->clear();
        ui->label->setText("串口"+currentPortName+"已打开");
        serial->setBaudRate(QSerialPort::Baud115200);
        serial->setDataBits(QSerialPort::Data8);
        serial->setParity(QSerialPort::NoParity);
        serial->setStopBits(QSerialPort::OneStop);
        serial->setFlowControl(QSerialPort::NoFlowControl);
    }
    else
    {
         ui->label->setText("串口"+currentPortName+"打开失败");
        //弹窗提示
        QMessageBox::information(this,"串口打开失败","无法打开串口"+currentPortName+".\n请检查是否被其他程序占用或不存在.");
    }

}

//当用户选择了对应的串口端口后进行的处理
void MainWindow::onSerialPorSelected(QAction *action)
{

    QString selectedPort = action->text();
    currentPortName=selectedPort;
    serial->setPortName(selectedPort);
    ui->menuSerialPorts->setEnabled(false);
    if(serial->isOpen())
    {
        serial->close();
    }

    serialControl();

}

void MainWindow::updateSerialPortMenu()
{

    ui->menuSerialPorts->clear();//清除旧的菜单栏
    protactionGroup=new QActionGroup(this);//用于管理互斥选择
    protactionGroup->setExclusive(true);
    foreach(const QSerialPortInfo &info,QSerialPortInfo::availablePorts())
    {
        QAction *protAction=new QAction(info.portName(),this);
        protAction->setCheckable(true);
        protactionGroup->addAction(protAction);
        ui->menuSerialPorts->addAction(protAction);
    }

    //连接槽函数:当用户点击某个串口菜单项时
   // connect(protactionGroup,&QActionGroup::triggered,this,&MainWindow::onSerialPorSelected);//这句话用Lambda表示如下:
    connect(protactionGroup,&QActionGroup::triggered,this,[this](QAction *action)
    {
        QString selectSerial=action->text();
        qDebug()<<"select Serial Port:"<<selectSerial;
        this->onSerialPorSelected(action);

    });

}



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

Snipaste_2025-06-15_21-39-58.jpg


stm32的串口代码(使用定时器定时往串口发送数据)

C
#include "timer.h"

uint8_t timer_flag = 0;
void Timer_NVIC(void)
{
	NVIC_InitTypeDef NVIC_InitStructure;

	NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&NVIC_InitStructure); 
}

void Timer_Config(void)
{
	TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
   /* Time Base configuration */
   TIM_TimeBaseStructure.TIM_Prescaler = 7200-1;
   TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
   TIM_TimeBaseStructure.TIM_Period = 10000-1;
   TIM_TimeBaseStructure.TIM_ClockDivision = 0;
   TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
   Timer_NVIC();
   TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);
	/* TIM3 counter enable */
	TIM_Cmd(TIM2, ENABLE);
 	
}

void TIM2_IRQHandler()
{
	if(TIM_GetITStatus(TIM2,TIM_IT_Update)==SET)
	{
		timer_flag=1;
		TIM_ClearITPendingBit(TIM2,TIM_IT_Update);
	}
}


#include "usart.h"  
void Usart_Config(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	USART_InitTypeDef USART_InitStructure;
	/* Enable GPIO clock */
   RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE);
	 

   /* Configure USARTy Rx as input floating */
   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
   GPIO_Init(GPIOA, &GPIO_InitStructure);
   
   /* Configure USARTy Tx as alternate function push-pull */
   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
   GPIO_Init(GPIOA, &GPIO_InitStructure);
		
   USART_InitStructure.USART_BaudRate = 115200;
   USART_InitStructure.USART_WordLength = USART_WordLength_8b;
   USART_InitStructure.USART_StopBits = USART_StopBits_1;
   USART_InitStructure.USART_Parity = USART_Parity_No;
   USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
   USART_InitStructure.USART_Mode = USART_Mode_Rx |USART_Mode_Tx;
   
   /* Configure USARTy */
   USART_Init(USART1, &USART_InitStructure);
 
   /* Enable USARTz */
   USART_Cmd(USART1, ENABLE);

}

void Usart_send(uint8_t ch)
 {
   /* Place your implementation of fputc here */
   /* e.g. write a character to the USART */
   USART_SendData(USART1, (uint8_t) ch);
 
   /* Loop until the end of transmission */
   while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET)
   {}
 
 }
 
 void Usart_sendBuff(uint8_t *buf,uint32_t size)
{
	for(uint32_t i=0;i<size;i++)
	{
		Usart_send(buf[i]);
	}
}

 //¶¨Ê±·¢ËÍ
 void Send_Handle()
 {
 	uint8_t xiao[9]="xiaoxiao";
		if(timer_flag==1)
		{
			timer_flag=0;
			Usart_sendBuff(xiao,sizeof(xiao));
		}
 }

gzh

微信扫码关注

更新实时通知

« 上一篇 下一篇 »

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。