第二个Qt开发实例:在Qt中利用GPIO子系统和sysfs伪文件系统实现按钮(Push Button)点击控制GPIO口(效果为LED2灯的灭和亮)

引言

本文承接博文 https://blog.csdn.net/wenhao_ir/article/details/145420998 里的代码,在那里面代码的基础上添加上利用sysfs伪文件系统实现按钮(Push Button)点击控制GPIO口的代码,进而实现LED2灯的灭和亮。
最终的效果是点击下面的LED按钮实现LED2的灭和亮。
在这里插入图片描述
本文使用了GPIO子系统和sysfs伪文件系统去操控GPIO口,
关于GPIO子系统的详细介绍见:https://blog.csdn.net/wenhao_ir/article/details/145444452
关于sysfs伪文件系统的详细介绍见:https://blog.csdn.net/wenhao_ir/article/details/145453877

完整源代码

文件led.h中的代码

#ifndef LED_H
#define LED_Hvoid 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_NAMESPACEclass MainWindow : public QMainWindow
{Q_OBJECTpublic: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>void led_init(void)
{/** echo 131 > /sys/class/gpio/export* echo out > /sys/class/gpio/gpio131/direction*/int fd;fd = open("/sys/class/gpio/export", O_WRONLY);if (fd < 0){qDebug()<<"open /sys/class/gpio/export err";return ;}write(fd, "131\n", 4);close(fd);fd = open("/sys/class/gpio/gpio131/direction", O_WRONLY);if (fd < 0){qDebug()<<"open /sys/class/gpio/gpio131/direction err";return ;}write(fd, "out\n", 4);close(fd);
}void led_control(int on)
{/** echo 1 > /sys/class/gpio/gpio131/value* echo 0 > /sys/class/gpio/gpio131/value*/static int fd = -1;if (fd == -1){fd = open("/sys/class/gpio/gpio131/value", O_RDWR);}if (fd < 0){qDebug()<<"open /sys/class/gpio/gpio131/value err";return ;}if (on){write(fd, "0\n", 2);}else{write(fd, "1\n", 2);}
}

文件main.cpp中的代码

#include "mainwindow.h"
#include "led.h"
#include <QApplication>int main(int argc, char *argv[])
{/* 1. init LED */led_init();QApplication a(argc, argv);MainWindow w;w.show();return a.exec();
}

文件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";elseqDebug()<<"LED clicked off";/* 2. control LED */led_control(status);status = !status;
}

书写LED的初始化函数led_init()

在工程中新建一个名为led.cpp的文件:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

然后在其中写出LED的初始化函数led_init()
代码如下:

void led_init(void)
{/** echo 131 > /sys/class/gpio/export* echo out > /sys/class/gpio/gpio131/direction*/int fd;fd = open("/sys/class/gpio/export", O_WRONLY);if (fd < 0){qDebug()<<"open /sys/class/gpio/export err";return ;}write(fd, "131\n", 4);close(fd);fd = open("/sys/class/gpio/gpio131/direction", O_WRONLY);if (fd < 0){qDebug()<<"open /sys/class/gpio/gpio131/direction err";return ;}write(fd, "out\n", 4);close(fd);
}

上面这段代码如果把下面两篇博文:
https://blog.csdn.net/wenhao_ir/article/details/145444452
https://blog.csdn.net/wenhao_ir/article/details/145453877
认真看了一遍,那就很好理解了,所以这里就不再赘述。
如果时间紧的话,那就看:
第1篇博文中的“终端中如何利用GPIO子系统(gpiolib)操作GPIO口”
第2篇博文中的第1个标题中的内容。
不过强烈建议把两篇博文浏览一遍。

另外,关于文件描述符的相关知识,可以参考我的另一篇博文 https://blog.csdn.net/wenhao_ir/article/details/144931005

这里附一张下面这条命令运行结果:
在这里插入图片描述
注意,上面截图中的gpio131是运行了下面这条代码后才有的:

write(fd, "131\n", 4);

具体的过程我在博文 https://blog.csdn.net/wenhao_ir/article/details/145453877 中有描述,打开博文搜索“请求使用 GPIO 131”

书写LED的控制函数led_control()

在文件led.cpp里书写LED的控制函数led_control(),代码如下:

