Qt 串口通信

在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
  8 /**
  9  * @brief 串口参数
 10  */
 11 struct SerialConfig{
 12     int baudRate;        //波特率
 13     int characterSize;   //传输位
 14     int stopBits;        //停止位
 15     int parity;          //校验位 0无校验 1奇校验 2偶校验
 16     //char*serialPort[20];     //设备文件名
 17     int flowControl;     //流控
 18     long timeOut;        //超时时间
 19 };
 20
 21 class Win_QextSerialPort;
 22
 23 /**
 24  * @brief 串口通信类
 25  */
 26 class SerialPort : public QObject
 27 {
 28     Q_OBJECT
 29 public:
 30
 31     explicit SerialPort(QString portName, QObject *parent = 0);
 32     //~SerialPort();
 33
 34     /**
 35      * @brief 串口数据大发送格式
 36      */
 37     enum SerialDataType{
 38         ASCLL=0, //ascll方式
 39         HEX      //二进制方式
 40     };
 41     /**
 42      * @brief 配置串口参数
 43      * @param config
 44      */
 45     void setSerila(SerialConfig *config);
 46
 47     /**
 48      * @brief 获取串口开启状态
 49      * @return
 50      */
 51     bool isOpend();
 52
 53     /**
 54      * @brief 设置数据发送方式
 55      * @param type
 56      */
 57     void setSerialDataType(SerialDataType type);
 58 signals:
 59     /**
 60      * @brief 串口获取到数据
 61      */
 62     void strSerial(QString);
 63 public slots:
 64
 65
 66     /**
 67      * @brief  开启串口
 68      * @param  串口参数
 69      * @return 是否成功打开串口
 70      */
 71     bool openSerial(SerialConfig *config);
 72
 73     /**
 74      * @brief 关闭串口
 75      */
 76     void closeSerial();
 77
 78     /**
 79      * @brief 写入数据到串口,系统默认是ascll方式
 80      * @param str 待写入数据
 81      */
 82     void writeSerial(QString str);
 83 private slots:
 84     /**
 85      * @brief 读取数据
 86      */
 87     void readSerial();
 88 private:
 89     /**
 90      * @brief 基本串口通信类
 91      */
 92     Win_QextSerialPort*serial;
 93
 94     /**
 95      * @brief 数据发送形式
 96      */
 97     SerialDataType serialDataType;
 98
 99
100 };
101
102 #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 9600:
 22         baudRate=BAUD9600;
 23         break;
 24     case 115200:
 25         baudRate=BAUD115200;
 26         break;
 27     default:
 28         baudRate=BAUD4800;
 29         break;
 30     }
 31
 32     //数据位
 33     DataBitsType dataBits;
 34     switch (config->characterSize) {
 35     case 7:
 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 1:
 47         stopBits=STOP_1;
 48         break;
 49     case 2:
 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 0:
 61         parity=PAR_NONE;
 62         break;
 63     case 1:
 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
 86 bool SerialPort::isOpend()
 87 {
 88     return this->serial!=NULL?serial->isOpen():false;
 89 }
 90
 91 void SerialPort::setSerialDataType(SerialPort::SerialDataType type)
 92 {
 93     this->serialDataType=type;
 94 }
 95
 96
 97 void SerialPort::writeSerial(QString str)
 98 {
 99
100     if(this->serialDataType==this->ASCLL){
101         serial->write(str.toLocal8Bit());
102     }else{
103
104         QByteArray b;
105         b=QByteArray::fromHex(str.toUtf8());
106         serial->write(b);
107     }
108
109 }
110
111 void SerialPort::readSerial()
112 {
113
114     qDebug()<<serial->bytesAvailable();
115
116     QString str="";
117
118     QByteArray array=serial->readAll();
119
120     if(this->serialDataType==SerialPort::ASCLL){
121         str=QString::fromLocal8Bit(array.data());
122     }else{
123         array=array.toHex();
124         str=QString::fromUtf8(array.data());
125     }
126
127     str=str.trimmed();
128
129     qDebug()<<"serial get:"<<str;
130
131     emit this->strSerial(str);
132
133
134 }
135
136
137 /**打开
138  * @brief SerialPort::openSerial
139  * @return
140  */
141 bool SerialPort::openSerial(SerialConfig*config)
142 {
143
144     bool isOpen=serial->open(QIODevice::ReadWrite);
145
146     qDebug()<<"isOpen:"<<isOpen;
147     //如果已经成功打开串口,则经行串口参数配置
148     //这里有一个概念:串口配置必须在串口设备成功打开后才有效!
149     if(isOpen){
150         this->setSerila(config);
151     }
152
153     return isOpen;
154 }
155
156 void SerialPort::closeSerial()
157 {
158     serial->close();
159
160 }

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(9600);
 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
13 typedef struct
14 {
15     int baudRate;        //!<波特率
16     int characterSize;   //!<传输位
17     int stopBits;        //!<停止位
18     int parity;          //!校验位 0无校验 1奇校验 2偶校验
19     char*serialPort; //!设备文件名
20
21 }SerialConfig;
22
23
24 class Serial : public QObject
25 {
26     Q_OBJECT
27 public:
28     explicit Serial(QObject *parent = 0);
29
30 signals:
31
32     void message(QString msg);
33 public slots:
34     //打开串口
35     bool open(SerialConfig*config);
36     void work();
37     void close();
38     void sendMesg(QString msg);
39 private slots:
40
41 private:
42     /**
43      * @brief 初始化串口数据
44      * @param config
45      */
46     void initSerialStream(SerialConfig*config);
47
48     /**
49      * @brief 串口字节流
50      */
51     SerialStream serialStream;
52
53     bool isRuning;
54 };
55
56 #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
 17     serialStream.Open(config->serialPort);
 18
 19     if(!serialStream.IsOpen())
 20     {
 21         qDebug()<<"cannot open serial "<<config->serialPort;
 22         return false;
 23     }else{
 24
 25         qDebug()<<"success open serial "<<config->serialPort;
 26     }
 27
 28     initSerialStream(config);
 29
 30     return true;
 31
 32 }
 33
 34
 35 void Serial::work(){
 36
 37     //缓存数据
 38     char *msg = new char[255];
 39     int index = 0;
 40     char next_byte ;    //串口接收到的下一个字节
 41     this->isRuning=true;
 42     forever{
 43         //
 44         if(this->isRuning==false){
 45             break;
 46         }
 47
 48         serialStream.get( next_byte );
 49
 50         int char_num=next_byte+0;
 51
 52         if(char_num<30){
 53             qDebug()<<":"<<next_byte+0;
 54         }else{
 55             qDebug()<<next_byte;
 56         }
 57
 58         if(char_num!=SERIAL_DATA_END)
 59         {
 60             if(char_num==SERIAL_DATA_START){
 61                 index=0;
 62                 continue;
 63             }
 64
 65             msg[index] = next_byte;
 66             index++;
 67         }
 68         else
 69         {
 70             msg[index] = ‘\0‘;
 71             index = 0;
 72             qDebug("%s",msg);
 73             emit message(QString(msg).trimmed());
 74         }
 75     }
 76 }
 77
 78 void Serial::close(){
 79
 80     this->isRuning=false;
 81 }
 82
 83 void Serial::sendMesg(QString msg)
 84 {
 85     msg.insert(0,2);
 86     msg.append(3);
 87
 88     char*cmsg =msg.toUtf8().data();
 89     serialStream.write(cmsg,strlen(cmsg));
 90
 91 }
 92
 93 void Serial::initSerialStream(SerialConfig *config)
 94 {
 95
 96     SerialStreamBuf::BaudRateEnum baudRate;
 97
 98     switch (config->baudRate) {
 99     case 9600:
100         baudRate=SerialStreamBuf::BAUD_9600;
101         break;
102     case 115200:
103         baudRate=SerialStreamBuf::BAUD_115200;
104         break;
105     default:
106         baudRate=SerialStreamBuf::BAUD_4800;
107         break;
108     }
109
110     SerialStreamBuf::CharSizeEnum characterSize;
111     switch (config->characterSize) {
112     case 7:
113         characterSize=SerialStreamBuf::CHAR_SIZE_7;
114         break;
115     default:
116         characterSize=SerialStreamBuf::CHAR_SIZE_8;
117         break;
118     }
119
120
121     SerialStreamBuf::ParityEnum parity;
122     switch (config->characterSize) {
123     case 0:
124         parity=SerialStreamBuf::PARITY_NONE;
125         break;
126     case 1:
127         parity=SerialStreamBuf::PARITY_ODD;
128         break;
129     default:
130         parity=SerialStreamBuf::PARITY_EVEN;
131         break;
132     }
133
134
135     serialStream.SetBaudRate(baudRate);
136     serialStream.SetCharSize(characterSize);
137     serialStream.SetNumOfStopBits(config->stopBits);
138     serialStream.SetParity(parity);
139 }

