Qt点亮I.MX6U开发板的一个LED

news2025/1/21 9:35:50

本篇开始将会介绍与开发版相关的Qt项目,首先从点亮一个LED开始。I.MX6U和STM32MP157的相关信息都会用到,但是后期还是将I.MX6U的学习作为重点。当然其他开发版的开发也可以参考本博文。

文章目录

  • 1. Qt是如何操控开发板上的一个LED
  • 2. 出厂内核设备树中注册的LED设备
  • 3. 如何去使用驱动提供的应用层接口
    • 3.1 如何通过按钮控制LED
      • 3.1.1 需要先找到接口
      • 3.1.2 如何访问该接口
    • 3.2 开发UI程序控制LED灯
      • 3.2.1 在源文件“mainwindow.h”的代码如下
      • 3.2.2 在源文件“mainwindow.cpp” 的代码如下
  • 4. 程序运行效果
    • 4.1 Ubuntu 上仿真界面的效果
    • 4.2 板卡上运行效果

1. Qt是如何操控开发板上的一个LED

Qt是无法直接控制开发板上的硬件,那么它是如何操控开发板上的硬件的呢?
从下图可以看到是Qt通过驱动层提供的接口来操控开发板上的硬件
在这里插入图片描述
关于驱动提供的接口可以从正点原子的驱动和试用教程,具体在哪?后期找一下。

如果你是应用开发人员,就要问驱动人员提供的接口信息。

2. 出厂内核设备树中注册的LED设备

此部分没有特别清楚,大概讲的应该就是Linux系统安装中2.3 硬件设备文件名中内容。

I.MX6U和STM32MP157的出厂系统如下:

  • I.MX6U设备树路径为:arch/arm/boot/dts/imx6ull-14x14-evk.dts
  • STM32MP157设备树路径为:arch/arm/boot/dts/stm32mp157d-atk.dtsi

(1)要找到设备树,先找到Linux源码
在“01、例程源码\03、正点原子Uboot和Linux出厂源码”下文件内容如下:
在这里插入图片描述
应用层访问的ID设备,都是在上图框选的Linux源码配置的,如何编译这个源码,正点原子的其他教程中做了介绍,此处不再做介绍。

(2)下面应该就是Linux源码的关于LED灯部分的内容
在这里插入图片描述
上图为I.MX6U的,led节点,其中是一个LED即led1,配置了sys.led,也就是系统ID,即收到货时闪的那个led,其中的heartbeat代表正在运行,gpio.leds代表驱动,本篇使用到的也就是该LED。

3. 如何去使用驱动提供的应用层接口

想要控制这个 LED,首先I.MX6U的出厂内核已经默认将这个 LED 注册成了 gpio-leds类型设备(驱动层配置给应用层的接口)。 所以我们可以直接在应用层接口直接可以操作这个 LED 设备。(如果搞了一些移植,有可能LED没有配置,就无法正常使用)
以下将会介绍如何查找和使用接口控制LED灯的过程。

3.1 如何通过按钮控制LED

3.1.1 需要先找到接口

“10、用户手册/01【正点原子】I.MX6U用户快速体验V2.6.pdf”中查找说明
在这里插入图片描述
上图中驱动提供的对应的接口文件即为:

echo none > /sys/class/leds/sys-led/trigger // 改变 LED 的触发模式
echo 1 > /sys/class/leds/sys-led/brightness // 向接口写1点亮 LED
echo 0 > /sys/class/leds/sys-led/brightness // 向接口写0熄灭 LED

3.1.2 如何访问该接口

我们在 Qt 里有很多种方法可以控制正点原子 I.MX6U 的 LED 设备。 如可以用 C 语言的读写函数读写来控制 LED的状态,或者直接使用 system()函数启动一个进程执行相关指令直接控制 LED 等。
我们介绍最简单的方法控制开发板上的LED, 就是使用Qt的操作文件的类QFile直接控制LED因为 Linux 上一切皆文件,所有的东西都当作文件来处理。

/* 开发板的 LED 控制接口 */
file.setFileName("/sys/devices/platform/leds/leds/sys-led/brightness");

项目虽然简单,但是在嵌入式里基本都是从点亮一个 LED 里开始说起。
只有我们会操作一个 IO,剩下的基本都不会难!

3.2 开发UI程序控制LED灯