void led_control(int on)
{/** echo 1 > /sys/class/gpio/gpio131/value* echo 0 > /sys/class/gpio/gpio131/value*/static int fd = -1;if (fd == -1){fd = open("/sys/class/gpio/gpio131/value", O_RDWR);}if (fd < 0){qDebug()<<"open /sys/class/gpio/gpio131/value err";return ;}if (on){write(fd, "0\n", 2);}else{write(fd, "1\n", 2);}
}

如果理解了初始化函数led_init()里的代码,那么这段代码也就很简单了,这里就不再赘述了。

这里附一张下面这条命令运行结果:
在这里插入图片描述
注意,上面截图中的gpio131是运行了下面这条代码后才有的:

write(fd, "131\n", 4);

具体的过程我在博文 https://blog.csdn.net/wenhao_ir/article/details/145453877 中有描述,打开博文搜索“请求使用 GPIO 131”

解决led.cpp因缺少头文件而导致的各种报错

上面的函数led_init()led_control()写到文件led.cpp后,会有很多报错:
在这里插入图片描述
这些报错本质上都是因为工程的代码编辑器没有正确设置头文件目录,具体的设置方法见 https://blog.csdn.net/wenhao_ir/article/details/145479279

注意:这些报错只是代码编辑器的报错,并不是编译时的报错,我实测过,不解决这个问题,也能成功编译,因为Makefile中有相关的路径设置。

新建头文件led.h并书写头文件的内容

初始化函数led_init()和控制函数led_control()已经写完了,接下来我们要写个头文件对这两个函数声明,以便其它文件中的代码能引用这两个函数。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
写入led.h的代码如下:

#ifndef LED_H
#define LED_Hvoid led_init(void);
void led_control(int on);#endif // LED_H

在这里插入图片描述

main函数里调用初始化函数led_init()

在这里插入图片描述

类MainWindow的成员函数on_pushButton_clicked里调用控制函数led_control()

代码如下:

void MainWindow::on_pushButton_clicked()
{static int status = 1;if (status)qDebug()<<"LED clicked on";elseqDebug()<<"LED clicked off";/* 2. control LED */led_control(status);status = !status;
}

这段代码很简单,没啥好说的。

值得注意的是哪里与按钮事件联结起来的?这涉及到Qt的信号槽机制,就是下面这些东西:
在这里插入图片描述
上面红框中的东西我已经在博文 https://blog.csdn.net/wenhao_ir/article/details/145420998 中介绍过了,这里就不再赘述了。

编译工程

编译方法

在这里插入图片描述
成功编译,顺利生成ELF可执行文件:test_01
在这里插入图片描述
把生成的这个ELF可执行文件test_01复制到NFS网络文件目录中,备用。

这里要说明下,其实在 led.cpp中,用到了Linux系统的很多用户空间的函数,但是似乎我在配置QtCreator时没有去配置用户空间编译时需要的头文件和库呀,配置QtCreator的博文链接 https://blog.csdn.net/wenhao_ir/article/details/145367198

那是怎么回事呢?其实只要有sysroot位置就能有这些需要的头文件和库,关于sysroot的详细介绍,见 https://blog.csdn.net/wenhao_ir/article/details/145468785
这里QtCreator能根据qmake的位置找到sysroot的位置,所以自然就能编译啦。
我们查看QtCreator工程中的Makefile文件:
在这里插入图片描述
能发现sysroot的路径为:

/home/book/100ask_imx6ull-sdk/Buildroot_2020.02.x/output/host/arm-buildroot-linux-gnueabihf/sysroot

如下图所示:
在这里插入图片描述
所以是能正确构建的。

重要概念:Qt程序是运行于用户空间的

这里要注意:其实Qt工程中的代码都是运行于用户空间的,Qt本身就是在用户空间运行的程序,所以只需要提供sysroot,就能正常编译啦。

上板测试

复制可执行文件到NFS网络文件目录

把之前编译生成个ELF可执行文件test_01复制到NFS网络文件目录中。
在这里插入图片描述
打开串口终端→打开开发板→挂载网络文件系统:

mount -t nfs -o nolock,vers=3 192.168.5.11:/home/book/nfs_rootfs /mnt

关掉开发板上自带的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界面被关掉了

设置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_sys_led/test_01

屏幕如下图所示:
在这里插入图片描述
点击LED按钮1次:
终端运行结果如下:
在这里插入图片描述
此时LED2灯是亮着的。