Qt 串口通信,布布扣,bubuko.com

时间: 2024-10-23 00:28:43

Qt 串口通信的相关文章

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

在QT中进行串口通信时,很多情况要用到发送16进制的数据.从网上找来了一段代码测试能用: static QByteArray QString2Hex(QString str) { QByteArray senddata; int hexdata,lowhexdata; int hexdatalen = 0; int len = str.length(); senddata.resize(len/2); char lstr,hstr; for(int i=0; i<len; ) { hstr=st

Qt串口通信专题教程

查看以前的教程:Qt编写串口通信程序全程图文讲解 查看Wincom和Lincom介绍:Qt跨平台串口通信软件Wincom与Lincom 下载软件,文档和源码:资源下载 --------------2010年7月8日更新--------------– 网友 赵文杰 使用多线程完成的linux下的串口通信. 下载源码:下载 ------------------------------------- 以下是正文: 前言 去年我使用Qt编写串口通信程序时,将自己的学习过程写成了教程(Qt编写串口通信程序

Qt串口通信接收数据不完整的解决方法(传输图片)

在使用串口接收数据时,当数据量大的时候会出现数据接收不完整的情况.因为串口数据获取函数readAll()由readyRead()信号触发,但readyRead()信号在串口读到起始标志时立即发送,并不保证一定是当前所发数据的起始部分.因此串口通信双方在通信前应制定好通信协议,规定好数据的起始和结束标志,串口当读到完整的起始和结束标志之后,才认定读完一条完整的数据. 本例中用串口定时发送当前时间,用"#"表示数据的结尾,定时时间为0毫秒,即能发多快就发多快. //发送 [cpp] vie

qt串口

qt串口通信:#ifdef _TTY_POSIX#include "posix_qextserialport.h"#define QextBaseType Posix_QextSerialPort #else#include "win_qextserialport.h"#define "QextBaseTypeport.h"#define QextBaseType Win_QexSerialPort#endif QextSerialBase类中

转:Qt编写串口通信程序全程图文讲解

转载:http://blog.csdn.net/yafeilinux/article/details/4717706  作者:yafeilinux (说明:我们的编程环境是windows xp下,在Qt Creator中进行,如果在Linux下或直接用源码编写,程序稍有不同,请自己改动.) 在Qt中并没有特定的串口控制类,现在大部分人使用的是第三方写的qextserialport类,我们这里也是使用的该类.我们可以去 http://sourceforge.net/projects/qextser

Qt实现串口通信总结

注意: Qt5发布之前,Qt实现串口通信一般是采用第三方类库qextserialport.Qt5发布后自带了QtSerialPort 能够支持串口通信. 1.Qextserialport类介绍 在Qt5之前的版本中并没有特定的串口控制类,现在大部分人使用的是第三方写的qextserialport类,本文章主要是讲解怎样利用此类实现串口通信. 2.文件下载地址: http://sourceforge.net/projects/qextserialport/files/ 3.文件内容:     3.

Qt编写串口通信程序

首先说明我们的编程环境是windows xp下,在Qt Creator中进行,如果在Linux下或直接用源码编写,程序稍有不同,请自己改动. 在Qt中并没有特定的串口控制类,现在大部分人使用的是第三方写的qextserialport类,我们这里也是使用的该类.我们可以去 http://sourceforge.net/projects/qextserialport/files/ 进行下载,也可以去下载论坛上的 http://www.qtcn.org/bbs/read.php?tid=22847 下

Qt编写串口通信程序全程图文解说

(说明:我们的编程环境是windows xp下,在Qt Creator中进行,假设在Linux下或直接用源代码编写,程序稍有不同,请自己修改.) 在Qt中并没有特定的串口控制类,如今大部分人使用的是第三方写的qextserialport类,我们这里也是使用的该类.我们能够去 http://sourceforge.net/projects/qextserialport/files/ 进行下载,也能够去下载我上传到网上的: http://download.csdn.net/source/176278

QT开发(五十)——QT串口编程基础

QT开发(五十)--QT串口编程基础 一.QtSerialPort简介 1.串口通信基础 目前使用最广泛的串口为DB9接口,适用于较近距离的通信.一般小于10米.DB9接口有9个针脚. 串口通信的主要参数如下: A.波特率:衡量通信速度的参数,表示每秒钟传送的bit的个数.例如9600波特表示每秒钟发送9600个bit. B.数据位:衡量通信中实际数据位的参数,当计算机发送一个信息包,实际包含的有效数据位个数. C.停止位:用于表示单个包的最后一位.典型的值为1和2位. D.奇偶校验位:串口通信