当前位置: 首页 > article >正文

第三个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


http://www.kler.cn/a/537197.html

相关文章:

  • MySQL的理解
  • 阿里云cdn怎样设置图片压缩
  • 力扣.623. 在二叉树中增加一行(链式结构的插入操作)
  • java手动实现常见数据结构
  • 水波效果
  • 从java角度对比nodejs、fastapi,同步和异步区别
  • 【redis】数据类型之string
  • 一条sql 在MySQL中是如何执行的
  • c语言:取绝对值
  • [笔记] 汇编杂记(持续更新)
  • HTML学习笔记(6)
  • ubuntu中如何在vscode的终端目录后显示(当前的git分支名) 实测有用
  • 组合总和II(力扣40)
  • centos7-mini-2009下载docker
  • Cloudflare 2024 网络流量回顾:洞悉网络发展趋势与安全挑战
  • 数据库读写分离、事务的特性、事务隔离级别及默认级别、脏读不可重复读和幻读、更新丢失问题、写偏斜问题、MVCC
  • 【开源免费】基于SpringBoot+Vue.JS智能学习平台系统(JAVA毕业设计)
  • 通过AutoHotkey将Windows按键修改为Mac的快捷键并设置开机自启动
  • 问题大集04-浏览器阻止从 本地 发起的跨域请求,因为服务器的响应头 Access-Control-Allow-Origin 设置为通配符 *
  • Vue3.5 企业级管理系统实战(五):图标组件
  • 远程 IO 模块:汽车零部件产线的高效生产引擎
  • AI智算-k8s部署DeepSeek Janus-Pro-7B 多模态大模型
  • 探索从传统检索增强生成(RAG)到缓存增强生成(CAG)的转变
  • selenium使用
  • Stable Diffusion的入门介绍和使用教程
  • 如何在Swift中实现基本的UI设计?