ESP32 PWM呼吸灯实现详解

一、ESP32配置PWM实现呼吸灯

#define LED_PIN GPIO_NUM_27

void led_pwm_task(void *pvParameters)
{
    // 配置LEDC定时器
    ledc_timer_config_t ledc_timer = {
        .duty_resolution = LEDC_TIMER_13_BIT,  // 设置PWM占空比分辨率为13位
        .freq_hz = 5000,                       // PWM频率5KHz
        .speed_mode = LEDC_HIGH_SPEED_MODE,    // 高速模式
        .timer_num = LEDC_TIMER_0              // 使用定时器0
    };
    ledc_timer_config(&ledc_timer);

    // 配置LEDC通道
    ledc_channel_config_t ledc_channel = {
        .channel = LEDC_CHANNEL_0,           // 使用LEDC通道0
        .duty = 0,                           // 初始占空比为0(LED完全熄灭)
        .gpio_num = LED_PIN,                 // 使用GPIO27引脚
        .speed_mode = LEDC_HIGH_SPEED_MODE,  // 使用高速模式
        .timer_sel = LEDC_TIMER_0            // 使用定时器0
    };
    ledc_channel_config(&ledc_channel);

    while(1) {
        // 从0到最大亮度渐变
        for(int duty = 0; duty < 8192; duty += 100) {
            ledc_set_duty(LEDC_HIGH_SPEED_MODE, LEDC_CHANNEL_0, duty);
            ledc_update_duty(LEDC_HIGH_SPEED_MODE, LEDC_CHANNEL_0);
            vTaskDelay(pdMS_TO_TICKS(10));
        }
        
        // 从最大亮度到0渐变
        for(int duty = 8191; duty >= 0; duty -= 100) {
            ledc_set_duty(LEDC_HIGH_SPEED_MODE, LEDC_CHANNEL_0, duty);
            ledc_update_duty(LEDC_HIGH_SPEED_MODE, LEDC_CHANNEL_0);
            vTaskDelay(pdMS_TO_TICKS(10));
        }
    }
}

函数功能概述

led_pwm_task 函数是一个用于控制 LED 亮度渐变的 FreeRTOS 任务函数。它通过配置 ESP32 的 LEDC(LED 控制)模块,实现 LED 从暗到亮再从亮到暗的循环渐变效果。

函数内部代码详细解释

  1. LEDC 定时器配置

    • ledc_timer_config_t ledc_timer:定义一个 LEDC 定时器配置结构体变量。
      • .duty_resolution = LEDC_TIMER_13_BIT:设置 PWM 占空比分辨率为 13 位。这意味着占空比可以有 2^13 = 8192 个不同的步长,能够更精细地控制 LED 的亮度。占空比越大,LED 越亮。
      • .freq_hz = 5000:设置 PWM 频率为 5000Hz。这个频率决定了 PWM 信号每秒切换的次数,较高的频率可以使 LED 亮度变化更加平滑,一般人眼对这个频率的 PWM 信号闪烁不太敏感。
      • .speed_mode = LEDC_HIGH_SPEED_MODE:选择高速模式。LEDC 有两种速度模式,高速模式和低速模式,这里选择高速模式通常用于对时间精度要求较高的场景。
      • .timer_num = LEDC_TIMER_0:指定使用定时器 0。ESP32 的 LEDC 模块有多个定时器可供选择,这里选择定时器 0 来为后续的 LEDC 通道提供时钟源。然后调用 ledc_timer_config(&ledc_timer) 函数应用这个定时器配置。
  2. LEDC 通道配置

    • ledc_channel_config_t ledc_channel:定义一个 LEDC 通道配置结构体变量。
      • .channel = LEDC_CHANNEL_0:选择通道 0。LEDC 有多个通道,每个通道可以连接到不同的 GPIO 引脚来控制不同的 LED 或者其他设备。
      • .duty = 0:初始占空比设置为 0,即 LED 初始状态为关闭。
      • .gpio_num = LED_PIN:指定用于控制 LED 的 GPIO 引脚,这里假设 LED_PIN 已经定义为某个具体的 GPIO 引脚编号,比如 27。
      • .speed_mode = LEDC_HIGH_SPEED_MODE:同样选择高速模式,与定时器的速度模式保持一致。
      • .timer_sel = LEDC_TIMER_0:选择定时器 0 为这个通道的时钟源,与之前配置的定时器相匹配。接着调用 ledc_channel_config(&ledc_channel) 函数完成通道配置。
  3. LED 亮度渐变循环

    • while(1):进入无限循环,持续执行亮度渐变操作。

      • 从暗到亮渐变

        • for(int duty = 0; duty < 8192; duty += 100):从占空比 0 开始,每次增加 100,直到占空比达到 8191(因为 13 位分辨率最大值是 8191)。这里 8192 是 2^13,所以循环条件是 duty < 8192
        • ledc_set_duty(LEDC_HIGH_SPEED_MODE, LEDC_CHANNEL_0, duty):设置通道 0 的占空比为当前 duty 值,从而逐渐增加 LED 的亮度。
        • ledc_update_duty(LEDC_HIGH_SPEED_MODE, LEDC_CHANNEL_0):更新占空比,使新的占空比设置生效。
        • vTaskDelay(pdMS_TO_TICKS(10)):任务延迟 10 毫秒,控制渐变速度,让亮度变化能够被肉眼观察到。
      • 从亮到暗渐变

        • for(int duty = 8191; duty >= 0; duty -= 100):从占空比 8191 开始,每次减少 100,直到占空比达到 0。
        • ledc_set_duty(LEDC_HIGH_SPEED_MODE, LEDC_CHANNEL_0, duty):设置通道 0 的占空比为当前 duty 值,逐渐降低 LED 的亮度。
        • ledc_update_duty(LEDC_HIGH_SPEED_MODE, LEDC_CHANNEL_0):更新占空比。
        • vTaskDelay(pdMS_TO_TICKS(10)):同样任务延迟 10 毫秒,保持渐变速度一致。
    • 这个循环使得 LED 不断地进行亮度的渐变,产生呼吸灯般的效果。