再点LED按钮1次:
终端运行结果如下:
在这里插入图片描述
此是LED2灯灭了。

这样测试就成功了。

附编译完成后完整的工程目录

https://pan.baidu.com/s/1j7DVGZaZj0WtK3J-K2xnsQ?pwd=h5sp
注意:QtCreator的工程换位置后一定要更换一下Build directory的位置,因为在QtCreator中Build directory是一个绝对路径,详情见 https://blog.csdn.net/wenhao_ir/article/details/145458743

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/69190.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

登山第十七梯:矩形拟合——无惧噪声

文章目录 一 摘要 二 资源 三 内容 (文章末尾提供源代码) 一 摘要 目前,获取点集的矩形拟合结果的主要方法是计算其最小外包直立矩形或者旋转矩形。这些方法简单、易用,在数据质量良好的情况下能够较好的贴合矩形形状。然而,在数据缺失时,最小外包围盒方法将会…

57. Uboot图形化界面配置

一、Uboot图形化配置方法 1、通过终端配置。 2、进入到uboot的源码根目录下。 3、首先默认配置 make mx6ull_alientek_emmc_defconfig //默认配置 4、输入make menuconfig。打开图形化配置界面。 5、注意&#xff0c;新电脑需要安装ncurses库。sudo apt-get install libncurs…

Java面试场景题分享

假设你在做电商秒杀活动&#xff0c;秒杀开始时&#xff0c;成千上万的用户同时请求抢购商品。你会如何设计系统来处理这些请求&#xff0c;确保库存不超卖 你如何保证库存的准确性&#xff1f; 这个问题引导你思考如何在高并发下确保库存更新的原子性&#xff0c;最直接的方式…

kalman滤波器C++设计仿真实例第三篇

1. 仿真场景 水面上有条船在做匀速直线航行&#xff0c;航行过程中由于风和浪的影响&#xff0c;会有些随机的干扰&#xff0c;也就是会有些随机的加速度作用在船身上&#xff0c;这个随机加速度的均方差大约是0.1&#xff0c;也就是说方差是0.01。船上搭载GPS设备&#xff0c;…

(2025|ICLR,音频 LLM,蒸馏/ALLD,跨模态学习,语音质量评估,MOS)音频 LLM 可作为描述性语音质量评估器

Audio Large Language Models Can Be Descriptive Speech Quality Evaluators 目录 1. 概述 2. 研究背景与动机 3. 方法 3.1 语音质量评估数据集 3.2 ALLD 对齐策略 4. 实验结果分析 4.1 MOS 评分预测&#xff08;数值评估&#xff09; 4.2 迁移能力&#xff08;在不同…

stm32生成hex文件详解

1.产生的map文件干啥的&#xff1f; 2.组成情况&#xff1f;&#xff1f;&#xff1f; 废话少说&#xff0c;直接上代码具体内容况&#xff1a; Component: ARM Compiler 5.06 update 7 (build 960) Tool: armlink [4d3601]Section Cross Referencesstartup_stm32f103xe.o(S…

百度热力图数据获取,原理,处理及论文应用6

目录 0、数据简介0、示例数据1、百度热力图数据日期如何选择1.1、其他实验数据的时间1.2、看日历1.3、看天气 2、百度热力图几天够研究&#xff1f;部分文章统计3、数据原理3.1.1 ** 这个比较重要&#xff0c;后面还会再次出现。核密度的值怎么理解&#xff1f;**3.1.2 Csv->…

汽车自动驾驶AI

汽车自动驾驶AI是当前汽车技术领域的前沿方向&#xff0c;以下是关于汽车自动驾驶AI的详细介绍&#xff1a; 技术原理 感知系统&#xff1a;自动驾驶汽车通过多种传感器&#xff08;如激光雷达、摄像头、雷达、超声波传感器等&#xff09;收集周围环境的信息。AI算法对这些传感…

[转]Java面试近一个月的面试总结

本文是在学习中的总结&#xff0c;欢迎转载但请注明出处&#xff1a;http://blog.csdn.net/pistolove/article/details/46753275 前言 打算换个工作&#xff0c;近一个月面试了不少的公司&#xff0c;下面将一些面试经验和思考分享给大家。另外校招也快要开始了&#xff0c;为…

出租车特殊计费表算法解析与实现

