0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看威廉希尔官方网站 视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

QT串口通信的简单使用

玩转单片机 来源:玩转单片机 2024-01-15 09:27 次阅读

QT串口通信上位机和下位机通信常用的通信方式,也是学习QT必须学会的基础知识, 这篇就简单介绍一下QT串口通信的简单使用.

| 创建项目

1: 创建新项目

dbbe5b88-b2bb-11ee-8b88-92fbcf53809c.png

2: 配置相关信息

dbdb6e4e-b2bb-11ee-8b88-92fbcf53809c.png

dbe5f346-b2bb-11ee-8b88-92fbcf53809c.png

dc0a21f8-b2bb-11ee-8b88-92fbcf53809c.png

dc1d1aec-b2bb-11ee-8b88-92fbcf53809c.png

3: 设计界面

dc307b46-b2bb-11ee-8b88-92fbcf53809c.png

dc4b6316-b2bb-11ee-8b88-92fbcf53809c.png

4:编写代码

目的: 通过简单实验验证串口通信.

4.1: 配置项目

dc607878-b2bb-11ee-8b88-92fbcf53809c.png

4.2: 编写上位机代码

widget.h文件

#ifndefWIDGET_H
#defineWIDGET_H

#include
//引入头文件
#include
#include

namespaceUi{
classWidget;
}

classWidget:publicQWidget
{
Q_OBJECT

public:
explicitWidget(QWidget*parent=0);
~Widget();

//定义曹函数
privateslots:
voidon_pushButton_clicked();
voidreceiveInfo();
voidsendInfo();

private:
Ui::Widget*ui;
//串口对象指针
QSerialPort*m_serialPort;
};

#endif//WIDGET_H

widget.cpp文件

#include"widget.h"
#include"ui_widget.h"

//调试输出头文件
#include

Widget::Widget(QWidget*parent):
QWidget(parent),
ui(newUi::Widget)
{
ui->setupUi(this);

//实例化一个串口对象
m_serialPort=newQSerialPort();

//获取可用的串口号
foreach(constQSerialPortInfoinfo,QSerialPortInfo::availablePorts())
{
qDebug()<< "Port name:" << info.portName();
        ui->comboBox->addItem(info.portName());
}
}

Widget::~Widget()
{
deleteui;
}

//pushButton点击触发的槽函数
voidWidget::on_pushButton_clicked()
{
if(m_serialPort->isOpen())//如果串口已经打开了先给他关闭了
{
m_serialPort->clear();
m_serialPort->close();
}

m_serialPort->setPortName(ui->comboBox->currentText());//当前选择的串口名字

if(!m_serialPort->open(QIODevice::ReadWrite))//用ReadWrite的模式尝试打开串口
{
qDebug()<<"打开失败!";
        return;
    }
    qDebug()<<"串口打开成功!";

    m_serialPort->setBaudRate(QSerialPort::Baud115200,QSerialPort::AllDirections);//设置波特率和读写方向
m_serialPort->setDataBits(QSerialPort::Data8);//数据位为8位
m_serialPort->setFlowControl(QSerialPort::NoFlowControl);//无流控制
m_serialPort->setParity(QSerialPort::NoParity);//无校验位
m_serialPort->setStopBits(QSerialPort::OneStop);//一位停止位

//手动绑定槽函数
connect(m_serialPort,SIGNAL(readyRead()),this,SLOT(receiveInfo()));
connect(ui->pushButton_2,SIGNAL(clicked()),this,SLOT(sendInfo()));
}

//接收到单片机发送的数据进行解析
voidWidget::receiveInfo()
{
qDebug()<<"接收";
    QByteArray info = m_serialPort->readAll();

qDebug()<<"receive info:"<write("0x55");
m_serialPort->write("0xaa");
}

4.3: 编写下位机代码

main.c文件

#include"stm32f10x.h"
#include"stdio.h"

voidled_init(void);
voidusart_init(uint32_tbound);

