在Qt5之前,串口通信基本依赖于第三方库,下面是我曾接触过的串口通信类库:

名称

语言

平台

 

QextSerialPort

QT C++

Win/Linux

http://sourceforge.net/projects/qextserialport/files/

QSerialPort

QT C++

QT5已经集成

libserial

C++

Linux

http://files.cnblogs.com/kyyblabla/libserial-0.5.2.gz.7z

  以上串口通信类库通信过程基本是一下步骤,即:打开串口 > 配置串口参数 > 收发数据。

  注意,串口参数(波特率、数据位、停止位、奇偶校验、流控等)必须在串口打开之后进行配置才有效。

  在使用串口接收数据时,会出现数据接收不完整的情况,这种情况很常见,尤其是在 QextSerialPort 和 QSerialPort 中,有一段时间我不得不怀疑是不是参数或者是硬件问题。后来发现这并不是异常,在通信中我依赖 readAll() 函数获取串口数据,但 readAll() 由 readyRead()信号触发,readyRead在串口读到起始标志时立即发送,并不一保证一定是当前所发数据的起始部分。因此串口通信双方通信前应制定好通信协议,规定好数据的起始于结尾标志,串口当读到完整的起始于结束标志之后,才认定读完一条完整的数据。

  下面分别就这三种串口通信类库进行实例代码的编写。

