linux LED代码设计

设计目标:

写RGB LED灭、亮、闪烁等效果,不同颜色也需要设置

cpp 复制代码
#include <iostream>
#include <unistd.h> // 对于usleep()
#include <fcntl.h>  // 对于open(), close()
#include <sys/ioctl.h> // 对于ioctl()
#include <linux/gpio.h> // GPIO相关宏定义

// 假设已经有了设置GPIO和PWM的函数,这里仅展示GPIO输出设置

void set_gpio_output(int gpio_chip, int offset, bool value) {
    // 注意:这里只是一个框架,实际实现需要根据系统和GPIO库
    // 创建一个到GPIO设备的文件描述符
    int fd = open("/dev/gpiochip" + std::to_string(gpio_chip), O_RDWR);
    if (fd < 0) {
        std::cerr << "Failed to open GPIO chip device" << std::endl;
        return;
    }

    // 设置GPIO方向为输出
    struct gpiolib_direction_request req = {
        .line_offset = offset,
        .flags = GPIOLIB_SET_DIRECTION_OUT,
        .values[0] = value, // 初始值
    };
    if (ioctl(fd, GPIOLIB_SET_DIRECTION, &req) < 0) {
        std::cerr << "Failed to set GPIO direction" << std::endl;
        close(fd);
        return;
    }

    // 如果想改变GPIO的值,可以再次使用ioctl()或libgpiod提供的函数
    // 注意:这里我们假设GPIO的值已经在设置方向时初始化了

    close(fd);
}

int main() {
    // 假设GPIO芯片号为0,引脚偏移量为9(红色LED)、10(绿色LED)、11(蓝色LED)
    int gpio_chip = 0;
    int red_pin = 9;
    int green_pin = 10;
    int blue_pin = 11;

    // 打开红色LED
    set_gpio_output(gpio_chip, red_pin, true);
    sleep(1); // 等待一秒

    // 关闭所有LED
    set_gpio_output(gpio_chip, red_pin, false);
    set_gpio_output(gpio_chip, green_pin, false);
    set_gpio_output(gpio_chip, blue_pin, false);

    // 注意:这里没有实现PWM控制,因为PWM控制通常涉及更复杂的设置
    // 可能需要使用专门的PWM库或系统调用来控制PWM

    return 0;
}

// 注意:
// 1. 上面的代码使用了"/dev/gpiochip"和GPIOLIB_SET_DIRECTION,这些在标准的Linux系统中并不存在。
//    需要使用如libgpiod或其他GPIO控制库来正确设置GPIO。
// 2. PWM控制通常涉及对`/sys/class/pwm/pwmchipX/pwmY/`目录的写入操作,或者使用专门的PWM库。
// 3. 错误处理非常基础,实际应用中需要更完善的错误处理和资源管理。

对于PWM控制,你需要查找你的Linux发行版和硬件平台支持的PWM控制方法。通常,这涉及到对/sys/class/pwm/目录下的文件进行操作,或者使用专门的PWM库。

当然,我们可以将上述代码拆分成多个.cpp.h文件,以便更好地组织和管理代码。以下是一个简单的拆分示例:

1. GpioPin.h

这个文件定义了GpioPinPwmPin的接口。

cpp 复制代码
// GpioPin.h
#ifndef GPIO_PIN_H
#define GPIO_PIN_H

#include <memory>

class GpioPin {
public:
    virtual ~GpioPin() {}
    virtual void set_direction(bool output) = 0;
    virtual void write(bool value) = 0;
};

class PwmPin : public GpioPin {
public:
    virtual ~PwmPin() {}
    virtual void set_frequency(int freq) = 0;
    virtual void set_duty_cycle(double percentage) = 0; // 百分比,0.0到1.0
};

// 工厂函数声明(通常放在其他文件中实现,或者作为类的静态方法)
std::unique_ptr<GpioPin> create_gpio_pin(int gpio_chip, int offset);
std::unique_ptr<PwmPin> create_pwm_pin(int pwm_chip, int pwm_device);

