基于 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==

相关推荐
道之极万物灭24 分钟前
Go小工具合集
开发语言·后端·golang
瑞士卷@25 分钟前
MyBatis入门到精通(Mybatis学习笔记)
java·数据库·后端·mybatis
yuuki2332331 小时前
【C语言】文件操作(附源码与图片)
c语言·后端
IT_陈寒1 小时前
Python+AI实战:用LangChain构建智能问答系统的5个核心技巧
前端·人工智能·后端
无名之辈J1 小时前
系统崩溃(OOM)
后端
码农刚子2 小时前
ASP.NET Core Blazor简介和快速入门 二(组件基础)
javascript·后端
间彧2 小时前
Java ConcurrentHashMap如何合理指定初始容量
后端
catchadmin2 小时前
PHP8.5 的新 URI 扩展
开发语言·后端·php
少妇的美梦2 小时前
Maven Profile 教程
后端·maven
白衣鸽子2 小时前
RPO 与 RTO:分布式系统容灾的双子星
后端·架构