在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

 #ifndef SERIALPORT_H
#define SERIALPORT_H #include <QObject> /**
* @brief 串口参数
*/
struct SerialConfig{
int baudRate; //波特率
int characterSize; //传输位
int stopBits; //停止位
int parity; //校验位 0无校验 1奇校验 2偶校验
//char*serialPort[20]; //设备文件名
int flowControl; //流控
long timeOut; //超时时间
}; class Win_QextSerialPort; /**
* @brief 串口通信类
*/
class SerialPort : public QObject
{
Q_OBJECT
public: explicit SerialPort(QString portName, QObject *parent = );
//~SerialPort(); /**
* @brief 串口数据大发送格式
*/
enum SerialDataType{
ASCLL=, //ascll方式
HEX //二进制方式
};
/**
* @brief 配置串口参数
* @param config
*/
void setSerila(SerialConfig *config); /**
* @brief 获取串口开启状态
* @return
*/
bool isOpend(); /**
* @brief 设置数据发送方式
* @param type
*/
void setSerialDataType(SerialDataType type);
signals:
/**
* @brief 串口获取到数据
*/
void strSerial(QString);
public slots: /**
* @brief 开启串口
* @param 串口参数
* @return 是否成功打开串口
*/
bool openSerial(SerialConfig *config); /**
* @brief 关闭串口
*/
void closeSerial(); /**
* @brief 写入数据到串口,系统默认是ascll方式
* @param str 待写入数据
*/
void writeSerial(QString str);
private slots:
/**
* @brief 读取数据
*/
void readSerial();
private:
/**
* @brief 基本串口通信类
*/
Win_QextSerialPort*serial; /**
* @brief 数据发送形式
*/
SerialDataType serialDataType; }; #endif // SERIALPORT_H

  源文件:serialport.cpp

 #include "serialport.h"
#include "serial_inc/win_qextserialport.h" #include <QDebug> SerialPort::SerialPort(QString portName,QObject *parent):QObject(parent),serialDataType(HEX)
{ this->serial=new Win_QextSerialPort(portName, QextSerialBase::EventDriven);
connect(serial,SIGNAL(readyRead()),this,SLOT(readSerial())); } void SerialPort::setSerila(SerialConfig *config)
{ //波特率
BaudRateType baudRate; switch (config->baudRate) {
case :
baudRate=BAUD9600;
break;
case :
baudRate=BAUD115200;
break;
default:
baudRate=BAUD4800;
break;
} //数据位
DataBitsType dataBits;
switch (config->characterSize) {
case :
dataBits=DATA_7;
break;
default:
dataBits=DATA_8;
break;
} //停止位
StopBitsType stopBits;
switch (config->stopBits) {
case :
stopBits=STOP_1;
break;
case :
stopBits=STOP_2;
break;
default:
stopBits=STOP_1_5;
break;
} //奇偶校验
ParityType parity;
switch (config->parity) {
case :
parity=PAR_NONE;
break;
case :
parity=PAR_ODD;
break;
default:
parity=PAR_EVEN;
break;
} //数据流控
FlowType flow=FLOW_OFF; serial->setBaudRate(baudRate);
serial->setDataBits(dataBits);
serial->setStopBits(stopBits);
serial->setParity(parity);
serial->setFlowControl(flow); serial->setDtr(false);
serial->setRts(false); } bool SerialPort::isOpend()
{
return this->serial!=NULL?serial->isOpen():false;
} void SerialPort::setSerialDataType(SerialPort::SerialDataType type)
{
this->serialDataType=type;
} void SerialPort::writeSerial(QString str)
{ if(this->serialDataType==this->ASCLL){
serial->write(str.toLocal8Bit());
}else{ QByteArray b;
b=QByteArray::fromHex(str.toUtf8());
serial->write(b);
} } void SerialPort::readSerial()
{ qDebug()<<serial->bytesAvailable(); QString str=""; QByteArray array=serial->readAll(); if(this->serialDataType==SerialPort::ASCLL){
str=QString::fromLocal8Bit(array.data());
}else{
array=array.toHex();
str=QString::fromUtf8(array.data());
} str=str.trimmed(); qDebug()<<"serial get:"<<str; emit this->strSerial(str); } /**打开
* @brief SerialPort::openSerial
* @return
*/
bool SerialPort::openSerial(SerialConfig*config)
{ bool isOpen=serial->open(QIODevice::ReadWrite); qDebug()<<"isOpen:"<<isOpen;
//如果已经成功打开串口,则经行串口参数配置
//这里有一个概念:串口配置必须在串口设备成功打开后才有效!
if(isOpen){
this->setSerila(config);
} return isOpen;
} void SerialPort::closeSerial()
{
serial->close(); }

QSerialPort 使用小例

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

  串口初始化代码片段:

   QSerialPort serial=new QSerialPort(this);

     connect(serial, SIGNAL(readyRead()), this, SLOT(readData()));

     serial->setPortName("COM4");
serial->setBaudRate();
serial->setDataBits(QSerialPort::Data8);
serial->setParity(QSerialPort::NoParity);
serial->setStopBits(QSerialPort::OneStop);
serial->setFlowControl(QSerialPort::NoFlowControl);
if (serial->open(QIODevice::ReadWrite)) { qDebug()<<"yes"; } else { qDebug()<<"no";
}

  数据接收函数:

 void QPort::readData()
{
QByteArray data = serial->readAll();
qDebug()<<data; }

libserial使用小例

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

  头文件:serial.h

 #ifndef SERIAL_H