#endif // GPIO_PIN_H

2. RgbLed.h

这个文件定义了RgbLed类。

cpp 复制代码
// RgbLed.h
#ifndef RGB_LED_H
#define RGB_LED_H

#include "GpioPin.h"
#include <thread>
#include <chrono>

class RgbLed {
public:
    RgbLed(std::unique_ptr<GpioPin> red, std::unique_ptr<GpioPin> green, std::unique_ptr<GpioPin> blue)
        : red_(std::move(red)), green_(std::move(green)), blue_(std::move(blue)) {}

    void off();
    void on(int r, int g, int b); // 假设r, g, b是0到255的整数
    void blink(int r, int g, int b, int interval_ms);
    // 注意:呼吸效果在这里不实现,以保持示例简洁

private:
    std::unique_ptr<GpioPin> red_;
    std::unique_ptr<GpioPin> green_;
    std::unique_ptr<GpioPin> blue_;
};

#endif // RGB_LED_H

3. RgbLed.cpp

这个文件包含RgbLed类的实现。

cpp 复制代码
// RgbLed.cpp
#include "RgbLed.h"

void RgbLed::off() {
    red_->write(false);
    green_->write(false);
    blue_->write(false);
}

void RgbLed::on(int r, int g, int b) {
    // 简单的开关控制,不考虑PWM
    red_->write(r > 0);
    green_->write(g > 0);
    blue_->write(b > 0);
}

void RgbLed::blink(int r, int g, int b, int interval_ms) {
    while (true) {
        on(r, g, b);
        std::this_thread::sleep_for(std::chrono::milliseconds(interval_ms));
        off();
        std::this_thread::sleep_for(std::chrono::milliseconds(interval_ms));
    }
}

4. GpioPinFactory.cpp(或其他实现文件)

这个文件将包含create_gpio_pincreate_pwm_pin的实现,但注意这里只是声明,因为具体实现将依赖于你的硬件和使用的库。

cpp 复制代码
// GpioPinFactory.cpp(示例,实际实现将更复杂)
#include "GpioPin.h"

std::unique_ptr<GpioPin> create_gpio_pin(int gpio_chip, int offset) {
    // 伪代码:你需要根据你的硬件和库来实现这个
    // 返回一个GpioPin对象,可能是通过某种方式初始化的
    return nullptr; // 这里只是示例,实际应该返回一个有效的GpioPin对象
}

std::unique_ptr<PwmPin> create_pwm_pin(int pwm_chip, int pwm_device) {
    // 伪代码:同上
    return nullptr; // 实际应该返回一个有效的PwmPin对象
}
相关推荐
人生苦短,菜的抠脚9 分钟前
Linux 内核IIO sensor驱动
linux·驱动开发
jz_ddk22 分钟前
[LVGL] 从0开始,学LVGL:进阶应用与项目实战(上)
linux·信息可视化·嵌入式·gui·lvgl·界面设计
望获linux1 小时前
【实时Linux实战系列】Linux 内核的实时组调度(Real-Time Group Scheduling)
java·linux·服务器·前端·数据库·人工智能·深度学习
MC丶科1 小时前
【SpringBoot常见报错与解决方案】端口被占用?Spring Boot 修改端口号的 3 种方法,第 3 种 90% 的人不知道!
java·linux·spring boot
江公望1 小时前
ubuntu kylin(优麒麟)和标准ubuntu的区别浅谈
linux·服务器·ubuntu·kylin
Lynnxiaowen1 小时前
今天我们开始学习python语句和模块
linux·运维·开发语言·python·学习
生态笔记2 小时前
PPT宏代码
linux·服务器·powerpoint
mucheni2 小时前
迅为RK3588开发板Ubuntu 系统开发ubuntu终端密码登录
linux·运维·ubuntu
skywoodsky2 小时前
Ubuntu 24.04环境下的挂起转休眠
linux
小云数据库服务专线2 小时前
GaussDB 应用侧报Read timed out解决方法
linux·服务器·gaussdb