当前位置:   article > 正文

Qt串口通信的简单使用_qt上位机串口通信教程

qt上位机串口通信教程

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

| 创建项目

1: 创建新项目


2: 配置相关信息

 

3: 设计界面

 
4:编写代码

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

4.1: 配置项目

4.2: 编写上位机代码

widget.h文件

  1. #ifndefWIDGET_H
  2. #defineWIDGET_H
  3. #include
  4. //引入头文件
  5. #include
  6. #include
  7. namespaceUi{
  8. classWidget;
  9. }
  10. classWidget:publicQWidget
  11. {
  12. Q_OBJECT
  13. public:
  14. explicitWidget(QWidget*parent=0);
  15. ~Widget();
  16. //定义曹函数
  17. privateslots:
  18. voidon_pushButton_clicked();
  19. voidreceiveInfo();
  20. voidsendInfo();
  21. private:
  22. Ui::Widget*ui;
  23. //串口对象指针
  24. QSerialPort*m_serialPort;
  25. };
  26. #endif//WIDGET_H

widget.cpp文件

  1. #include"widget.h"
  2. #include"ui_widget.h"
  3. //调试输出头文件
  4. #include
  5. Widget::Widget(QWidget*parent):
  6. QWidget(parent),
  7. ui(newUi::Widget)
  8. {
  9. ui->setupUi(this);
  10. //实例化一个串口对象
  11. m_serialPort=newQSerialPort();
  12. //获取可用的串口号
  13. foreach(constQSerialPortInfoinfo,QSerialPortInfo::availablePorts())
  14. {
  15. qDebug()<< "Port name:" << info.portName();
  16. ui->comboBox->addItem(info.portName());
  17. }
  18. }
  19. Widget::~Widget()
  20. {
  21. deleteui;
  22. }
  23. //pushButton点击触发的槽函数
  24. voidWidget::on_pushButton_clicked()
  25. {
  26. if(m_serialPort->isOpen())//如果串口已经打开了先给他关闭了
  27. {
  28. m_serialPort->clear();
  29. m_serialPort->close();
  30. }
  31. m_serialPort->setPortName(ui->comboBox->currentText());//当前选择的串口名字
  32. if(!m_serialPort->open(QIODevice::ReadWrite))//用ReadWrite的模式尝试打开串口
  33. {
  34. qDebug()<<"打开失败!";
  35. return;
  36. }
  37. qDebug()<<"串口打开成功!";
  38. m_serialPort->setBaudRate(QSerialPort::Baud115200,QSerialPort::AllDirections);//设置波特率和读写方向
  39. m_serialPort->setDataBits(QSerialPort::Data8);//数据位为8
  40. m_serialPort->setFlowControl(QSerialPort::NoFlowControl);//无流控制
  41. m_serialPort->setParity(QSerialPort::NoParity);//无校验位
  42. m_serialPort->setStopBits(QSerialPort::OneStop);//一位停止位
  43. //手动绑定槽函数
  44. connect(m_serialPort,SIGNAL(readyRead()),this,SLOT(receiveInfo()));
  45. connect(ui->pushButton_2,SIGNAL(clicked()),this,SLOT(sendInfo()));
  46. }
  47. //接收到单片机发送的数据进行解析
  48. voidWidget::receiveInfo()
  49. {
  50. qDebug()<<"接收";
  51. QByteArray info = m_serialPort->readAll();
  52. qDebug()<<"receive info:"<write("0x55");
  53. m_serialPort->write("0xaa");
  54. }

4.3: 编写下位机代码

