By Toradex秦海
1). 简介
基于Embedded Linux系统的嵌入式设备使用跨平台GUI开发工具Qt来开发嵌入式应用已经非常普遍,本文就以分别通过原生C语言方式和使用Qt QSerialPort控件方式来进行RS232/RS485串口应用的开发示例。
本文所演示的平台来自于Toradex Colibri iMX6DL ARM嵌入式平台,这是一个基于NXP iMX6DL ARM处理器,支持双核Cortex-A9。
2. 准备
a). Colibri iMX6DL ARM核心版配合Colibri Eva Board载板,连接调试串口UART1到开发主机方便调试。
b). Colibri iMX6DL系统使用基于OpenEmbedded框架重新编译的集成Qt5.5 的Toradex Linux image releaseV2.6.1版本以及对应的SDK.这个可以结合这里的说明自己进行编译, 也可以通过这里直接下载编译好的image和SDK文件,image更新方法请参考这里。
c). 关于开发主机SDK安装和qtcreator开发环境的配置请参考之前发布的《嵌入式Linux基于Qt开发GPIO应用一文》。
3). 串口硬件连接
a). Colibri iMX6S核心版默认定义提供了三个串口,如下所示,其中UART1为默认的调试串口,当然可以通过uboot设置关闭调试串口或者指定另外一个串口作为调试串口。
b). Colibri Eva Board X25 Top DB9连接器默认为UART2接口RS232电平输出,可以连接到Ubuntu开发主机进行UART2串口测试。另外,通过载板跳线测试也可以将UART3串口路由到X25 bottom DB9连接器上面,具体说明可以参考这里。
c). Colibri iMX6 UART除了RS232模式,也支持RS422/485模式,这里还是利用UART2来测试RS485半双工模式通讯,基于Colibri Eva Board的硬件连接如下:
./ 将Colibri Eva Board连接器X2 bottom DB9 管脚4(RXD+),管脚5(RXD-)以及管脚1(GND)和PC主机485接口设备对接
./ 将Colibri Eva Board下面几个跳线做如下设置:
JP11 短接 – 让485接口可以发送以及接收收据,如果断开,则只能发送数据
JP12,JP14断开 – 用于插入120ohm终端电阻,针对RS-422模式
JP13,JP15短接 – 设置为半双工模式,如果断开,则为全双工模式
JP16短接 – UART2到RS232的功能关闭,切换到RS485功能;断开则反之。
4). RS485功能使能方法
a).在device tree中使能,。
//参考这里下载Toradex Linux kernel V2.6版本源代码,根据如下patch文件修改arch/arm/boot/dts/imx6dl-colibri-eval-v3.dts文件,并参考这里编译新的dtb文件后部署到Colibri iMX6模块上。
https://github.com/simonqin09/uarttest/blob/master/485.patch
这种使能后在应用程序就不需要针对485做使能处理了。
b). 利用ioctrl TIOCSRS485在应用程序中使能,具体代码可以参考下面实例。
5). 基于原生C语言操作串口Qt widget应用示例
a). Qtcreator 创建一个新项目”uarttest”, New Project-> Applications -> Qt Widgets Application -> Location (任意) -> Kit (针对Colibri imx6的kit) -> Class Information (默认)
b). 在项目中首先添加串口基本操作的header和source文件
./ Header 文件代码如下,主要定义一些全局环境变量和声明UART基本的操作函数
https://github.com/simonqin09/Qtuarttest/blob/master/uartconfig.h
./ source文件代码如下,主要是UART基本操作函数,包含open/close, config, 485 enable,read, write等。
https://github.com/simonqin09/Qtuarttest/blob/master/uartconfig.cpp
c). 进入Forms -> mainwindow.ui, 如下编辑界面, 同时通过”go to slot”添加”SendButton”, ”ReceiveButton”和”SubmitButton”的”clicked”动作函数。
d). 修改mainwindow header和source文件, 实现UART串口的打开,配置以及读取控制
./ Hearder文件代码如下,声明界面buttons,lineedits,lable变量以及串口控制所需的全局变量
https://github.com/simonqin09/Qtuarttest/blob/master/mainwindow.h
./ source文件代码如下, 在窗口初始化的时候先隐藏”Send”和”Receive” button以及对应的输入输出框,先根据Lable输出提示输入需要调试的UART设备名,点击”Submit”按键会完成打开并配置串口的操作,这里串口配置参数为”1152008N1”,同时显示发送接收按钮,可以分别点击实现发送和接收功能测试。
https://github.com/simonqin09/Qtuarttest/blob/master/mainwindow.cpp
./ 注意,默认是通过” uart_485()” 在 ” void MainWindow::on_SubmitButton_clicked()” 中使能了485模式,如果测试RS232或者通过device tree方式使能了485,则可以将这部分注释掉
e). 编译应用程序, 将编译好的可执行文件scp复制到Colibri iMX6模块系统上面执行,效果如下:
6). 基于QSerialPort控件操作串口Qt widget应用示例
a). Qtcreator 创建一个新项目”qtserialtest”, New Project-> Applications -> Qt Widgets Application -> Location (任意) -> Kit (针对Colibri imx6的kit) -> Class Information (默认)
b). 编辑界面保持和上面5章节应用界面完全一致。
c). 修改mainwindow header和source文件, 实现UART串口的打开,配置以及读取控制
./ Hearder文件代码如下,区别主要是添加了”QSerialPort”和”QTimer”头文件和相关变量,以及两个槽函数”void uartread()”和”void readtimeout()”
https://github.com/simonqin09/qtserialtest/blob/master/mainwindow.h
./ source文件代码如下, 同样在窗口初始化的时候先隐藏”Send”和”Receive” button以及对应的输入输出框,先根据Lable输出提示输入需要调试的UART设备名,点击”Submit”按键会通过QSerialPort控件相关操作函数打开并配置串口,这里串口配置参数为”1152008N1”,同时显示发送接收按钮,然后可以分别点击实现发送和接收功能测试。
https://github.com/simonqin09/qtserialtest/blob/master/mainwindow.cpp
./ 注意,如果测试RS485,需要通过上面章节4第一种方法通过device tree使能485
./ 通过对比可以发现,通过QSerialPort控件操作更简单,其定义了很多现成的操作可以实现非常方便的串口操作,尤其在Receive方面,通过”SIGNAL(readyRead())和”Slot(uartread())”函数的connect以及”SIGNAL(timeout())和”Slot(readtimeout())”函数的connect,非常方便的实现了数据接收和Timeout延时的处理。
d). 编译部署执行结果和上面章节5类似。
7). 总结
本文基于NXP iMX6嵌入式平台在嵌入式linux系统下测试基于Qt开发UART通信应用,对比了使用原生C代码从底层操作UART设备和使用QSerialPort控件操作UART。