QextSerialPort使用小例

  QextSerialPort在Window平台下可用Win_QextSerialPort进行串口通信,下面对Win_QextSerialPort再一次封装的串口通信类SerialPort:

  头文件:serialport.h

  1. #ifndef SERIALPORT_H
  2. #define SERIALPORT_H
  3.  
  4. #include <QObject>
  5.  
  6. /**
  7. * @brief 串口参数
  8. */
  9. struct SerialConfig{
  10. int baudRate; //波特率
  11. int characterSize; //传输位
  12. int stopBits; //停止位
  13. int parity; //校验位 0无校验 1奇校验 2偶校验
  14. //char*serialPort[20]; //设备文件名
  15. int flowControl; //流控
  16. long timeOut; //超时时间
  17. };
  18.  
  19. class Win_QextSerialPort;
  20.  
  21. /**
  22. * @brief 串口通信类
  23. */
  24. class SerialPort : public QObject
  25. {
  26. Q_OBJECT
  27. public:
  28.  
  29. explicit SerialPort(QString portName, QObject *parent = );
  30. //~SerialPort();
  31.  
  32. /**
  33. * @brief 串口数据大发送格式
  34. */
  35. enum SerialDataType{
  36. ASCLL=, //ascll方式
  37. HEX //二进制方式
  38. };
  39. /**
  40. * @brief 配置串口参数
  41. * @param config
  42. */
  43. void setSerila(SerialConfig *config);
  44.  
  45. /**
  46. * @brief 获取串口开启状态
  47. * @return
  48. */
  49. bool isOpend();
  50.  
  51. /**
  52. * @brief 设置数据发送方式
  53. * @param type
  54. */
  55. void setSerialDataType(SerialDataType type);
  56. signals:
  57. /**
  58. * @brief 串口获取到数据
  59. */
  60. void strSerial(QString);
  61. public slots:
  62.  
  63. /**
  64. * @brief 开启串口
  65. * @param 串口参数
  66. * @return 是否成功打开串口
  67. */
  68. bool openSerial(SerialConfig *config);
  69.  
  70. /**
  71. * @brief 关闭串口
  72. */
  73. void closeSerial();
  74.  
  75. /**
  76. * @brief 写入数据到串口,系统默认是ascll方式
  77. * @param str 待写入数据
  78. */
  79. void writeSerial(QString str);
  80. private slots:
  81. /**
  82. * @brief 读取数据
  83. */
  84. void readSerial();
  85. private:
  86. /**
  87. * @brief 基本串口通信类
  88. */
  89. Win_QextSerialPort*serial;
  90.  
  91. /**
  92. * @brief 数据发送形式
  93. */
  94. SerialDataType serialDataType;
  95.  
  96. };
  97.  
  98. #endif // SERIALPORT_H

  源文件:serialport.cpp

  1. #include "serialport.h"
  2. #include "serial_inc/win_qextserialport.h"
  3.  
  4. #include <QDebug>
  5.  
  6. SerialPort::SerialPort(QString portName,QObject *parent):QObject(parent),serialDataType(HEX)
  7. {
  8.  
  9. this->serial=new Win_QextSerialPort(portName, QextSerialBase::EventDriven);
  10. connect(serial,SIGNAL(readyRead()),this,SLOT(readSerial()));
  11.  
  12. }
  13.  
  14. void SerialPort::setSerila(SerialConfig *config)
  15. {
  16.  
  17. //波特率
  18. BaudRateType baudRate;
  19.  
  20. switch (config->baudRate) {
  21. case :
  22. baudRate=BAUD9600;
  23. break;
  24. case :
  25. baudRate=BAUD115200;
  26. break;
  27. default:
  28. baudRate=BAUD4800;
  29. break;
  30. }
  31.  
  32. //数据位
  33. DataBitsType dataBits;
  34. switch (config->characterSize) {
  35. case :
  36. dataBits=DATA_7;
  37. break;
  38. default:
  39. dataBits=DATA_8;
  40. break;
  41. }
  42.  
  43. //停止位
  44. StopBitsType stopBits;
  45. switch (config->stopBits) {
  46. case :
  47. stopBits=STOP_1;
  48. break;
  49. case :
  50. stopBits=STOP_2;
  51. break;
  52. default:
  53. stopBits=STOP_1_5;
  54. break;
  55. }
  56.  
  57. //奇偶校验
  58. ParityType parity;
  59. switch (config->parity) {
  60. case :
  61. parity=PAR_NONE;
  62. break;
  63. case :
  64. parity=PAR_ODD;
  65. break;
  66. default:
  67. parity=PAR_EVEN;
  68. break;
  69. }
  70.  
  71. //数据流控
  72. FlowType flow=FLOW_OFF;
  73.  
  74. serial->setBaudRate(baudRate);
  75. serial->setDataBits(dataBits);
  76. serial->setStopBits(stopBits);
  77. serial->setParity(parity);
  78. serial->setFlowControl(flow);
  79.  
  80. serial->setDtr(false);
  81. serial->setRts(false);
  82.  
  83. }
  84.  
  85. bool SerialPort::isOpend()
  86. {
  87. return this->serial!=NULL?serial->isOpen():false;
  88. }
  89.  
  90. void SerialPort::setSerialDataType(SerialPort::SerialDataType type)
  91. {
  92. this->serialDataType=type;
  93. }
  94.  
  95. void SerialPort::writeSerial(QString str)
  96. {
  97.  
  98. if(this->serialDataType==this->ASCLL){
  99. serial->write(str.toLocal8Bit());
  100. }else{
  101.  
  102. QByteArray b;
  103. b=QByteArray::fromHex(str.toUtf8());
  104. serial->write(b);
  105. }
  106.  
  107. }
  108.  
  109. void SerialPort::readSerial()
  110. {
  111.  
  112. qDebug()<<serial->bytesAvailable();
  113.  
  114. QString str="";
  115.  
  116. QByteArray array=serial->readAll();
  117.  
  118. if(this->serialDataType==SerialPort::ASCLL){
  119. str=QString::fromLocal8Bit(array.data());
  120. }else{
  121. array=array.toHex();
  122. str=QString::fromUtf8(array.data());
  123. }
  124.  
  125. str=str.trimmed();
  126.  
  127. qDebug()<<"serial get:"<<str;
  128.  
  129. emit this->strSerial(str);
  130.  
  131. }
  132.  
  133. /**打开
  134. * @brief SerialPort::openSerial
  135. * @return
  136. */
  137. bool SerialPort::openSerial(SerialConfig*config)
  138. {
  139.  
  140. bool isOpen=serial->open(QIODevice::ReadWrite);
  141.  
  142. qDebug()<<"isOpen:"<<isOpen;
  143. //如果已经成功打开串口,则经行串口参数配置
  144. //这里有一个概念:串口配置必须在串口设备成功打开后才有效!
  145. if(isOpen){
  146. this->setSerila(config);
  147. }
  148.  
  149. return isOpen;
  150. }
  151.  
  152. void SerialPort::closeSerial()
  153. {
  154. serial->close();
  155.  
  156. }

