第三个Qt开发实例:利用之前已经开发好的LED驱动在Qt生成的界面中控制LED2的亮和灭
前言
上一篇博文 https://blog.csdn.net/wenhao_ir/article/details/145459006 中,我们是直接利用GPIO子系统控制了LED2的亮和灭,这篇博文中我们利用之前写好的LED驱动程序在Qt的生成的界面中控制LED2的亮和灭。
之前已经在下面两篇博文中实现了LED驱动程序:
https://blog.csdn.net/wenhao_ir/article/details/144973219
https://blog.csdn.net/wenhao_ir/article/details/145119224
本篇博文中我们就在Qt的代码中利用已经写好的LED驱动程序来控制LED2的亮和灭。由于第2个LED驱动程序要去修改设备树文件,比较麻烦,所以我们就用上面第1篇博文中的LED驱动程序来实现本篇博文“利用之前已经开发好的LED驱动在Qt生成的界面中控制LED2的亮和灭”的目的。
代码来源及修改说明
本文的代码在上一篇博文 https://blog.csdn.net/wenhao_ir/article/details/145459006 的基础上进行修改,其实只需要改动文件led.cpp中的代码,即把函数led_init
和函数led_control
按驱动程序的使用方法进行修改就行了。
由于之前是认真仔细地学习了驱动程序的书写,所以其实代码的修改是非常简单的,所以相关的代码就不去进行说明了。
完整源代码
文件mainwindow.ui 中的代码
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>800</width>
<height>600</height>
</rect>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<widget class="QWidget" name="centralwidget">
<widget class="QPushButton" name="pushButton">
<property name="geometry">
<rect>
<x>90</x>
<y>130</y>
<width>89</width>
<height>25</height>
</rect>
</property>
<property name="text">
<string>LED</string>
</property>
</widget>
<widget class="QLabel" name="label">
<property name="geometry">
<rect>
<x>260</x>
<y>80</y>
<width>71</width>
<height>41</height>
</rect>
</property>
<property name="text">
<string>TextLabel</string>
</property>
</widget>
<widget class="QLabel" name="label_2">
<property name="geometry">
<rect>
<x>260</x>
<y>160</y>
<width>71</width>
<height>31</height>
</rect>
</property>
<property name="text">
<string>TextLabel</string>
</property>
</widget>
</widget>
<widget class="QMenuBar" name="menubar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>800</width>
<height>22</height>
</rect>
</property>
</widget>
<widget class="QStatusBar" name="statusbar"/>
</widget>
<resources/>
<connections/>
</ui>
文件led.h中的代码
#ifndef LED_H
#define LED_H
void led_init(void);
void led_control(int on);
#endif // LED_H
文件mainwindow.h中的代码
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
private slots:
void on_pushButton_clicked();
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
文件led.cpp中的代码
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <QDebug>
static int fd;
void led_init(void)
{
fd = open("/dev/imx6ull_led0", O_RDWR);
if (fd < 0)
{
qDebug()<<"open /dev/imx6ull_led0 failed";
}
}
void led_control(int on)
{
char status;
// 因为int类型是占4个字节,而我只向驱动空间写入1个字节,正好char类型只占一个字节,所以这里要强制转换一下
// 当status为1时,驱动程序会在对应的GPIO口输出低电平,此时灯亮,反之灯灭
status = (char)on;
write(fd, &status, 1);
}
文件main.cpp中的代码
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "led.h"
#include <QDebug>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_pushButton_clicked()
{
static int status = 1;
if (status)
qDebug()<<"LED clicked on";
else
qDebug()<<"LED clicked off";
/* 2. control LED */
led_control(status);
status = !status;
}
文件mainwindow.cpp中的代码
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "led.h"
#include <QDebug>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_pushButton_clicked()
{
static int status = 1;
if (status)
qDebug()<<"LED clicked on";
else
qDebug()<<"LED clicked off";
/* 2. control LED */
led_control(status);
status = !status;
}
编译工程生成可执行程序
为了确保是新生成的可执行程序,所以把之前在别的博文中生成的可执行程序删掉~
然后编译:
生成了新的ELF可执行文件:
放到NFS网络文件目录中,备用:
把驱动程序放到NFS目录中备用
把博文 https://blog.csdn.net/wenhao_ir/article/details/144973219 中生成的驱动程序放到NFS目录中备用
上板测试
打开串口→启动开发板
打开串口终端→打开开发板
关掉开发板上自带的QT的GUI
经实测,如果不关闭开发板自带的QT的GUI,虽然你自己写的Qt界面能加载出来,但是当你用手划动屏幕时,开发板上自带的QT的GUI有可能会弹出来。
参考博文 https://blog.csdn.net/wenhao_ir/article/details/144591685 用一次性有效的方法(即不是永久有效的方法)关掉自带的QT的GUI界面。
这里用一次性的方法,即不是永久有效的方法:
执行下面这条命令:
/etc/init.d/S99myirhmi2 stop
执行完成后再用手去操作屏幕上的UI界面,UI界面就没有任何反应了,说明QT的GUI界面被关掉了
加载驱动程序
挂载网络文件系统:
mount -t nfs -o nolock,vers=3 192.168.5.11:/home/book/nfs_rootfs /mnt
加载驱动程序
insmod /mnt/qt_driver_led/led_driver.ko
设置Qt环境变量
export QT_QPA_GENERIC_PLUGINS=tslib:/dev/input/event1
export QT_QPA_PLATFORM=linuxfb:fb=/dev/fb0
export QT_QPA_FONTDIR=/usr/lib/fonts/
这三条命令的详细解释见 https://blog.csdn.net/wenhao_ir/article/details/145433648
运行编译生成的Qt程序
注意:运行前请确保Qt运行的环境变量设置好了。
注意:运行前请确保Qt运行的环境变量设置好了。
/mnt/qt_driver_led/test_01
屏幕如下图所示:
点击LED按钮1次:
终端运行结果如下:
此时LED2灯是亮着的。
再点LED按钮1次:
终端运行结果如下:
此是LED2灯灭了。
这样测试就成功了。
附编译完成后完整的工程目录
https://pan.baidu.com/s/1sOm3uA8q_TLcuGqPCJ2I2g?pwd=gt5u
注意:QtCreator的工程换位置后一定要更换一下Build directory的位置,因为在QtCreator中Build directory是一个绝对路径,详情见 https://blog.csdn.net/wenhao_ir/article/details/145458743