二、其他可用的 LEDC 配置选项

1. 占空比分辨率(duty_resolution

  • 作用:决定 PWM 信号占空比的精度,值越大,亮度控制越精细,亮度的等级更丰富。
  • 可选值:范围从LEDC_TIMER_1_BIT(1位,占空比0-1)到LEDC_TIMER_16_BIT(16位,占空比0-65535)。常选LEDC_TIMER_13_BIT(13位,占空比0-8191),适合多数LED调光场景。

2. PWM频率(freq_hz

  • 作用:设置PWM信号频率,影响LED闪烁速度。
  • 可选值:任意正整数,如1000Hz、5000Hz、10000Hz等。低频(如1000Hz)易闪烁,高频(5000Hz以上)更平滑,但需考虑硬件限制。

3. 速度模式(speed_mode

  • 作用:选择LEDC工作模式,影响时钟源和性能。
  • 可选值LEDC_HIGH_SPEED_MODE(高速模式,适合高精度场景)、LEDC_LOW_SPEED_MODE(低速模式,适合对时间精度要求低的场景)。

4. 定时器选择(timer_num

  • 作用:选择生成PWM信号的定时器。
  • 可选值LEDC_TIMER_0LEDC_TIMER_1LEDC_TIMER_2LEDC_TIMER_3。不同定时器可独立配置频率和分辨率,支持多路PWM信号。

5. 通道选择(channel

  • 作用:选择控制特定GPIO引脚的LEDC通道。
  • 可选值LEDC_CHANNEL_0LEDC_CHANNEL_1LEDC_CHANNEL_2LEDC_CHANNEL_3。每个通道可连接不同GPIO引脚,实现多路独立PWM输出。

6. GPIO引脚(gpio_num

  • 作用:指定PWM信号输出的GPIO引脚。
  • 可选值:ESP32支持的任一GPIO引脚(如GPIO2、GPIO4、GPIO12等)。需确保引脚支持LEDC功能,参考ESP32数据手册。

7. 初始占空比(duty

  • 作用:设置通道初始占空比,决定LED初始亮度。
  • 可选值0(关闭)到最大值(由duty_resolution决定,如13位为8191)。如duty=4096,在13位分辨率下约为50%亮度。

8. 定时器绑定(timer_sel

  • 作用:将通道绑定到指定定时器。
  • 可选值LEDC_TIMER_0LEDC_TIMER_1LEDC_TIMER_2LEDC_TIMER_3。需与定时器配置中的timer_num一致,确保通道使用正确时钟源。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值