QSerialPort 使用小例

  QSerialPort通信方式与 Win_QextSerialPort方式类似。

  串口初始化代码片段:

  1. QSerialPort serial=new QSerialPort(this);
  2.  
  3. connect(serial, SIGNAL(readyRead()), this, SLOT(readData()));
  4.  
  5. serial->setPortName("COM4");
  6. serial->setBaudRate();
  7. serial->setDataBits(QSerialPort::Data8);
  8. serial->setParity(QSerialPort::NoParity);
  9. serial->setStopBits(QSerialPort::OneStop);
  10. serial->setFlowControl(QSerialPort::NoFlowControl);
  11. if (serial->open(QIODevice::ReadWrite)) {
  12.  
  13. qDebug()<<"yes";
  14.  
  15. } else {
  16.  
  17. qDebug()<<"no";
  18. }

  数据接收函数:

  1. void QPort::readData()
  2. {
  3. QByteArray data = serial->readAll();
  4. qDebug()<<data;
  5.  
  6. }

libserial使用小例

  libserial只使用于Linux平台,下载源码后,进行编译和安装。下面是封装的串口通信类 Serial:

  头文件:serial.h

  1. #ifndef SERIAL_H
  2. #define SERIAL_H
  3.  
  4. #include "common.h"
  5. #include "SerialStream.h"
  6. #include "SerialStreamBuf.h"
  7. #include <QObject>
  8.  
  9. using namespace std;
  10. using namespace LibSerial;
  11.  
  12. typedef struct
  13. {
  14. int baudRate; //!<波特率
  15. int characterSize; //!<传输位
  16. int stopBits; //!<停止位
  17. int parity; //!校验位 0无校验 1奇校验 2偶校验
  18. char*serialPort; //!设备文件名
  19.  
  20. }SerialConfig;
  21.  
  22. class Serial : public QObject
  23. {
  24. Q_OBJECT
  25. public:
  26. explicit Serial(QObject *parent = );
  27.  
  28. signals:
  29.  
  30. void message(QString msg);
  31. public slots:
  32. //打开串口
  33. bool open(SerialConfig*config);
  34. void work();
  35. void close();
  36. void sendMesg(QString msg);
  37. private slots:
  38.  
  39. private:
  40. /**
  41. * @brief 初始化串口数据
  42. * @param config
  43. */
  44. void initSerialStream(SerialConfig*config);
  45.  
  46. /**
  47. * @brief 串口字节流
  48. */
  49. SerialStream serialStream;
  50.  
  51. bool isRuning;
  52. };
  53.  
  54. #endif // SERIAL_H

  源文件:serial.cpp

  1. #include "serial.h"
  2.  
  3. //数据开始标示
  4. #define SERIAL_DATA_START 2
  5.  
  6. //数据结束标示
  7. #define SERIAL_DATA_END 3
  8.  
  9. Serial::Serial(QObject *parent) :
  10. QObject(parent)
  11. {
  12. }
  13.  
  14. bool Serial::open(SerialConfig *config){
  15.  
  16. serialStream.Open(config->serialPort);
  17.  
  18. if(!serialStream.IsOpen())
  19. {
  20. qDebug()<<"cannot open serial "<<config->serialPort;
  21. return false;
  22. }else{
  23.  
  24. qDebug()<<"success open serial "<<config->serialPort;
  25. }
  26.  
  27. initSerialStream(config);
  28.  
  29. return true;
  30.  
  31. }
  32.  
  33. void Serial::work(){
  34.  
  35. //缓存数据
  36. char *msg = new char[];
  37. int index = ;
  38. char next_byte ; //串口接收到的下一个字节
  39. this->isRuning=true;
  40. forever{
  41. //
  42. if(this->isRuning==false){
  43. break;
  44. }
  45.  
  46. serialStream.get( next_byte );
  47.  
  48. int char_num=next_byte+;
  49.  
  50. if(char_num<){
  51. qDebug()<<":"<<next_byte+;
  52. }else{
  53. qDebug()<<next_byte;
  54. }
  55.  
  56. if(char_num!=SERIAL_DATA_END)
  57. {
  58. if(char_num==SERIAL_DATA_START){
  59. index=;
  60. continue;
  61. }
  62.  
  63. msg[index] = next_byte;
  64. index++;
  65. }
  66. else
  67. {
  68. msg[index] = '\0';
  69. index = ;
  70. qDebug("%s",msg);
  71. emit message(QString(msg).trimmed());
  72. }
  73. }
  74. }
  75.  
  76. void Serial::close(){
  77.  
  78. this->isRuning=false;
  79. }
  80.  
  81. void Serial::sendMesg(QString msg)
  82. {
  83. msg.insert(,);
  84. msg.append();
  85.  
  86. char*cmsg =msg.toUtf8().data();
  87. serialStream.write(cmsg,strlen(cmsg));
  88.  
  89. }
  90.  
  91. void Serial::initSerialStream(SerialConfig *config)
  92. {
  93.  
  94. SerialStreamBuf::BaudRateEnum baudRate;
  95.  
  96. switch (config->baudRate) {
  97. case :
  98. baudRate=SerialStreamBuf::BAUD_9600;
  99. break;
  100. case :
  101. baudRate=SerialStreamBuf::BAUD_115200;
  102. break;
  103. default:
  104. baudRate=SerialStreamBuf::BAUD_4800;
  105. break;
  106. }
  107.  
  108. SerialStreamBuf::CharSizeEnum characterSize;
  109. switch (config->characterSize) {
  110. case :
  111. characterSize=SerialStreamBuf::CHAR_SIZE_7;
  112. break;
  113. default:
  114. characterSize=SerialStreamBuf::CHAR_SIZE_8;
  115. break;
  116. }
  117.  
  118. SerialStreamBuf::ParityEnum parity;
  119. switch (config->characterSize) {
  120. case :
  121. parity=SerialStreamBuf::PARITY_NONE;
  122. break;
  123. case :
  124. parity=SerialStreamBuf::PARITY_ODD;
  125. break;
  126. default:
  127. parity=SerialStreamBuf::PARITY_EVEN;
  128. break;
  129. }
  130.  
  131. serialStream.SetBaudRate(baudRate);
  132. serialStream.SetCharSize(characterSize);
  133. serialStream.SetNumOfStopBits(config->stopBits);
  134. serialStream.SetParity(parity);
  135. }