intmain(void)
{
uint32_ti=0;
led_init();
usart_init(115200);
printf("ok
");
while(1)
{
GPIO_ResetBits(GPIOE,GPIO_Pin_5);
for(i=0;i< 0xfffff; i++);
        GPIO_SetBits(GPIOE,GPIO_Pin_5);
        for(i = 0; i< 0xfffff; i++);
    }
}

void led_init(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;//定义结构体变量

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE,ENABLE);

    GPIO_InitStructure.GPIO_Pin=GPIO_Pin_5;  //选择你要设置的IO口
    GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;   //设置推挽输出模式
    GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;   //设置传输速率
    GPIO_Init(GPIOE,&GPIO_InitStructure);      /* 初始化GPIO */

    GPIO_SetBits(GPIOE,GPIO_Pin_5);   //将LED端口拉高,熄灭所有LED
}

void usart_init(uint32_t bound)
{
    //GPIO端口设置
    GPIO_InitTypeDef GPIO_InitStructure;
    USART_InitTypeDef USART_InitStructure;
    NVIC_InitTypeDef NVIC_InitStructure;

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);

    /*  配置GPIO的模式和IO口 */
    GPIO_InitStructure.GPIO_Pin=GPIO_Pin_9;//TX         //串口输出PA9
    GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;      //复用推挽输出
    GPIO_Init(GPIOA,&GPIO_InitStructure);  /* 初始化串口输入IO */
    GPIO_InitStructure.GPIO_Pin=GPIO_Pin_10;//RX       //串口输入PA10
    GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING;      //模拟输入
    GPIO_Init(GPIOA,&GPIO_InitStructure); /* 初始化GPIO */

    //USART1 初始化设置
    USART_InitStructure.USART_BaudRate = bound;//波特率设置
    USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为8位数据格式
    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;  //收发模式
    USART_Init(USART1, &USART_InitStructure); //初始化串口1

    USART_Cmd(USART1, ENABLE);  //使能串口1 

    USART_ClearFlag(USART1, USART_FLAG_TC);

    USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//开启相关中断

    //Usart1 NVIC 配置
    NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;//串口1中断通道
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3;//抢占优先级3
    NVIC_InitStructure.NVIC_IRQChannelSubPriority =3;    //子优先级3
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;      //IRQ通道使能
    NVIC_Init(&NVIC_InitStructure);  //根据指定的参数初始化VIC寄存器
}

int fputc(int ch,FILE *f)   //printf重定向函数
{
    USART_SendData(USART1,(uint8_t)ch);   //发送一字节数据
    while(USART_GetFlagStatus(USART1,USART_FLAG_TXE) == RESET);   //等待发送完成
    return ch;
}

void USART1_IRQHandler(void)
{
    if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)
    {
        uint8_t r = USART_ReceiveData(USART1);
        USART_SendData(USART1,r);
        while(USART_GetFlagStatus(USART1,USART_FLAG_TC) != SET);
    }
    USART_ClearFlag(USART1,USART_FLAG_TC);
}

| 验证效果

把下位机代码下到开发板, 然后运行自己编写的上位机, 点击上位机发送数据, 下位机就会把收到的数据返回到上位机, 可以通过控制台查看接收到的数据;

dc7a3fa6-b2bb-11ee-8b88-92fbcf53809c.png

| 简单shell

main.c文件

#include"stm32f10x.h"
#include"stdio.h"
#include"string.h"

#defineCMD_MAX_LEN16//定义最大命令长度
charcmd_buf[CMD_MAX_LEN];//定义命令缓冲区
uint8_tcmd_len=0;//定义命令长度
uint8_tcmd_flag=0;//定义命令接收完成标志

voidled_init(void);
voidusart_init(uint32_tbound);
voiduser_shell_irq(void);

intmain(void)
{
led_init();
usart_init(115200);
printf("ok
");
while(1)
{
if(cmd_flag)
{
//匹配指令
if(strcmp(cmd_buf,"ledon")==0)
{
printf("ledon");
}
//清理缓存
cmd_len=0;//清零命令长度
memset(cmd_buf,0,CMD_MAX_LEN);//清空命令缓冲区
cmd_flag=0;//清除命令接收完成标志
}
}
}

voidled_init(void)
{
GPIO_InitTypeDefGPIO_InitStructure;//定义结构体变量

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE,ENABLE);

GPIO_InitStructure.GPIO_Pin=GPIO_Pin_5;//选择你要设置的IO口
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;//设置推挽输出模式
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;//设置传输速率
GPIO_Init(GPIOE,&GPIO_InitStructure);/*初始化GPIO*/

GPIO_SetBits(GPIOE,GPIO_Pin_5);//将LED端口拉高,熄灭所有LED
}

