基于 Qt控制开发板 LED和C语言控制LED渐变亮度效果

资源简介

在STM32开发板,板载资源上有两个可自由控制的 LED。如下图原理 图其中我们以操作 LED1 为示例,LED1 为出厂系统的心跳指示灯。

应用实例

想要控制这个 LED,首先出厂内核已经默认将这个 LED 注册成了 gpio-leds类型设备。所以我们可以直接在应用层接口直接可以操作这个 LED 设备。如可以用 C 语言的读写函数读写来控制LED 的状态,或者直接使用 system()函数启动一个进程执行相关指令直接控制 LED 等。

我们介绍最简单的方法控制开发板上的LED,就是使用Qt的操作文件的类直接控制LED。因为 Linux 上一切皆文件,所有的东西都当作文件来处理。下面将贴上代码,其中不会再去讲如何搭建工程,不会贴上实验现象图。代码注释详细,不额外说明。实现现象请自行编译到开发板上运行查看。项目虽然简单,但是在嵌入式里基本都是从点亮一个 LED 里开始说起。只有我们会操作一个 IO,剩下的基本都不会难!

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

项目源码

​头文件:

js 复制代码
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QPushButton>
#include <QFile>
class MainWindow : public QMainWindow
{
    Q_OBJECT
public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();
private:
    /* 按钮 */
     QPushButton *pushButton;
    /* 文件 */
     QFile file;
    /* 设置 LED 的状态 */
    void setLEDState();
    /* 获取 LED 的状态 */
    bool getLEDState();
    private slots:
    /* 槽函数 */
    void pushButtonClicked();
};
#endif // MAINWINDOW_H

​源文件:

js 复制代码
#include "mainwindow.h"
#include <QDebug>
#include <QGuiApplication>
#include <QScreen>
#include <QRect>
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    /* 获取屏幕的分辨率,Qt 官方建议使用这
        11 * 种方法获取屏幕分辨率,防上多屏设备导致对应不上
        12 * 注意,这是获取整个桌面系统的分辨率
        13 */
        QList<QScreen *>list_screen = QGuiApplication::screens();
    /* 如果是 ARM 平台,直接设置大小为屏幕的大小 */
    #if __arm__
    /* 重设大小 */
    this->resize(list_screen.at(0)->geometry().width(),list_screen.at(0)->geometry().height());
    /* 默认是出厂系统的 LED 心跳的触发方式,想要控制 LED,
            * 需要改变 LED 的触发方式,改为 none,即无 */
            system("echo none > /sys/class/leds/sys-led/trigger");
    #else
    /* 否则则设置主窗体大小为 800x480 */
    this->resize(800, 480);
    #endif
        pushButton = new QPushButton(this);
    /* 居中显示 */
         pushButton->setMinimumSize(200, 50);
         pushButton->setGeometry((this->width() - pushButton->width()) /2 ,
             (this->height() - pushButton->height()) /2,
             pushButton->width(),
             pushButton->height()
         );
        file.setFileName("/sys/devices/platform/leds/leds/sys-led/brightness");
    if (!file.exists())
    /* 设置按钮的初始化文本 */
             pushButton->setText("LED device does not exist");
    /* 获取 LED 的状态 */
    getLEDState();
    /* 信号槽连接 */
         connect(pushButton, SIGNAL(clicked()),this, SLOT(pushButtonClicked()));
}
MainWindow::~MainWindow()
{
}
/* 设置 LED 的状态 */
void MainWindow::setLEDState()
{
    /* 在设置 LED 状态时先读取 */
    bool state = getLEDState();
    /* 如果文件不存在,则返回 */
    if (!file.exists()) {
        return;
         }
    if(!file.open(QIODevice::ReadWrite))
                qDebug()<<file.errorString();
    // 蜂鸣器开或关
         QByteArray buf[2] = {"0", "1"};
    if (state)
            file.write(buf[0]);
    else
            file.write(buf[1]);
         file.close();
    /* 更新按钮状态 */
         getLEDState();
}
/* 获取 LED 的状态 */
bool MainWindow::getLEDState()
{
    /* 如果文件不存在,则返回 */
    if (!file.exists())
        return false;
    if(!file.open(QIODevice::ReadWrite))
             qDebug()<<file.errorString();
    QTextStream in(&file);
    /* 读取文件所有数据 */
         QString buf = in.readLine();
    /* 打印出读出的值 */
         qDebug()<<"buf: "<<buf<<endl;
          file.close();
    if (buf == "1") {
              pushButton->setText("LED 开");
    return true;
          } else {
              pushButton->setText("LED 关");
    return false;
          }
}
void MainWindow::pushButtonClicked()
{
    /* 设置蜂鸣器的状态 */
     setLEDState();
}

