找回密码
 立即注册
收起左侧

Qt串口通信全新专题

125
回复
97639
查看
  [复制链接]
累计签到:1564 天
连续签到:1 天
来源: Qt文章 2013-4-4 01:29:27 显示全部楼层 |阅读模式
Qt串口通信全新专题


版权声明

该文章原创于Qter开源社区(www.qter.org),转载请注明出处!


软件:QCom跨平台串口调试助手


更新提示

这次源码更新,与前面“串口通信专题”主要有下面两点不同:

1.以前必须先使用open()函数打开串口,再进行配置;而现在打开串口和配置串口没有顺序要求;

2.以前在Linux下面必须使用查询polling(或者叫轮询)的方式读取串口,现在在Linux下面也可以使用事件驱动的方式。




概述


yafeilinux.com以前推出了“Qt串口通信专题教程”,得到很多网友的关注和支持。对此我们表示感谢!由于最近对Wincom和Lincom进行了更新整合,推出了可以跨平台编译的QCom,所以有必要推出本文档。本文档是“Qt串口通信专题教程”的升级和改进。希望通过本文档,可以帮助大家理解和掌握基于QT的串口通信程序的编写。以下是跨平台串口调试助手QCom在Ubuntu下的界面截图。

    本教程分为三部分进行讲述。第一部分讲解关于串口通信的基础知识;第二部分讲解qextserialport类的结构和使用方法;第三部分结合QCom实例具体的讲解qextserialport类的应用。在本教程中我们更注重串口通信相关知识的讲解,而不是界面的设计。关于界面的设计和关于QT更多的知道请关注qter.org精品文章专区。

第一部分 关于串口通信的基础知识
   
一、连接方式

    目前使用最广泛的串口为DB9接口,它适用于较近距离的通信。一般小于10米。DB9接口有9个针脚。它们的编号名称和作用如下表所示:

    虽然DB9接口有9个针脚,但在做普通的通信用时候,只会用到2、3、5这三个针脚。这也就是我们通常所说的“三线制”连接方法。在连接的时候需要把一方的2针脚接别一方的3针脚,也就是一方的接收针脚连接另一方的发送针脚。5针脚和另一方的5针脚相连。也就是两方的信号地连接在一起。如下图所示:



二、参数简介

  • 波特率:这是一个衡量通信速度的参数。它表示每秒钟传送的bit的个数。例如9600波特表示每秒钟发送9600个bit。
  • 数据位:这是衡量通信中实际数据位的参数,当计算机发送一个信息包,实际包含的有效数据位个数。
  • 停止位:用于表示单个包的最后一位。典型的值为1和2位。由于数据是在传输线上定时的,并且每一个设备有其自己的时钟,很可能在通信中两台设备间出现了小小的不同步。因此停止位不仅仅是表示传输的结束,并且提供计算机校正时钟同步的机会。适用于停止位的位数越多,不同时钟同步的容忍程度越大,但是数据传输率同时也越慢。
  • 奇偶校验位:它是串口通信中一种检错方式。常用的检错方式有:偶、奇校验。当然没有校验位也是可以的。软件只以设置好校验方式就可以了,真正的校验过程是由硬件自动完成的。编程是不需要考虑。


三、数据传输方式
    关于这一部分的详细介绍,可以参考“串口通讯—异步通信方式”一文。


第二部分 qextserialport类的结构和使用方法

    在Qt中并没有特定的串口控制类,现在大部分人使用的是第三方写的qextserialport类,我们这里也使用了该类。

一、文件下载

官方下载地址:
在本文中所使用的qextserail的版本为1.2rc。

二、文件内容介绍

1.下载到的文件为qextserialport-1.2rc.zip ,解压并打开后其内容如下。

下面分别介绍:
(1)doc文件夹中的文件内容是QextSerialPort类和QextBaseType的简单的说明,我们可以使用记事本程序将它们打开。
(2)examples文件夹中是几个例子程序,可以看一下它的源码,不过想运行它们好像会出很多问题啊。
(3)src文件夹中是QextSerialPort类的代码,真正使用到的源文件都存这个文件夹中。现在来详细看一下src文件夹下有哪些文件,如下图:

这么多文件,哪真正对我们有用的又有哪些呢?

在windows下需要用到的文件有:
qextserialport.cpp
qextserialport_global.h
qextserialport.h
qextserialport_p.h
qextserialport_win.cpp