voidusart_init(uint32_tbound)
{
//GPIO端口设置
GPIO_InitTypeDefGPIO_InitStructure;
USART_InitTypeDefUSART_InitStructure;
NVIC_InitTypeDefNVIC_InitStructure;

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);

/*配置GPIO的模式和IO口*/
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_9;//TX//串口输出PA9
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;//复用推挽输出
GPIO_Init(GPIOA,&GPIO_InitStructure);/*初始化串口输入IO*/
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_10;//RX//串口输入PA10
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING;//interwetten与威廉的赔率体系
输入
GPIO_Init(GPIOA,&GPIO_InitStructure);/*初始化GPIO*/

//USART1初始化设置
USART_InitStructure.USART_BaudRate=bound;//波特率设置
USART_InitStructure.USART_WordLength=USART_WordLength_8b;//字长为8位数据格式
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;//收发模式
USART_Init(USART1,&USART_InitStructure);//初始化串口1

USART_Cmd(USART1,ENABLE);//使能串口1

USART_ClearFlag(USART1,USART_FLAG_TC);

USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);//开启相关中断

//Usart1NVIC配置
NVIC_InitStructure.NVIC_IRQChannel=USART1_IRQn;//串口1中断通道
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3;//抢占优先级3
NVIC_InitStructure.NVIC_IRQChannelSubPriority=3;//子优先级3
NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;//IRQ通道使能
NVIC_Init(&NVIC_InitStructure);//根据指定的参数初始化VIC寄存器
}

intfputc(intch,FILE*f)//printf重定向函数
{
USART_SendData(USART1,(uint8_t)ch);//发送一字节数据
while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET);//等待发送完成
returnch;
}

voidUSART1_IRQHandler(void)
{
if(USART_GetITStatus(USART1,USART_IT_RXNE)!=RESET)
{
//shell
user_shell_irq();
}
}