#define SERIAL_H #include "common.h"
#include "SerialStream.h"
#include "SerialStreamBuf.h"
#include <QObject> using namespace std;
using namespace LibSerial; typedef struct
{
int baudRate; //!<波特率
int characterSize; //!<传输位
int stopBits; //!<停止位
int parity; //!校验位 0无校验 1奇校验 2偶校验
char*serialPort; //!设备文件名 }SerialConfig; class Serial : public QObject
{
Q_OBJECT
public:
explicit Serial(QObject *parent = ); signals: void message(QString msg);
public slots:
//打开串口
bool open(SerialConfig*config);
void work();
void close();
void sendMesg(QString msg);
private slots: private:
/**
* @brief 初始化串口数据
* @param config
*/
void initSerialStream(SerialConfig*config); /**
* @brief 串口字节流
*/
SerialStream serialStream; bool isRuning;
}; #endif // SERIAL_H

  源文件:serial.cpp

 #include "serial.h"

 //数据开始标示
#define SERIAL_DATA_START 2 //数据结束标示
#define SERIAL_DATA_END 3 Serial::Serial(QObject *parent) :
QObject(parent)
{
} bool Serial::open(SerialConfig *config){ serialStream.Open(config->serialPort); if(!serialStream.IsOpen())
{
qDebug()<<"cannot open serial "<<config->serialPort;
return false;
}else{ qDebug()<<"success open serial "<<config->serialPort;
} initSerialStream(config); return true; } void Serial::work(){ //缓存数据
char *msg = new char[];
int index = ;
char next_byte ; //串口接收到的下一个字节
this->isRuning=true;
forever{
//
if(this->isRuning==false){
break;
} serialStream.get( next_byte ); int char_num=next_byte+; if(char_num<){
qDebug()<<":"<<next_byte+;
}else{
qDebug()<<next_byte;
} if(char_num!=SERIAL_DATA_END)
{
if(char_num==SERIAL_DATA_START){
index=;
continue;
} msg[index] = next_byte;
index++;
}
else
{
msg[index] = '\0';
index = ;
qDebug("%s",msg);
emit message(QString(msg).trimmed());
}
}
} void Serial::close(){ this->isRuning=false;
} void Serial::sendMesg(QString msg)
{
msg.insert(,);
msg.append(); char*cmsg =msg.toUtf8().data();
serialStream.write(cmsg,strlen(cmsg)); } void Serial::initSerialStream(SerialConfig *config)
{ SerialStreamBuf::BaudRateEnum baudRate; switch (config->baudRate) {
case :
baudRate=SerialStreamBuf::BAUD_9600;
break;
case :
baudRate=SerialStreamBuf::BAUD_115200;
break;
default:
baudRate=SerialStreamBuf::BAUD_4800;
break;
} SerialStreamBuf::CharSizeEnum characterSize;
switch (config->characterSize) {
case :
characterSize=SerialStreamBuf::CHAR_SIZE_7;
break;
default:
characterSize=SerialStreamBuf::CHAR_SIZE_8;
break;
} SerialStreamBuf::ParityEnum parity;
switch (config->characterSize) {
case :
parity=SerialStreamBuf::PARITY_NONE;
break;
case :
parity=SerialStreamBuf::PARITY_ODD;
break;
default:
parity=SerialStreamBuf::PARITY_EVEN;
break;
} serialStream.SetBaudRate(baudRate);
serialStream.SetCharSize(characterSize);
serialStream.SetNumOfStopBits(config->stopBits);
serialStream.SetParity(parity);
}

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. [原创]如何写好SqlHelper 之终章

    精简的美丽...... 标题有点大.但是,我觉得99%的接近了. 好了,下面我们来说说一个SqlHelper为了适应各种不同的业务需要,它应该具备哪些基本要素. 第一点.可控的事务. 事务是数据库操作 ...

  2. JS加解密URL参数encodeURIComponent() decodeURIComponent()

    参考1:http://www.w3school.com.cn/js/jsref_encodeURIComponent.asp 参考2:http://www.w3school.com.cn/js/jsr ...

  3. 项目源码--Android本地音乐播放器

    下载源码 技术要点: 1.本地音乐播放与管理 2.支持在线下载 3.非库音频流的解码 4. UI控件的综合使用 5. HTTP通信模块 6. Mysql数据库的综合使用 7. 后台服务技术 8. 源码 ...

  4. php的引用&(就是在变量或者函数、对象等前面加上&符号)

    官方文档: 1.引用是什么:http://www.php.net/manual/zh/language.references.whatare.php 2.引用做什么:http://www.php.ne ...

  5. tar --help

    pengdl@debian:~/test$ mkdir test1 pengdl@debian:~/test$ mkdir test2 pengdl@debian:~/test$ tar -xzf p ...

  6. iOS,面试必看,最全梳理

    序言 目前形势,参加到iOS队伍的人是越来越多,甚至已经到供过于求了.今年,找过工作人可能会更深刻地体会到今年的就业形势不容乐观,加之,培训机构一火车地向用人单位输送iOS开发人员,打破了生态圈的动态 ...

  7. Turn the pokers

    Problem Description During summer vacation,Alice stay at home for a long time, with nothing to do. S ...

  8. 实现JavaScript的组成----BOM和DOM

    我们知道,一个完整的JavaScript的实现,需要由三部分组成:ECMAScript(核心),BOM(浏览器对象模型),DOM(文档对象模型). 今天主要学习BOM和DOM. BOM: BOM提供了 ...

  9. App Thinning

    App Thinning 由于项目中需要开启Bitcode编译,之前对Bitcode也有些误区,故整理了下相关知识,仅供参考,如有不对,还请指出. 当前 iOS App 的编译打包方式是把适配兼容多个 ...

  10. [转]DataTable用中使用Compute 实现简单的DataTable数据的统计

    本文转自:http://blog.csdn.net/zwxrain/article/details/252285 調用格式: object DataTable.Compute(string expre ...