资源简介
在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的渐变亮度效果。
以下是两种常见的方法:
-
线性调光:线性调光是通过改变LED的电流大小来实现渐变亮度效果。可以使用可变电阻、数字电位器或数字模拟转换器(DAC)来调节LED的电流。通过逐步增加或减小LED的电流,可以实现渐变亮度效果。然而,线性调光可能会导致LED的效率较低,因为LED的亮度与电流之间的关系并非线性。
-
使用多个LED:另一种方法是使用多个LED,并根据需要逐步打开或关闭这些LED来实现渐变亮度效果。例如,可以使用一组LED,每个LED的亮度不同,从而通过逐步打开或关闭这些LED来实现渐变亮度的效果。这种方法在一些特定的应用场景中比较常见,但需要更多的硬件资源。
需要注意的是,选择哪种方法取决于具体的应用需求和可用资源。脉冲宽度调制(PWM)是最常用和有效的方法之一,因为它可以通过改变信号的占空比来控制LED的亮度,并且在很多嵌入式系统中都有内置的PWM模块或库可用。其他方法可能需要更多的硬件和软件开发工作。
==END==