项目简介:设置一个按钮,点击即可控制 LED 状态反转(点亮或者熄灭 LED)。 项目看来很起来很简单, 实际上有些需要注意的地方,我们在改变 LED 的状态时,需要先去读取 LED的状态,防止外界(外面应用程序)将 LED 的状态改变了。 否则我们反转操作将不成立。 在C++里一般使用 get()和 set()方法来获取和设置。我们的 LED 程序里也有这种方法。所以需要写好一个让人看得懂的程序是有“方法”的。不能将程序功能写在一堆,最好是分开写,留有接口。让后面的人看懂!

3.2.1 在源文件“mainwindow.h”的代码如下

#ifndef MAINWINDOW_H
2 #define MAINWINDOW_H
3 4
#include <QMainWindow>
5 #include <QPushButton>
6 #include <QFile>
7 8
class MainWindow : public QMainWindow
9 {
10 Q_OBJECT
11
12 public:
13 MainWindow(QWidget *parent = nullptr);
14 ~MainWindow();
15
16 private:
17 /* 按钮 */
18 QPushButton *pushButton;
19
20 /* 文件 */
21 QFile file;
22
23 /* 设置 lED 的状态 */
24 void setLedState();
25
26 /* 获取 lED 的状态 */
27 bool getLedState();
28
29 private slots:
30 void pushButtonClicked();
31 };
32 #endif // MAINWINDOW_H

在头文件“mainwindow.h”里第 24 行声明一个设置 LED 状态方法, 另一个是获取状态的方法。 另外声明一个槽函数,作用是点击切换 LED 的状态。

3.2.2 在源文件“mainwindow.cpp” 的代码如下

#include "mainwindow.h"
2 #include <QDebug>
3 #include <QGuiApplication>
4 #include <QScreen>
5 #include <QRect>
6 7
MainWindow::MainWindow(QWidget *parent)
8 : QMainWindow(parent)
9 {
10 /* 获取屏幕的分辨率, Qt 官方建议使用这
11 * 种方法获取屏幕分辨率,防上多屏设备导致对应不上
12 * 注意,这是获取整个桌面系统的分辨率
13 */
14 QList <QScreen *> list_screen = QGuiApplication::screens();
15
16 /* 如果是 ARM 平台,直接设置大小为屏幕的大小 */
17 #if __arm__
18 /* 重设大小 */
19 this->resize(list_screen.at(0)->geometry().width(),
20 list_screen.at(0)->geometry().height());
21 /* 默认是出厂系统的 LED 心跳的触发方式,想要控制 LED,
22 * 需要改变 LED 的触发方式,改为 none,即无 */
23 system("echo none > /sys/class/leds/sys-led/trigger");
24 #else
25 /* 否则则设置主窗体大小为 800x480 */
26 this->resize(800, 480);
27 #endif
28
29 pushButton = new QPushButton(this);
30
31 /* 居中显示 */
32 pushButton->setMinimumSize(200, 50);
33 pushButton->setGeometry((this->width() - pushButton->width()) /2 ,
34 (this->height() - pushButton->height()) /2,
35 pushButton->width(),
36 pushButton->height()
37 );
38 /* 开发板的 LED 控制接口 */
39
file.setFileName("/sys/devices/platform/leds/leds/sys-led/brightness");

if (!file.exists())
42 /* 设置按钮的初始化文本 */
43 pushButton->setText("未获取到 LED 设备! ");
44
45 /* 获取 LED 的状态 */
46 getLedState();
47
48 /* 信号槽连接 */
49 connect(pushButton, SIGNAL(clicked()),
50 this, SLOT(pushButtonClicked()));
51 }
52
53 MainWindow::~MainWindow()
54 {
55 }
56
57 void MainWindow::setLedState()
58 {
59 /* 在设置 LED 状态时先读取 */
60 bool state = getLedState();
61
62 /* 如果文件不存在,则返回 */
63 if (!file.exists())
64 return;
65
66 if(!file.open(QIODevice::ReadWrite))
67 qDebug()<<file.errorString();
68
69 QByteArray buf[2] = {"0", "1"};
70
71 /* 写 0 或 1 */
72 if (state)
73 file.write(buf[0]);
74 else
75 file.write(buf[1]);
76
77 /* 关闭文件 */
78 file.close();
79
80 /*重新获取 LED 的状态 */
81 getLedState();
82 }
bool MainWindow::getLedState()
85 {
86 /* 如果文件不存在,则返回 */
87 if (!file.exists())
88 return false;
89
90 if(!file.open(QIODevice::ReadWrite))
91 qDebug()<<file.errorString();
92
93 QTextStream in(&file);
94
95 /* 读取文件所有数据 */
96 QString buf = in.readLine();
97
98 /* 打印出读出的值 */
99 qDebug()<<"buf: "<<buf<<endl;
100 file.close();
101 if (buf == "1") {
102 pushButton->setText("LED 点亮");
103 return true;
104 } else {
105 pushButton->setText("LED 熄灭");
106 return false;
107 }
108 }
109
110 void MainWindow::pushButtonClicked()
111 {
112 /* 设置 LED 的状态 */
113 setLedState();
114 }