//获取
voiduser_shell_irq(void)
{
uint8_ttemp=USART_ReceiveData(USART1);
if(temp=='
'||temp=='
')
{
cmd_buf[cmd_len]='�';
cmd_flag=1;
}
else
{
cmd_buf[cmd_len++]=temp;
if(cmd_len>=CMD_MAX_LEN)
{
//清理缓存
cmd_len=0;
memset(cmd_buf,0,CMD_MAX_LEN);
}
}
}

验证:

dc964d36-b2bb-11ee-8b88-92fbcf53809c.png

简单介绍了QT的串口如何与下位机通信, 同时也简单通过shell交互, 进一步拓展了串口通信场景.

审核编辑:汤梓红

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 串口通信
    +关注

    关注

    34

    文章

    1622

    浏览量

    55476
  • 上位机
    +关注

    关注

    27

    文章

    940

    浏览量

    54766
  • Qt
    Qt
    +关注

    关注

    1

    文章

    301

    浏览量

    37868
  • 下位机
    +关注

    关注

    0

    文章

    94

    浏览量

    18745

原文标题:QT|串口通信

文章出处:【微信号:玩转单片机,微信公众号:玩转单片机】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    基于QT串口调试工具设计

    串口通信是我们经常会遇到的问题。很多时候当我们设计一个串口应用时,我们希望有一个简便的、可视的方式来验证它。这一篇中我们就来基于QT设计一个串口
    的头像 发表于 12-13 14:37 2256次阅读
    基于<b class='flag-5'>QT</b>的<b class='flag-5'>串口</b>调试工具设计

    QT串口通信的相关资料推荐

    QT通信-串口通信前言一、串口搜索二、打开串口二、发送或接收数据二、程序如下:总结前言
    发表于 01-11 07:56

    Qt串口通信专题教程

    这是一个关于在Qt Creator下进行串口通信软件开发的专题教程,能够帮助你快速的开发有关的串口应用。
    发表于 05-04 14:37 24次下载

    基于Qt串口通信应用研究与实现严贤

    基于Qt串口通信应用研究与实现_严贤
    发表于 03-17 08:00 3次下载

    利用QT 串口通信进行RS232协议开发

    QT串口通信协议代码最近在研究用串口通信去发送协议指令控制相机工作,因为是第一次接触串口,期间也
    发表于 01-14 10:05 3次下载
    利用<b class='flag-5'>QT</b> <b class='flag-5'>串口</b><b class='flag-5'>通信</b>进行RS232协议开发

    基于Qt实现的串口示波器

    摘要:逛github时看到这个QT串口示波器,完全开源,支持串口、TCP、波形显示、通信协议。感觉很不错,跟以前分享的那个vofa+有点像。感兴趣的可以下载下来学习学习。
    的头像 发表于 06-12 15:34 3708次阅读

    基于QT串口小助手开发

    QT开发一个串口小助手,要求能实现串口接收,发送等基本功能。
    的头像 发表于 04-04 15:07 2101次阅读
    基于<b class='flag-5'>QT</b>的<b class='flag-5'>串口</b>小助手开发

    QT与三菱PLC串口通信

    最近两天在学习QT与三菱PLC串口通信,特此记录下来。 通信格式 我这里使用RS-232C连接的,根据FX编程口协议! 设置参数,以读写的方式打开
    发表于 04-17 16:08 0次下载
    <b class='flag-5'>QT</b>与三菱PLC<b class='flag-5'>串口</b><b class='flag-5'>通信</b>

    Qt实现串口通信

    要实现串口通信,需要知道串口通信需要的信息
    的头像 发表于 04-23 17:34 3966次阅读
    <b class='flag-5'>Qt</b>实现<b class='flag-5'>串口</b><b class='flag-5'>通信</b>

    基于QT简单的上位机

    。同样的,我们也从编写一个简单的基于QT的上位机来体会体会上位机开发及认识认识QT。我们本次实现的上位机的功能很简单:上位机通过串口来控制开
    发表于 05-08 10:57 16次下载
    基于<b class='flag-5'>QT</b>的<b class='flag-5'>简单</b>的上位机

    QTQT上位机串口编程

    QTQT上位机串口编程 最近因为项目需要,需要用到上位机,通过串口与上位机进行通讯,来上传和下发一些数据以及控制指令,所以用QT写了一
    发表于 05-08 10:02 25次下载
    <b class='flag-5'>QT</b>篇<b class='flag-5'>QT</b>上位机<b class='flag-5'>串口</b>编程

    QT实现简单的上位机软件

    最近项目要求写上位机软件,需要实现界面功能和串口读写。界面方面用过MFC(早忘记了),网上查阅资料后发现QT在5.1版本后有自带的串口模块,而且用QT实现
    发表于 05-08 09:54 4次下载
    <b class='flag-5'>QT</b>实现<b class='flag-5'>简单</b>的上位机软件

    QT5串口编程——编写简单的上位机

    下面开始介绍串口类的使用。 首先,QT5是自带QSerialPort这个类的,使用时需要在pro文件里面添加一行: ​然后直接引用头文件就可以了。 ​在QT5中,串口
    发表于 05-10 14:28 0次下载
    <b class='flag-5'>QT</b>5<b class='flag-5'>串口</b>编程——编写<b class='flag-5'>简单</b>的上位机

    Qt5实现上位机与串口通信

    Qt助手内搜索:Qt Serial Port为串口的相关函数  1.添加串口头文件: # include //使用串口功能# inc
    发表于 05-10 10:46 0次下载
    <b class='flag-5'>Qt</b>5实现上位机与<b class='flag-5'>串口</b><b class='flag-5'>通信</b>

    STM32单片机如何处理QT上位机串口中发过来的数据?

    数据传输的通信方式。串口通信是一种简单、稳定、可靠的通信方式,其原理是通过串口发送端口将数据转换
    的头像 发表于 09-14 14:22 3115次阅读