main.c文件

  1. #include"stm32f10x.h"
  2. #include"stdio.h"
  3. voidled_init(void);
  4. voidusart_init(uint32_tbound);
  5. intmain(void)
  6. {
  7. uint32_ti=0;
  8. led_init();
  9. usart_init(115200);
  10. printf("ok
  11. ");
  12. while(1)
  13. {
  14. GPIO_ResetBits(GPIOE,GPIO_Pin_5);
  15. for(i=0;i< 0xfffff; i++);
  16. GPIO_SetBits(GPIOE,GPIO_Pin_5);
  17. for(i = 0; i< 0xfffff; i++);
  18. }
  19. }
  20. void led_init(void)
  21. {
  22. GPIO_InitTypeDef GPIO_InitStructure;//定义结构体变量
  23. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE,ENABLE);
  24. GPIO_InitStructure.GPIO_Pin=GPIO_Pin_5; //选择你要设置的IO口
  25. GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP; //设置推挽输出模式
  26. GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz; //设置传输速率
  27. GPIO_Init(GPIOE,&GPIO_InitStructure); /* 初始化GPIO */
  28. GPIO_SetBits(GPIOE,GPIO_Pin_5); //将LED端口拉高,熄灭所有LED
  29. }
  30. void usart_init(uint32_t bound)
  31. {
  32. //GPIO端口设置
  33. GPIO_InitTypeDef GPIO_InitStructure;
  34. USART_InitTypeDef USART_InitStructure;
  35. NVIC_InitTypeDef NVIC_InitStructure;
  36. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
  37. RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
  38. /* 配置GPIO的模式和IO口 */
  39. GPIO_InitStructure.GPIO_Pin=GPIO_Pin_9;//TX //串口输出PA9
  40. GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
  41. GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP; //复用推挽输出
  42. GPIO_Init(GPIOA,&GPIO_InitStructure); /* 初始化串口输入IO */
  43. GPIO_InitStructure.GPIO_Pin=GPIO_Pin_10;//RX //串口输入PA10
  44. GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING; //模拟输入
  45. GPIO_Init(GPIOA,&GPIO_InitStructure); /* 初始化GPIO */
  46. //USART1 初始化设置
  47. USART_InitStructure.USART_BaudRate = bound;//波特率设置
  48. USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为8位数据格式
  49. USART_InitStructure.USART_StopBits = USART_StopBits_1;//一个停止位
  50. USART_InitStructure.USART_Parity = USART_Parity_No;//无奇偶校验位
  51. USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//无硬件数据流控制
  52. USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //收发模式
  53. USART_Init(USART1, &USART_InitStructure); //初始化串口1
  54. USART_Cmd(USART1, ENABLE); //使能串口1
  55. USART_ClearFlag(USART1, USART_FLAG_TC);
  56. USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//开启相关中断
  57. //Usart1 NVIC 配置
  58. NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;//串口1中断通道
  59. NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3;//抢占优先级3
  60. NVIC_InitStructure.NVIC_IRQChannelSubPriority =3; //子优先级3
  61. NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能
  62. NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化VIC寄存器
  63. }
  64. int fputc(int ch,FILE *f) //printf重定向函数
  65. {
  66. USART_SendData(USART1,(uint8_t)ch); //发送一字节数据
  67. while(USART_GetFlagStatus(USART1,USART_FLAG_TXE) == RESET); //等待发送完成
  68. return ch;
  69. }
  70. void USART1_IRQHandler(void)
  71. {
  72. if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)
  73. {
  74. uint8_t r = USART_ReceiveData(USART1);
  75. USART_SendData(USART1,r);
  76. while(USART_GetFlagStatus(USART1,USART_FLAG_TC) != SET);
  77. }
  78. USART_ClearFlag(USART1,USART_FLAG_TC);
  79. }

验证效果

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

| 简单shell