第 9 行~24 行,界面初始化设置,在嵌入式里,根据实际的屏的大小,设置全屏显示。按钮居中显示。

第 23 行,因为出厂系统里配置 LED 的触发方式为心跳方式, 要想控制此 LED,需要将 LED的触发方式改为none,即是无触发方式。为了方便,编者直接使用 system()函数,用指令的方式改变 LED 的触发方式。

第 54~82 行设置 LED 的方法,写入“0”或“1”代表开和关。 写入之前先读取 LED 的状态,预防在用户其他地方有设置过 LED。

第 84 行~108 行, 获取 LED 的状态。

第 110 行~114 行设置 LED 的状态,此方法为槽函数,由点击按钮触发。

4. 程序运行效果

4.1 Ubuntu 上仿真界面的效果

下面为 Ubuntu 上仿真界面的效果,由于 Ubuntu 不是“开发板”,所以在读取 LED 设备时会读取失败。实际在板上运行图略。 交叉编译程序到正点原子 I.MX6U 开发板上运行即可控制LED 的状态。
在这里插入图片描述

4.2 板卡上运行效果

按照上一篇I.MX6U开发板交叉编译Qt项目进行交叉编译,拷贝到开发板的Linux系统中,可以看到通过UI上的按钮控制了LED灯。
在这里插入图片描述

对应地址:Qt点亮I.MX6U开发板的一个LED

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

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

相关文章

linux修改最大线程数却未生效的原因

可能是没有重新对新文件进行编译 更改一个进程所能创建的最大进程数之前 更改一个进程所能创建的最大进程数之后 测试代码 #include <iostream> #include <unistd.h> #include <sys/wait.h> #include <string.h> #include <stdio.h> #include…

学生信息系统(python实现)

#codingutf-8 import os.path filenamestudent.txtdef menm():#菜单界面print(学生管理系统)print(-----------------------------功能菜单-----------------------------)print(\t\t\t\t\t\t1.录入学生信息)print(\t\t\t\t\t\t2.查找学生信息)print(\t\t\t\t\t\t3.删除学生信息…

合宙Air724UG LuatOS-Air LVGL API控件-图片(Gif)

图片&#xff08;Gif&#xff09; GIF图片显示&#xff0c;core版本号要>3211 示例代码 方法一 -- 创建GIF图片控件 glvgl.gif_create(lvgl.scr_act()) -- 设置显示的GIF图像 lvgl.gif_set_src(g,"/lua/test.gif") -- gif图片居中 lvgl.obj_align(g, nil, lvgl…

软件测试行业35岁职场魔咒,你准备怎么应对?

以前就流传一种说法“IT行业职场35岁危机”&#xff0c;那时我半信半疑。 或许那时觉得还离我比较遥远&#xff0c;也或许那时每天都重复着996&#xff0c;工作上的任务已经应接不暇&#xff0c;每天都处在忙碌中&#xff0c;也没精力花时间去过多思考这个问题。休息的时候能好…

机器学习实战-系列教程7:SVM分类实战2线性SVM(鸢尾花数据集/软间隔/线性SVM/非线性SVM/scikit-learn框架)项目实战、代码解读

&#x1f308;&#x1f308;&#x1f308;机器学习 实战系列 总目录 本篇文章的代码运行界面均在Pycharm中进行 本篇文章配套的代码资源已经上传 SVM分类实战1之简单SVM分类 SVM分类实战2线性SVM SVM分类实战3非线性SVM 3、不同软间隔C值 3.1 数据标准化的影响 如图左边是没…

GLSL ES着色器 精度限定字

目录 前言 WebGL支持的三种精度 数据类型的默认精度 float类型没有默认精度 预处理指令 在GLSL ES中常用的三种预处理指令。 预定义的内置宏 前言 GLSL ES新引入了精度限定字&#xff0c;目的是帮助着色器程序提高运行效率&#xff0c;削减内存开支。顾名思义&#xf…

Kafka3.0.0版本——消费者(自动提交 offset)

目录 一、自动提交offset的相关参数二、消费者&#xff08;自动提交 offset&#xff09;代码示例 一、自动提交offset的相关参数 官网文档 参数解释 参数描述enable.auto.commi默认值为 true&#xff0c;消费者会自动周期性地向服务器提交偏移量。auto.commit.interval.ms如果…