代码​解析

【1】界面初始化设置,在嵌入式里,根据实际的屏的大小,设置全屏显示。按钮居中显示。

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

【3】设置 LED 的方法,写入"0"或"1"代表开和关。写入之前先读取 LED 的状态,预防在用户其他地方有设置过 LED。

【4】获取 LED 的状态

【5】设置 LED 的状态,此方法为槽函数,由点击按钮触发。至此常规的控制一个 IO,大概流程已经完成。​

程序运行效果


C语言举例LED

嵌入式LED (Light-Emitting Diode) 是一种常用于嵌入式系统中的发光二极管。LED是一种固态电子器件,具有低功耗、长寿命和快速开关速度等特点。在嵌入式系统中,LED通常用作指示灯、状态指示器或显示器的一部分。

嵌入式LED可以通过控制引脚的电平状态来控制其亮灭。一般来说,将引脚设置为高电平会导致LED点亮,而将引脚设置为低电平会导致LED熄灭。控制LED的具体方法取决于所使用的硬件平台和编程语言。

在嵌入式开发中,通常需要包含相关的头文件以便在代码中使用LED的控制函数、常量或宏定义等。头文件包含了相关的声明和定义,使得编译器能够正确理解和处理LED相关的代码。

例如,在C语言中,可以使用如下的头文件和函数来控制嵌入式LED:

c 复制代码
#include <gpio.h>
// 控制LED亮灭的函数
void setLedState(int pin, int state) {
// 设置引脚为输出模式
    gpio_set_direction(pin, GPIO_MODE_OUTPUT);
// 控制引脚电平状态
if (state == 1) {
        gpio_set_level(pin, 1);  // 设置引脚为高电平,点亮LED
    } else {
        gpio_set_level(pin, 0);  // 设置引脚为低电平,熄灭LED
    }
}

上述代码中的gpio.h头文件包含了控制GPIO引脚的相关函数和常量定义。通过调用setLedState函数并传入相应的引脚号和状态值,可以控制LED的亮灭。

请注意,具体的头文件和函数名称可能因硬件平台、开发环境或使用的编程语言而有所不同。因此,在实际开发中,建议查阅所使用的嵌入式平台或开发工具的文档,以了解正确的头文件和函数使用方式。

如何在嵌入式系统中实现LED的渐变亮度效果?

要在嵌入式系统中实现LED的渐变亮度效果,可以利用脉冲宽度调制(PWM)技术。PWM是一种调节信号的方法,通过改变信号的占空比(高电平的时间占总周期的比例),来模拟出不同亮度的效果。

以下是一个在嵌入式系统中使用PWM实现LED渐变亮度效果的示例代码(假设使用C语言和特定的开发平台):

