3. 窗口代码化设计–串口通信¶
前面了解了使用Qt Designer进行可视化UI设计,接下来看下窗口代码化设计,用纯代码进行窗口的设计和布局。
我们将纯代码设计一个简单串口通信的窗口,显示串口的接收和发送。
提示
本章的串口例程只是了解下纯代码窗口设计,没有使用Qt的串口模块QtSerialPort,QtSerialPort模块的使用参考下后面章节。
3.1. 鲁班猫板卡串口资源介绍¶
鲁班猫板卡上,普通IO口可以复用为串口,以LubanCat2板卡为例( 其他鲁班猫系列板卡引脚参考 https://doc.embedfire.com/linux/rk356x/quick_start/zh/latest/quick_start/40pin/40pin.html
看到上面图片中红色框框的部分,引出的40 Pin中,最多可以复用出5个串口(UART3、UART4、UART7、UART8、UART9)。 开启串口的复用,需要修改下/boot/uEnv/uEnvLubanCat2.txt文件(这里是以LubanCat2为例,其他鲁班猫板卡的类似,比如LubanCat1,就是修改/boot/uEnv/uEnvLubanCat1.txt文件)。
我们测试下LubanCat2板卡的串口3,需要开启下串口,在板卡终端使用命令,然后修改:
cat@lubancat:~$ sudo vim /boot/uEnv/uEnvLubanCat2.txt
重启后就可以看到:
cat@lubancat:~$ ls /dev/ttyS*
/dev/ttyS3
# /dev/ttyS3就是uart3的设备文件
串口的开启也可以使用我们提供的fire-config工具, 更多串口的开启和测试看下 这里 。
3.2. 串口例程¶
3.2.1. 编程思路¶
我们要实现一个简单的串口通信例程,是板卡和PC上位机通过usb转串口线通信。板卡串口的使用通过基本的系统调用,使用open函数打开串口设备文件,tcsetattr函数设置基础的串口参数,还有ioctl等等。
在这个示例中,串口参数我们默认使用 115200-N-8-1
。
使用Qt Creator创建一个qt_serial工程(基于qwidget),不勾选使用form UI;
设计一个简单串口通信的窗口,创建一个1个显示框(QTextEdit),1个输入框(QLineEdit),1个按键等;
向工程中添加一个串口类(Uart),实现串口的打开,关闭,发送,接收等基础操作;
在Widget文件,初始化窗口,开启串口,关联信号与槽,在主函数显示窗口。
3.2.3. 界面设计和布局¶
在widget.h中,声明一些函数等:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | #ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QListWidget>
#include <QGridLayout>
#include <QTextEdit>
#include <QPushButton>
#include <QLineEdit>
#include <QTimer>
#include "uart.h"
class Widget : public QWidget
{
Q_OBJECT
public:
Uart uart3; //串口
void iniUI(); //初始化窗口
public:
Widget(QWidget *parent = nullptr);
~Widget();
private:
QTextEdit *textEdit; //用于显示信息
QLineEdit *lineEdit; //用于输入
QPushButton *BtnSend; //发送按钮
private slots:
void do_send(); //发送
void do_recvData(); //接收串口信息
};
#endif // WIDGET_H
|
在Widget构造函数中初始化串口,初始化窗口,设置信号与槽函数等,iniUI()中实现窗口布局和设计:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | #include "widget.h"
void Widget::iniUI()
{
//创建文本框,只读
textEdit = new QTextEdit;
textEdit->setReadOnly(1);
lineEdit = new QLineEdit;
BtnSend = new QPushButton("发送");
QHBoxLayout *HLay =new QHBoxLayout;
HLay->addWidget(lineEdit);
HLay->addWidget(BtnSend);
//创建垂直布局,并设置为主布局
QVBoxLayout *VLay=new QVBoxLayout(this);
VLay->addWidget(textEdit); //添加textEdit
VLay->addSpacing(5); //添加空隙
VLay->addLayout(HLay); //添加HLay
setLayout(VLay); //设置为窗口的主布局
}
//......省略
Widget::Widget(QWidget *parent)
: QWidget(parent)
{
setGeometry(0,0,640,480); //设置窗口大小
iniUI(); //窗口创建与初始化
setWindowTitle("串口测试"); //设置窗口标题
uart3.uart_open(); //连接串口
QTimer* timerRead = new QTimer;
timerRead->start(500);
//信号与槽的关联
connect(timerRead, SIGNAL(timeout()),this, SLOT(do_recvData()));
connect(lineEdit, SIGNAL(returnPressed()), this, SLOT(do_send()));
connect(BtnSend,SIGNAL(clicked()),this,SLOT(do_send()));
}
|
先在窗口中创建一个文本框,并且设置只读,然后创建一个QLineEdit,作为输入端(支持回车发送等),然后创建一个“发送”按钮。
创建组件后,添加一个布局控件,来规划整体窗口,然后设置为窗口的主体布局。
3.2.4. 串口通讯程序¶
点击左边资源目录,添加新文件(创建一个uart类,父类是QObject):
创建之后,在uart声明函数和变量等,在uart.cpp中实现:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | #include "uart.h"
Uart::Uart(QObject *parent)
: QObject{parent}
{
_fd=0;
}
void Uart::uart_open(QString dev, speed_t buad)
{
struct termios options;
if ((_fd = open(dev.toUtf8().data(), O_RDWR | O_NOCTTY | O_NDELAY | O_NONBLOCK)) == -1)
{
qDebug("open failed!");
return;
}
// 读写
fcntl (_fd, F_SETFL, O_RDWR) ;
// 设置波特率,串口的其他参数设置参考下https://doc.embedfire.com/linux/rk356x/linux_base/zh/latest/linux_app/uart/uart.html#id12
tcgetattr (_fd, &options);
cfmakeraw (&options) ;
cfsetispeed (&options, buad) ;
cfsetospeed (&options, buad) ;
tcsetattr (_fd, TCSANOW, &options) ;
}
|
3.3. 运行测试例程¶
3.3.2. 编译测试¶
选择 LubanCat_RK
编译套件,然后点击Qt Creator左下角的锤子符号,进行编译,会在构建目录下生成qt_serial可执行文件。
传输文件到板卡,然后执行命令:
# 复制可执行程序到板卡
scp qt_serial cat@192.168.103.110:/home/cat/qt
# 在debian10 带桌面的系统中运行,使用xcb
# 注意程序打开设备文件,需要root权限
sudo ./qt_serial -platform xcb
板卡运行程序,
PC端使用野火多功能串口,打开串口,设置默认串口参数 115200-N-8-1
,然后点击发送:
板端输入信息,然后点击发送或者回车发送:
提示
远程部署和测试,ssh连接需要root用户。