在linux下需要的文件有:
qextserialport.cpp
qextserialport_global.h
qextserialport.h
qextserialport_p.h
qextserialport_unix.cpp

仔细看一下,会发现,在两个不同的平台下需要的文件前几个是一样的,只有最后一个不同。这说明,不同平台实现的具体代码存在于这两个文件中。其它的一些文件用不到,可以不用管它。

2.qextserialport的简单介绍
    qextserialport类的声明在qextserialport.h中。我们可以调用的成员函数和一些类型定义都可以在这个文件中找到。下边我们来看一下qextserialport类的定义:

class QEXTSERIALPORT_EXPORT QextSerialPort: public QIODevice

可以看到继承自QIODevice类,所以该类的一些函数我们也可以直接来使用。这个类提供给我们四个构造函数,在实际编程中可以酌情使用。声明如下:

explicit QextSerialPort(QueryMode mode = EventDriven, QObject *parent = 0);
explicit QextSerialPort(const QString &name, QueryMode mode =EventDriven, QObject *parent = 0);
explicit QextSerialPort(const PortSettings &s, QueryMode mode =EventDriven, QObject *parent = 0);
QextSerialPort(const QString &name, const PortSettings &s,QueryMode mode = EventDriven, QObject *parent=0);

关于explicit这个关键字的作用,如果有兴趣可以问一问google,如果没兴趣可以直接忽略它。另外,这个类提供给我们可以调用的关键成员函数有:

void setBaudRate(BaudRateType);//设置波特率
void setDataBits(DataBitsType);//设置数据位
void setParity(ParityType);//设置校验类型
void setStopBits(StopBitsType);//设置停止位

当然还有其它的一些成员函数,详细内容可以打开qextserialport.h这个文件来看一下,我们在这里就不一一列出了。
在QextSerialPort类中还涉及到了一个枚举变量QueryMode。它有两个值Polling和EventDriven 。QueryMode指的是读取串口的方式,下面我们称为查询模式,我们将Polling称为查询方式Polling,将EventDriven称为事件驱动方式。
    事件驱动方式EventDriven就是使用事件处理串口的读取,一旦有数据到来,就会发出readyRead()信号,我们可以关联该信号来读取串口的数据。在事件驱动的方式下,串口的读写是异步的,调用读写函数会立即返回,它们不会冻结调用线程。
而查询方式Polling则不同,读写函数是同步执行的,信号不能工作在这种模式下,而且有些功能也无法实现。我们需要自己建立定时器来读取串口的数据。

需要注意的是:以前版本的QextSerialPort类,在linux下面只能使用Polling查询的方式读取串口,而该类的最新版本已经支持在linux下使用事件驱动的方式读取串口。


第三部分 qextserialport类在QCom跨平台串口调试助手中的应用
   