c 复制代码
#include <gpio.h>
#include <pwm.h>
#define PWM_CHANNEL 0  // PWM通道号
#define PWM_FREQ 1000  // PWM频率,单位为赫兹
#define LED_PIN 2      // LED连接的引脚号
void setupPWM() {
    // 初始化PWM模块
    pwm_init(PWM_CHANNEL, PWM_FREQ);
    // 设置引脚为PWM输出模式
    gpio_set_direction(LED_PIN, GPIO_MODE_OUTPUT);
    // 将PWM通道与引脚关联
    pwm_attach_pin(PWM_CHANNEL, LED_PIN);
}
void setLedBrightness(float brightness) {
    // 将亮度值映射到PWM周期范围内
    uint32_t duty_cycle = (uint32_t)(brightness * PWM_CYCLE_RANGE);
    // 设置PWM占空比
    pwm_set_duty(PWM_CHANNEL, duty_cycle);
    // 更新PWM输出
    pwm_start(PWM_CHANNEL);
}
int main() {
    setupPWM();
    while (1) {
    // 实现渐变亮度效果
    for (float brightness = 0.0; brightness <= 1.0; brightness += 0.1) {
                setLedBrightness(brightness);
                delay_ms(100);  // 延时一段时间,使亮度渐变可见
            }
        }
    return 0;
}

上述代码中,首先使用pwm_init函数初始化PWM模块,并将LED连接的引脚设置为PWM输出模式。然后,通过pwm_attach_pin函数将PWM通道与引脚关联。在setLedBrightness函数中,将期望的亮度值映射到PWM周期范围内,并使用pwm_set_duty函数设置PWM占空比。最后,通过循环逐渐增加亮度值,调用setLedBrightness函数实现LED的渐变亮度效果,并使用delay_ms函数延时一段时间,使亮度渐变可见。

请注意,具体的实现方式可能因使用的嵌入式平台、开发工具或编程语言而有所不同。因此,在实际开发中,建议查阅所使用的嵌入式平台或开发工具的文档,以了解正确的PWM库和函数使用方式。

除了脉冲宽度调制(PWM)技术,还有其他方法可以在嵌入式系统中实现LED的渐变亮度效果。

以下是两种常见的方法:

  1. 线性调光:线性调光是通过改变LED的电流大小来实现渐变亮度效果。可以使用可变电阻、数字电位器或数字模拟转换器(DAC)来调节LED的电流。通过逐步增加或减小LED的电流,可以实现渐变亮度效果。然而,线性调光可能会导致LED的效率较低,因为LED的亮度与电流之间的关系并非线性。

  2. 使用多个LED:另一种方法是使用多个LED,并根据需要逐步打开或关闭这些LED来实现渐变亮度效果。例如,可以使用一组LED,每个LED的亮度不同,从而通过逐步打开或关闭这些LED来实现渐变亮度的效果。这种方法在一些特定的应用场景中比较常见,但需要更多的硬件资源。

需要注意的是,选择哪种方法取决于具体的应用需求和可用资源。脉冲宽度调制(PWM)是最常用和有效的方法之一,因为它可以通过改变信号的占空比来控制LED的亮度,并且在很多嵌入式系统中都有内置的PWM模块或库可用。其他方法可能需要更多的硬件和软件开发工作。

==END==

相关推荐
姜学迁1 小时前
Rust-枚举
开发语言·后端·rust
爱学习的小健2 小时前
MQTT--Java整合EMQX
后端
北极小狐2 小时前
Java vs JavaScript:类型系统的艺术 - 从 Object 到 any,从静态到动态
后端
【D'accumulation】2 小时前
令牌主动失效机制范例(利用redis)注释分析
java·spring boot·redis·后端
2401_854391082 小时前
高效开发:SpringBoot网上租赁系统实现细节
java·spring boot·后端
Cikiss2 小时前
微服务实战——SpringCache 整合 Redis
java·redis·后端·微服务
Cikiss2 小时前
微服务实战——平台属性
java·数据库·后端·微服务
OEC小胖胖3 小时前
Spring Boot + MyBatis 项目中常用注解详解(万字长篇解读)
java·spring boot·后端·spring·mybatis·web
2401_857617623 小时前
SpringBoot校园资料平台:开发与部署指南
java·spring boot·后端
计算机学姐3 小时前
基于SpringBoot+Vue的在线投票系统
java·vue.js·spring boot·后端·学习·intellij-idea·mybatis