main.c文件

  1. #include"stm32f10x.h"
  2. #include"stdio.h"
  3. #include"string.h"
  4. #defineCMD_MAX_LEN16//定义最大命令长度
  5. charcmd_buf[CMD_MAX_LEN];//定义命令缓冲区
  6. uint8_tcmd_len=0;//定义命令长度
  7. uint8_tcmd_flag=0;//定义命令接收完成标志
  8. voidled_init(void);
  9. voidusart_init(uint32_tbound);
  10. voiduser_shell_irq(void);
  11. intmain(void)
  12. {
  13. led_init();
  14. usart_init(115200);
  15. printf("ok
  16. ");
  17. while(1)
  18. {
  19. if(cmd_flag)
  20. {
  21. //匹配指令
  22. if(strcmp(cmd_buf,"ledon")==0)
  23. {
  24. printf("ledon");
  25. }
  26. //清理缓存
  27. cmd_len=0;//清零命令长度
  28. memset(cmd_buf,0,CMD_MAX_LEN);//清空命令缓冲区
  29. cmd_flag=0;//清除命令接收完成标志
  30. }
  31. }
  32. }
  33. voidled_init(void)
  34. {
  35. GPIO_InitTypeDefGPIO_InitStructure;//定义结构体变量
  36. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE,ENABLE);
  37. GPIO_InitStructure.GPIO_Pin=GPIO_Pin_5;//选择你要设置的IO口
  38. GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;//设置推挽输出模式
  39. GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;//设置传输速率
  40. GPIO_Init(GPIOE,&GPIO_InitStructure);/*初始化GPIO*/
  41. GPIO_SetBits(GPIOE,GPIO_Pin_5);//将LED端口拉高,熄灭所有LED
  42. }
  43. voidusart_init(uint32_tbound)
  44. {
  45. //GPIO端口设置
  46. GPIO_InitTypeDefGPIO_InitStructure;
  47. USART_InitTypeDefUSART_InitStructure;
  48. NVIC_InitTypeDefNVIC_InitStructure;
  49. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
  50. RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
  51. /*配置GPIO的模式和IO口*/
  52. GPIO_InitStructure.GPIO_Pin=GPIO_Pin_9;//TX//串口输出PA9
  53. GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
  54. GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;//复用推挽输出
  55. GPIO_Init(GPIOA,&GPIO_InitStructure);/*初始化串口输入IO*/
  56. GPIO_InitStructure.GPIO_Pin=GPIO_Pin_10;//RX//串口输入PA10
  57. GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING;//模拟输入
  58. GPIO_Init(GPIOA,&GPIO_InitStructure);/*初始化GPIO*/
  59. //USART1初始化设置
  60. USART_InitStructure.USART_BaudRate=bound;//波特率设置
  61. USART_InitStructure.USART_WordLength=USART_WordLength_8b;//字长为8位数据格式
  62. USART_InitStructure.USART_StopBits=USART_StopBits_1;//一个停止位
  63. USART_InitStructure.USART_Parity=USART_Parity_No;//无奇偶校验位
  64. USART_InitStructure.USART_HardwareFlowControl=USART_HardwareFlowControl_None;//无硬件数据流控制
  65. USART_InitStructure.USART_Mode=USART_Mode_Rx|USART_Mode_Tx;//收发模式
  66. USART_Init(USART1,&USART_InitStructure);//初始化串口1
  67. USART_Cmd(USART1,ENABLE);//使能串口1
  68. USART_ClearFlag(USART1,USART_FLAG_TC);
  69. USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);//开启相关中断
  70. //Usart1NVIC配置
  71. NVIC_InitStructure.NVIC_IRQChannel=USART1_IRQn;//串口1中断通道
  72. NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3;//抢占优先级3
  73. NVIC_InitStructure.NVIC_IRQChannelSubPriority=3;//子优先级3
  74. NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;//IRQ通道使能
  75. NVIC_Init(&NVIC_InitStructure);//根据指定的参数初始化VIC寄存器
  76. }
  77. intfputc(intch,FILE*f)//printf重定向函数
  78. {
  79. USART_SendData(USART1,(uint8_t)ch);//发送一字节数据
  80. while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET);//等待发送完成
  81. returnch;
  82. }
  83. voidUSART1_IRQHandler(void)
  84. {
  85. if(USART_GetITStatus(USART1,USART_IT_RXNE)!=RESET)
  86. {
  87. //shell
  88. user_shell_irq();
  89. }
  90. }
  91. //获取
  92. voiduser_shell_irq(void)
  93. {
  94. uint8_ttemp=USART_ReceiveData(USART1);
  95. if(temp=='
  96. '||temp=='
  97. ')
  98. {
  99. cmd_buf[cmd_len]='�';
  100. cmd_flag=1;
  101. }
  102. else
  103. {
  104. cmd_buf[cmd_len++]=temp;
  105. if(cmd_len>=CMD_MAX_LEN)
  106. {
  107. //清理缓存
  108. cmd_len=0;
  109. memset(cmd_buf,0,CMD_MAX_LEN);
  110. }
  111. }
  112. }

验证:

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

粉丝福利,费领取Qt开发学习资料包、技术视频,内容包括(Qt实战项目视频教程+代码,C++语言基础,C++设计模式,Qt编程入门,Qt信号与槽机制,Qt界面开发-图像绘制,Qt网络,Qt数据库编程,Qt项目实战,QSS,OpenCV,Quick模块,面试题等等)↓↓↓↓↓↓见下面↓↓文章底部点击费领取↓↓

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Guff_9hys/article/detail/979412
推荐阅读
相关标签
  

闽ICP备14008679号