《TCP/IP网络编程》阅读笔记--I/O复用

1--基于I/O复用的服务器 多进程服务器端具有以下缺点&#xff1a;当有多个客户端发起连接请求时&#xff0c;就会创建多个进程来分别处理客户端的请求&#xff0c;创建多个进程往往需要付出巨大的代价&#xff1b; I/O复用的服务器端可以减少进程数&#xff0c;无论连接多少个客…

Ubuntu22.04_如何调试ROS2_humble的源代码

这里的源码&#xff0c;是指的ros2 humble的官方源码。如果是自己手撸的节点或相关源码&#xff0c;请参考本人以前的贴子&#xff0c; Ubuntu20.04vscode快速调试ROS通用程序_ubuntu20.04vscode那个版本和ros 兼容_高精度计算机视觉的博客-CSDN博客 Ubuntu20.04&#xff0b;…

【pygame】01 pygame制作游戏的最小系统

这次使用sublimepython进行pygame的游戏开发&#xff0c;目的是学习使用python的基本操作和常用模块 添加一个文件夹到工程 最小系统 import pygame import sys ##导入sys模块 主要是为了 exit函数 from pygame.locals import * #导入一些常用的函数和常量pygame.init() …

计算机网络第四章——网络层(上)

提示&#xff1a;朝碧海而暮苍梧,睹青天而攀白日 文章目录 网络层是路由器的最高层次&#xff0c;通过网络层就可以将各个设备连接到一起&#xff0c;从而实现这两个主机的数据通信和资源共享&#xff0c;之前学的数据链路层和物理层也是将两端连接起来&#xff0c;但是却没有网…

C语言——指针进阶(2)

继续上次的指针&#xff0c;想起来还有指针的内容还没有更新完&#xff0c;今天来补上之前的内容&#xff0c;上次我们讲了函数指针&#xff0c;并且使用它来实现一些功能&#xff0c;今天我们就讲一讲函数指针数组等内容&#xff0c;废话不多说&#xff0c;我们开始今天的学习…

ESP32蓝牙主从站模式:主站发送,从站接收,同时附加简单通信协议

主站发送:WXAiBj,六个字符 蓝牙模式是一个字符一个字符发送 主站和从站设置通信协议 使得六个字符一句话完整接收,同时打印出接收完成信息 硬件电路连接如下: 主从站为两个ESP32,只使用了其中的蓝牙功能 代码如下: 主站: //主机模式 #include <Arduino.h> …

ARM指令集--数据处理指令

数据处理指令&#xff1a;数学运算&#xff0c;逻辑运算 立即数 立即数的本质 就是包含在指令当中的数&#xff0c;属于指令的一部分 立即数的优点&#xff1a;取指的时候就可以将其读取到CPU&#xff0c;不用单独去内存读取&#xff0c;速度快 立即数的缺点&#xff1a;不…

vue学习之内容渲染

内容渲染 创建 demo2.html,内容如下 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Document</…

敏捷项目管理完整流程及实践管理方法

​Scrum是目前运用最为广泛的敏捷开发方法&#xff0c;是一个轻量级的项目管理和产品研发管理框架&#xff0c;旨在最短时间内交付最大价值。 Leangoo领歌是一款永久免费的专业敏捷研发管理工具&#xff0c;提供敏捷研发解决方案&#xff0c;解决研发痛点&#xff0c;打造成功…

学习机器学习需要哪些数学知识?

作为一门以数据及其模型为 研究对象的学科&#xff0c;优化模型、分析模型性能等都需要数学手段的帮助。和其他学科一样&#xff0c;数学 可以帮我们更清晰地描述和理解机器学习算法&#xff0c;也可以从理论上证明算法的有效性&#xff0c;是机器学习中必不可少的一环。 1 向…

【数据结构】AVL树的插入与验证

文章目录 一、基本概念1.发展背景2.性质 二、实现原理①插入操作1.平衡因子1.1平衡因子的更新1.1.1树的高度变化1.1.2树的高度不变 2. 旋转2.1左旋2.2右旋2.3右左双旋2.4 左右双旋 ②验证1.求二叉树高度2. 判断是否为AVL树 源码总结 一、基本概念 1.发展背景 普通的二叉搜索树…

Linux常见进程类别

目录 常见进程类别 守护进程&精灵进程 任务管理 进程组 作业 作业 | 进程组 会话 w命令 守护进程 守护进程的创建 setsid()函数 daemon()函数 模拟实现daemon函数 前台进程 | 后台进程 僵尸进程 | 孤儿进程 僵尸进程的一些细节 守护进程 | 后台进程 守护…