QCom跨平台调试助手是qter.org推出的串口通信调试软件,源代码完全公开。大家可以完全免费的使用这个软件,并可以通过这个软件学习QT环境下的串口通信编程。(项目主页

一、在qcom.pro文件中如何实现不同平台下使用不同的源文件

    以下是qcom.pro的部分代码:
SOURCES += main.cpp\
        mainwindow.cpp \
            aboutdialog.cpp\
        qextserial/qextserialport.cpp
HEADERS  += mainwindow.h \
            aboutdialog.h\
       qextserial/qextserialport_global.h \
        qextserial/qextserialport_p.h\
        qextserial/qextserialport.h
win32 {  
//如果是windows环境把qextserialport_win.cpp加入到源文件列表中
        SOURCES+= qextserial/qextserialport_win.cpp
}
unix {
//如果是linux环境把qextserialport_unix.cpp加入到源文件列表中
        SOURCES+= qextserial/qextserialport_unix.cpp
}

二、qextserialport的定义和设置

下面这段代码存在于QCom项目中的mainwindow.cpp文件中:

    #ifdef Q_OS_LINUX
        myCom= new QextSerialPort("/dev/" + portName);
#elif defined (Q_OS_WIN)
            myCom= new QextSerialPort(portName);
#endif
connect(myCom, SIGNAL(readyRead()), this, SLOT(readMyCom()));

可以看到,在不同的平台下,我们给QextSerialPort类的参数是不同的。参考上一部分中的QextSerialPort类的构造函数,可以看到,这里采用的是“事件驱动”方式。
    最后一行代码实现了信号的槽的连接。这样,当串口收到数据以后,就会调readMyCom()函数。


结语

    这篇教程只是帮助大家更容易看懂QCom跨平台串口调试助手的源码,并没有涉及编程的细节。大家也可以参考以前推出的Qt串口编程教程。




本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
回复

使用道具 举报

累计签到:1564 天
连续签到:1 天
2013-7-10 11:45:41 显示全部楼层
heyang 发表于 2013-7-9 17:09
希望可以尽快联系我,我期望加入你们的项目。
最近时间也比较多,5年Windows平台C/C++开发经验。
QQ2529092 ...

嗯。先加 190742443这个群吧聊聊吧!
回复 支持 1 反对 0

使用道具 举报

尚未签到

2013-4-18 15:53:53 显示全部楼层
啥时候更新啊。。。半个月过去了都

点评

教程已经更新,请提出宝贵意见!  发表于 2013-4-24 23:26
回复 支持 反对

使用道具 举报

累计签到:87 天
连续签到:1 天
2013-4-18 23:18:57 显示全部楼层
希望详细讲讲发布,照着做的发布用不了……
回复 支持 反对

使用道具 举报

累计签到:1564 天
连续签到:1 天
2013-4-19 09:01:04 显示全部楼层
20030969 发表于 2013-4-18 23:18
希望详细讲讲发布,照着做的发布用不了……

Qt 4程序发布可以看下这里;Qt 5程序发布可以看下这里
回复 支持 反对

使用道具 举报

累计签到:1564 天
连续签到:1 天
2013-4-19 09:01:44 显示全部楼层
曙光重现 发表于 2013-4-18 15:53
啥时候更新啊。。。半个月过去了都

嗯。这个周末更新。也可以先看看以前的:www.yafeilinux.com
回复 支持 反对

使用道具 举报

尚未签到

2013-4-22 11:38:33 显示全部楼层
没有教程,就一个已经发布的串口程序?

点评

嗯,其实教程跟以前没有什么变化的,最主要的就是使用了最新的第三方串口类。因为参与这次更新的成员一直有事情,所以教程还没有更新出来。  发表于 2013-4-22 18:01
回复 支持 反对

使用道具 举报

累计签到:1564 天
连续签到:1 天
2013-4-24 23:27:26 显示全部楼层
vads 发表于 2013-4-22 11:38
没有教程,就一个已经发布的串口程序?

教程已经更新了,下面抽时间把以前的教程也整理过来!
回复 支持 反对

使用道具 举报

尚未签到

2013-5-2 14:07:09 显示全部楼层
谢谢楼主了,这个很有用

教程在哪里下载?

点评

以前的教程,在yafeilinux.com下载  发表于 2013-5-2 15:03
回复 支持 反对

使用道具 举报

尚未签到

2013-5-2 16:59:46 显示全部楼层
旷性怡情 发表于 2013-5-2 14:07
谢谢楼主了,这个很有用

教程在哪里下载?

没有最新的教程吗?
   
回复 支持 反对

使用道具 举报

累计签到:1564 天
连续签到:1 天
2013-5-2 17:25:36 显示全部楼层
旷性怡情 发表于 2013-5-2 16:59
没有最新的教程吗?

这个就是最新的教程。其实主要内容没有什么改动,以前的也可以使用的。

点评

串口显示乱码问题怎么解决啊 读到的中文都是乱码,都说是编码问题 ,咋整??  详情 回复 发表于 2015-2-9 17:24
回复 支持 反对

使用道具 举报

尚未签到

2013-5-2 17:33:41 显示全部楼层
再问一句,qextserialport-1.2rc.zip是不是只支持4.8以上的版本?我编译你的那个程序,和我自己写的代码都出现以下错误,我的版本是4.7.4
D:\work\HaiZhuQuZhengFu\TestCom\qextserial\qextserialport_win.cpp:43: 错误:QtCore/private/qwineventnotifier_p.h: No such file or directory
D:\work\HaiZhuQuZhengFu\TestCom\qextserial\qextserialport_win.cpp:-1: In member function 'bool QextSerialPortPrivate::open_sys(QFlags<QIODevice::OpenModeFlag>)':
D:\work\HaiZhuQuZhengFu\TestCom\qextserial\qextserialport_win.cpp:112: 错误:invalid use of incomplete type 'struct QWinEventNotifier'
D:\work\HaiZhuQuZhengFu\TestCom\qextserial\qextserialport_p.h:173: 错误:forward declaration of 'struct QWinEventNotifier'
D:\work\HaiZhuQuZhengFu\TestCom\qextserial\qextserialport_win.cpp:114: 错误:no matching function for call to 'QextSerialPort::connect(QWinEventNotifier*&, const char*, QextSerialPort* const&, const char*, Qt::ConnectionType)'
c:\QtSDK\Desktop\Qt\4.7.4\mingw\include\QtCore\qobject.h:198: candidates are: static bool QObject::connect(const QObject*, const char*, const QObject*, const char*, Qt::ConnectionType)
c:\QtSDK\Desktop\Qt\4.7.4\mingw\include\QtCore\qobject.h:313: note:                 bool QObject::connect(const QObject*, const char*, const char*, Qt::ConnectionType) const
D:\work\HaiZhuQuZhengFu\TestCom\qextserial\qextserialport_win.cpp:-1: In member function 'bool QextSerialPortPrivate::close_sys()':
D:\work\HaiZhuQuZhengFu\TestCom\qextserial\qextserialport_win.cpp:129: 错误:invalid use of incomplete type 'struct QWinEventNotifier'
D:\work\HaiZhuQuZhengFu\TestCom\qextserial\qextserialport_p.h:173: 错误:forward declaration of 'struct QWinEventNotifier'
D:\work\HaiZhuQuZhengFu\TestCom\qextserial\qextserialport_win.cpp:130: 错误:invalid use of incomplete type 'struct QWinEventNotifier'
D:\work\HaiZhuQuZhengFu\TestCom\qextserial\qextserialport_p.h:173: 错误:forward declaration of 'struct QWinEventNotifier'
回复 支持 反对

使用道具 举报

累计签到:1564 天
连续签到:1 天
2013-5-2 19:32:06 显示全部楼层
旷性怡情 发表于 2013-5-2 17:33
再问一句,qextserialport-1.2rc.zip是不是只支持4.8以上的版本?我编译你的那个程序,和我自己写的代码都 ...

应该没有问题的,我这里使用Qt 4.7.2编译通过了,没有任何警告和错误。

你测试下编译其他程序是否有问题!
回复 支持 反对

使用道具 举报

尚未签到

2013-5-3 09:14:16 显示全部楼层
yafeilinux 发表于 2013-5-2 19:32
应该没有问题的,我这里使用Qt 4.7.2编译通过了,没有任何警告和错误。

你测试下编译其他程序是否有问题 ...

谢谢了
问题解决了,是缺少文件
从官网下载qt源文件然后拷贝src/corelib/kernel/qwineventnotifier_p.h至系统安装目录里include/QtCore/private/就可以了
回复 支持 反对

使用道具 举报

尚未签到

2013-5-16 20:33:47 显示全部楼层
教程很好~
回复 支持 反对

使用道具 举报

尚未签到

2013-5-18 11:15:58 显示全部楼层
真心觉得好啊,可以实现其他的基于串口的应用了。
回复 支持 反对

使用道具 举报

累计签到:1 天
连续签到:1 天
2013-7-3 16:39:59 显示全部楼层
旷性怡情 发表于 2013-5-3 09:14
谢谢了
问题解决了,是缺少文件
从官网下载qt源文件然后拷贝src/corelib/kernel/qwineventnotifier_p.h至 ...

我也遇到了,但是linux中 qt 的include/QtCore/private/下存在这个文件。win平台一切正常。
从官网下载qt哪个版本源文件?然后拷贝src/corelib/kernel/qwineventnotifier_p.h?
回复 支持 反对

使用道具 举报

累计签到:1 天
连续签到:1 天
2013-7-3 16:42:06 显示全部楼层
yuansh7 发表于 2013-7-3 16:39
我也遇到了,但是linux中 qt 的include/QtCore/private/下存在这个文件。win平台一切正常。
从官网下载qt ...

我的qt版本4.5.3(linux),4.7(win7)
回复 支持 反对

使用道具 举报

尚未签到

2013-7-9 17:09:27 显示全部楼层
希望可以尽快联系我,我期望加入你们的项目。
最近时间也比较多,5年Windows平台C/C++开发经验。
QQ252909254
h252909254@163.com
电话13558811813
网站我也可以帮着维护。
回复 支持 反对

使用道具 举报

尚未签到

2013-8-4 20:14:45 显示全部楼层
谢谢楼主,期待制作完整QT视频教程,目前中国还没有较好的QT教程
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

公告
可以关注我们的微信公众号yafeilinux_friends获取最新动态,或者加入QQ会员群进行交流:190741849、186601429(已满) 我知道了