赞
踩
QT串口通信是上位机和下位机通信常用的通信方式,也是学习QT必须学会的基础知识, 这篇就简单介绍一下QT串口通信的简单使用.
1: 创建新项目
2: 配置相关信息
3: 设计界面
4:编写代码
目的: 通过简单实验验证串口通信.
4.1: 配置项目
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);
- }

把下位机代码下到开发板, 然后运行自己编写的上位机, 点击上位机发送数据, 下位机就会把收到的数据返回到上位机, 可以通过控制台查看接收到的数据;
| 简单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;//模拟输入
- 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);
- }
- }
- }

验证:
简单介绍了QT的串口如何与下位机通信, 同时也简单通过shell交互, 进一步拓展了串口通信场景.
粉丝福利,莬费领取Qt开发学习资料包、技术视频,内容包括(Qt实战项目视频教程+代码,C++语言基础,C++设计模式,Qt编程入门,Qt信号与槽机制,Qt界面开发-图像绘制,Qt网络,Qt数据库编程,Qt项目实战,QSS,OpenCV,Quick模块,面试题等等)↓↓↓↓↓↓见下面↓↓文章底部点击莬费领取↓↓
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。