Qt 串口通信的更多相关文章

  1. Qt串口通信

    1. Qt串口通信类QSerialPort 在Qt5的的更新中,新增了串口通信的相关接口类QSerialPort,这使得在开发者在使用Qt进行UI开发时,可以更加简单有效地实现串口通信的相关功能. 开 ...

  2. linux下的qt串口通信

    1.linux下的qt串口通信跟windows唯一的差别就是端口号的名字,windows下面是COM,而linux是ttyUSB0的路径 2.一般情况下linux插上USB转串口线就可以在/dev/目 ...

  3. Linux 虚拟串口及 Qt 串口通信实例

    Linux 虚拟串口及 Qt 串口通信实例 2011-06-22 17:49 佚名 互联网 字号:T | T Linux 虚拟串口及 Qt 串口通信实例是本文所要介绍的内容,在实现过程中,打开了两个伪 ...

  4. QT串口通信编程

    QT串口编程 文件夹目录结构如下图所示 设计的示例界面如下图所示 首先在项目文件里面添加一句 QT += serialport SerialPortDemo.pro文件如下: #----------- ...

  5. Qt 串口通信之使用16进制发送数据的转换方式

    Qt 串口通信之使用16进制发送数据的转换方式 一 概述 有时候在做上位机串口通讯时,经常需要将字符串转成16进制的形式作为发送,借此分析记录一下. 二 需求分析 //假设需要转换的字符:如下 QSt ...

  6. QT 串口通信 数据16进制发送

    在QT中进行串口通信时,很多情况要用到发送16进制的数据.从网上找来了一段代码测试能用: static QByteArray QString2Hex(QString str) { QByteArray ...

  7. Qt串口通信专题教程

    查看以前的教程:Qt编写串口通信程序全程图文讲解 查看Wincom和Lincom介绍:Qt跨平台串口通信软件Wincom与Lincom 下载软件,文档和源码:资源下载 ——————————————20 ...

  8. Qt 串口通信 高速发送出错的解决方法总结

    使用网上的qextserialport-1.2类,自行开发多线程串口通信.开发的过程中,出现两个问题:   问题1:我用信号槽跨线程调用串口类MyCom 发送和接收数据,中间运行的时候,会内存错误,Q ...

  9. Qt串口通信接收数据不完整的解决方法

    在使用串口接收数据时,当数据量大的时候会出现数据接收不完整的情况.因为串口数据获取函数readAll()由readyRead()信号触发,但readyRead()信号在串口读到起始标志时立即发送,并不 ...

随机推荐

  1. MyBatis之五:动态sql语句

    在mybatis 3 或以上的版本提供了4类标签,分别是:if,choose(when,otherwise),rim(where,set),foreach.接下来将分别介绍这几种标签的具体用法,映射x ...

  2. ClassLoader使用记录《安卓高手之路》

    我不喜欢那些泛泛而谈的去讲那些形而上学的道理,更不喜欢记那些既定的东西.靠记忆去弥补思考的人,容易陷入人云亦云的境地,最后必定被记忆所围困,而最终消亡的是创造力.希望这个高手之路系列能够记录我学习安卓 ...

  3. [Angular 2] More on *ngFor, @ContentChildren & QueryList<>

    In previous artical, we introduce the how to use *ngFor. The limitation for previous solution to dis ...

  4. Tomcat安装、配置、优化及负载均衡详解

    一.常见JavaWeb服务器      1.WebLogic:是BEA公司的产品.WebSphereAS:是IBM公司的产品.JBossAS:红帽公司的产品,可以自行了解      2.Tomcat服 ...

  5. PHP概率算法(适用于抽奖、随机广告)

    做网站类的有时会弄个活动什么的,来让用户参加,既吸引用户注册,又提高网站的用户活跃度.同时参加的用户会获得一定的奖品,有100%中奖的,也有按一定概率中奖的,大的比如中个ipad.iphone5,小的 ...

  6. 《C和指针》之ANSI C标准输入输出函数

    一.I/O流操作一般流程: (1)为每一个要打开的文件定义一个FILE *类型的指针变量,这个指针变量将指向I/O流使用的FILE结构体. (2)使用fopen函数打开I/O流.要打开一个I/O流,必 ...

  7. css笔记12:块元素和行内元素

    1.概念: 行内元素:又叫内联元素,内联元素只能容纳文本或者其他内联元素,常见的内联元素有<span><a> 块元素:块元素一般都是从新行开始,可容纳文本,其他内联元素和其他块 ...

  8. MYSQL基础笔记(六)- 数据类型一

    数据类型(列类型) 所谓数据烈性,就是对数据进行统一的分类.从系统角度出发时为了能够使用统一的方式进行管理,更好的利用有限的空间. SQL中讲数据类型分成三大类:1.数值类型,2.字符串类型和时间日期 ...

  9. 高德地图 JavaScript API 开发系列教程(一)

    高德地图 API 提供包括 Web API 即 JavaScript API,Android API,定位API,IOS API,WP API,Win8 API等,本系列教程主要针对高德 JavaSc ...

  10. myeclipse web 包名保留字与servlet冲突

    包名不能取modify ..........等保留字 不能有数字