目录 引言算法核心概念 特殊计费规则解析数据类型与输入输出算法数学原理 数字位判断与处理逻辑数值转换与累加计算算法框架图Python 实现 代码展示代码解析Python 实现的优势与局限C 语言实现 代码展示代码解析C 语言实现的性能特点性能分析与优化 性能分析 时间复杂度空间复杂…

学习threejs,tga格式图片文件贴图

&#x1f468;‍⚕️ 主页&#xff1a; gis分享者 &#x1f468;‍⚕️ 感谢各位大佬 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍⚕️ 收录于专栏&#xff1a;threejs gis工程师 文章目录 一、&#x1f340;前言1.1 ☘️TGA图片1.2 ☘️THREE.Mesh…

MSPFN 代码复现

1、环境配置 conda create -n MSPFN python3.9 conda activate MSPFN pip install opencv-python pip install tensorflow pip install tqdm pip install matplotlib2、train 2.1 创建数据集 2.1.1 数据集格式 |--rainysamples |--file1&#xff1a; |--file2:|--fi…

【创建模式-单例模式(Singleton Pattern)】

赐萧瑀 实现方案饿汉模式懒汉式&#xff08;非线程安全&#xff09;懒汉模式&#xff08;线程安全&#xff09;双重检查锁定静态内部类 攻击方式序列化攻击反射攻击 枚举(最佳实践)枚举是一种类 唐 李世民 疾风知劲草&#xff0c;板荡识诚臣。 勇夫安识义&#xff0c;智者必怀仁…

2025职业发展规划

2025职业发展规划 我是一名大公司的高级移动应用开发技术专家&#xff0c;目前参与了鸿蒙App开发&#xff0c;对鸿蒙的TS语言也有所了解。现在需要制定2025年的职业发展规划&#xff0c;包括学习内容和方向&#xff0c;并以思维导图的形式呈现。我需要梳理出合适的发展路径。首…

如何查看linux机器有几个cpu

在 Linux 机器上&#xff0c;你可以使用以下几种方法来查看 CPU 的数量&#xff08;物理 CPU 和逻辑 CPU&#xff09;&#xff1a; 方法 1&#xff1a;使用 lscpu 命令 lscpu输出示例&#xff1a; CPU(s): 8 Thread(s) per core: 2 Core(s) per socket: 4 Soc…

fputs的概念和使用案例

fputs 是 C 语言中用于向文件写入字符串的标准库函数。它与 puts 类似&#xff0c;但不会自动添加换行符&#xff0c;且支持向任意文件流&#xff08;如磁盘文件、标准输出等&#xff09;写入数据。 概念解析 函数原型&#xff1a;int fputs(const char *str, FILE *stream); …

宏观经济:信贷紧缩与信贷宽松、通货膨胀与通货紧缩以及经济循环的四个周期

目录 信贷紧缩与信贷宽松信贷紧缩信贷宽松信贷政策对经济影响当前政策环境 通货膨胀与通货紧缩通货膨胀通货紧缩通货膨胀与通货紧缩对比 经济循环的四个周期繁荣阶段衰退阶段萧条阶段复苏阶段经济周期理论解释经济周期类型 信贷紧缩与信贷宽松 信贷紧缩 定义&#xff1a;金融…

20240206 adb 连不上手机解决办法

Step 1: lsusb 确认电脑 usb 端口能识别设备 lsusb不知道设备有没有连上&#xff0c;就插拔一下&#xff0c;对比观察多了/少了哪个设备。 Step 2: 重启 adb server sudo adb kill-serversudo adb start-serveradb devices基本上就可以了&#xff5e; Reference https://b…

《利用原始数据进行深度神经网络闭环 用于光学驻留空间物体检测》论文精读

Deep Neural Network Closed-loop with Raw Data for Optical Resident Space Object Detection 摘要 光学勘测是观测驻留空间物体和空间态势感知的重要手段。随着天文技术和还原方法的应用&#xff0c;宽视场望远镜在发现和识别驻留空间物体方面做出了重大贡献。然而&#x…

2025年前端面试准备html篇

1.对html 语义化标签的理解 html语义化标签简单来说页面有良好的结构&#xff0c;使元素有含义便于理解。 优点可以使页面呈现出清晰的机构&#xff0c;有利于seo和搜索引擎抓取信息&#xff0c;便于团队的开发和管理。 常见的语义化标签有&#xff1a; <header> - 定义页…