ESP-IDF 点灯(简单点灯+PWM点灯)

  • 一、简单点灯

  (1)初始化IO模式,初始化前先复位一下IO,再设置IO模式为输出模式(输出模式有普通的输出和开漏输出,这里点灯就用普通的输出模式)

gpio_reset_pin(LED_NUM);
gpio_set_direction(LED_NUM, GPIO_MODE_OUTPUT);

  (2)开始点灯

ESP_LOGI(TAG, "Turning the LED %s!", s_led_state == true ? "ON" : "OFF");
gpio_set_level(LED_NUM, s_led_state);
s_led_state = !s_led_state;
vTaskDelay(500 / portTICK_PERIOD_MS);
  • 二、PWM点灯(LED PWM 控制器)

  (1)PWM 控制器的主要特性:

    LED PWM 控制器具有如下特性:

      • 八个独立的 PWM 生成器(即八个通道)
      • 四个独立定时器,可实现小数分频
      • 占空比自动渐变(即 PWM 信号占空比可逐渐增加或减小,无须处理器干预),渐变完成时产生中断
      • 输出 PWM 信号相位可调
      • 低功耗模式 (Light-sleep mode) 下可输出 PWM 信号
      • PWM 最大精度为 14 位
    四个定时器具有相同的功能和运行方式,下文将四个定时器统称为定时器x(x 的范围是 0 到 3)。八个 PWM 生
    成器的功能和运行方式也相同,下文将统称为 PWM n(n 的范围是 0 到 7)

        

 LED PWM 控制器架构

    

  (2)代码编写

    ①定时器配置

/**
 * @brief 定时器配置
 * 
 */
static const ledc_timer_config_t lcd_bl_ledc_timer = {
    .duty_resolution = LEDC_TIMER_10_BIT, // LEDC驱动器占空比精度
    .freq_hz = 2000,                      // PWM频率
    .speed_mode = LEDC_LOW_SPEED_MODE,   // 定时器模式(“高速”||“低速”)
    .timer_num = LEDC_TIMER_0, // ledc使用的定时器编号。若需要生成多个频率不同的PWM信号,则需要指定不同的定时器 (定时器源 0-3)
    .clk_cfg = LEDC_AUTO_CLK,  //自动选择定时器的时钟源
};

    ②LEDC通道配置

 

/**
 * @brief ledc通道配置
 * 频率越高,分别率也就越低。这个看个人需要去配置,乐鑫最高支持 40 MHz的pwm,
 * 但是只能实现百分之50占空比的方波,也就是duty_resolution = 2^1-1
* PS:如果不同通道使用同一个定时器,那么这些通道的频率和占空比分辨率相同
*/ static const ledc_channel_config_t lcd_bl_ledc_channel[3] = { { .channel = LEDC_CHANNEL_0, // LED使用通道0 .duty = 0, //占空比0 .gpio_num = 5, //连接LED的IO .speed_mode = LEDC_LOW_SPEED_MODE, .hpoint = 0, .timer_sel = LEDC_TIMER_0, //使用上面初始化过的定时器 }, { .channel = LEDC_CHANNEL_0, // LED使用通道0 .duty = 0, //占空比0 .gpio_num = 6, //连接LED的IO .speed_mode = LEDC_LOW_SPEED_MODE, .hpoint = 0, .timer_sel = LEDC_TIMER_0, //使用上面初始化过的定时器 }, { .channel = LEDC_CHANNEL_0, // LED使用通道0 .duty = 0, //占空比0 .gpio_num = 7, //连接LED的IO .speed_mode = LEDC_LOW_SPEED_MODE, .hpoint = 0, .timer_sel = LEDC_TIMER_0, //使用上面初始化过的定时器 }, };

 

     ③初始化LEDPWM

/**
 * @brief 初始化LEDPWM
 *
 * @return esp_err_t 错误代码
 */
static esp_err_t lcd_bl_init()
{
    /* 初始化定时器1,将初始化好的定时器编号传给ledc通道初始化函数即可 */
    esp_err_t error = ledc_timer_config(&lcd_bl_ledc_timer);
    if (error)
    {
        return error;
    }
    /* 初始化LED通道 */
    ledc_channel_config(&lcd_bl_ledc_channel[0]);
    ledc_channel_config(&lcd_bl_ledc_channel[1]);
    ledc_channel_config(&lcd_bl_ledc_channel[2]);

return true; }

 

    ④设置LED亮度

/**
 * @brief 设置LED亮度
 *
 * @param brightness LED百分比,0-100
 * @param channel ledc指定通道
 * @return esp_err_t 错误代码
 */
esp_err_t lcd_bl_set(uint8_t brightness, uint8_t channel)
{
    /* 设定PWM占空比 */
    esp_err_t error = ledc_set_duty(lcd_bl_ledc_channel[channel].speed_mode, lcd_bl_ledc_channel[channel].channel, brightness * 10);
    if (error)
    {
        return error;
    }
    /* 更新PWM占空比输出 */
    return ledc_update_duty(lcd_bl_ledc_channel[channel].speed_mode, lcd_bl_ledc_channel[channel].channel);
}

 

    ⑤编写app_main

void app_main(void)
{

    /* Configure the peripheral according to the LED type */
    ESP_LOGI(TAG, "Example configured to blink GPIO LED!");
    lcd_bl_init();//初始化LEDPWM
    while (1)
    {
        ESP_LOGI(TAG, "Turning the LED %s!", s_led_state == true ? "ON" : "OFF");
        for (int i = 0; i < 80; i++)
        {
            lcd_bl_set(i,0);
            lcd_bl_set(i,1);
            lcd_bl_set(i,2);
            vTaskDelay(20 / portTICK_PERIOD_MS);
        }
        for (int i = 80; i > 0; i--)
        {
            lcd_bl_set(i,0);
            lcd_bl_set(i,1);
            lcd_bl_set(i,2);
            vTaskDelay(20 / portTICK_PERIOD_MS);
        }
    }
}

 

  •  三、本次工程代码

#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/gpio.h"
#include "esp_log.h"
#include "led_strip.h"
#include "sdkconfig.h"
#include <esp_err.h>
#include <driver/gpio.h>
#include <driver/ledc.h>

static const char *TAG = "Main";

#define LED_GPIO \
    {            \
        5, 6, 7  \
    }

static uint8_t s_led_state = 0;

/**
 * @brief 定时器配置
 * 
 */
static const ledc_timer_config_t lcd_bl_ledc_timer = {
    .duty_resolution = LEDC_TIMER_10_BIT, // LEDC驱动器占空比精度
    .freq_hz = 2000,                      // PWM频率
    .speed_mode = LEDC_LOW_SPEED_MODE,
    .timer_num = LEDC_TIMER_0, // ledc使用的定时器编号。若需要生成多个频率不同的PWM信号,则需要指定不同的定时器
    .clk_cfg = LEDC_AUTO_CLK,  //自动选择定时器的时钟源
};

/**
 * @brief ledc通道配置
 * 频率越高,分别率也就越低。这个看个人需要去配置,乐鑫最高支持 40 MHz的pwm,
 * 但是只能实现百分之50占空比的方波,也就是duty_resolution = 2^1-1
 */
static const ledc_channel_config_t lcd_bl_ledc_channel[3] = {
    {
        .channel = LEDC_CHANNEL_0, // LED使用通道0
        .duty = 0,                 //占空比0
        .gpio_num = 5,             //连接LED的IO
        .speed_mode = LEDC_LOW_SPEED_MODE,
        .hpoint = 0,
        .timer_sel = LEDC_TIMER_0, //使用上面初始化过的定时器
    },
    {
        .channel = LEDC_CHANNEL_0, // LED使用通道0
        .duty = 0,                 //占空比0
        .gpio_num = 6,             //连接LED的IO
        .speed_mode = LEDC_LOW_SPEED_MODE,
        .hpoint = 0,
        .timer_sel = LEDC_TIMER_0, //使用上面初始化过的定时器
    },
    {
        .channel = LEDC_CHANNEL_0, // LED使用通道0
        .duty = 0,                 //占空比0
        .gpio_num = 7,             //连接LED的IO
        .speed_mode = LEDC_LOW_SPEED_MODE,
        .hpoint = 0,
        .timer_sel = LEDC_TIMER_0, //使用上面初始化过的定时器
    },
};


/**
 * @brief 初始化LEDPWM
 *
 * @return esp_err_t 错误代码
 */
static esp_err_t lcd_bl_init()
{
    /* 初始化定时器1,将初始化好的定时器编号传给ledc通道初始化函数即可 */
    esp_err_t error = ledc_timer_config(&lcd_bl_ledc_timer);
    if (error)
    {
        return error;
    }

    ledc_channel_config(&lcd_bl_ledc_channel[0]);
    ledc_channel_config(&lcd_bl_ledc_channel[1]);
    ledc_channel_config(&lcd_bl_ledc_channel[2]);

    /* 初始化ledc通道 */
    return true;
}

/**
 * @brief 设置LED亮度
 *
 * @param brightness LED百分比,0-100
 * @param channel ledc指定通道
 * @return esp_err_t 错误代码
 */
esp_err_t lcd_bl_set(uint8_t brightness, uint8_t channel)
{
    /* 设定PWM占空比 */
    esp_err_t error = ledc_set_duty(lcd_bl_ledc_channel[channel].speed_mode, lcd_bl_ledc_channel[channel].channel, brightness * 10);
    if (error)
    {
        return error;
    }
    /* 更新PWM占空比输出 */
    return ledc_update_duty(lcd_bl_ledc_channel[channel].speed_mode, lcd_bl_ledc_channel[channel].channel);
}



void app_main(void)
{

    /* Configure the peripheral according to the LED type */
    ESP_LOGI(TAG, "Example configured to blink GPIO LED!");

    lcd_bl_init();

    // gpio_reset_pin(5);
    // // gpio_reset_pin(6);
    // gpio_reset_pin(7);
    // /* Set the GPIO as a push/pull output */
    // gpio_set_direction(5, GPIO_MODE_OUTPUT);
    // gpio_set_direction(6, GPIO_MODE_OUTPUT);
    // gpio_set_direction(7, GPIO_MODE_OUTPUT);

    while (1)
    {
        ESP_LOGI(TAG, "Turning the LED %s!", s_led_state == true ? "ON" : "OFF");

        // gpio_set_level(5, s_led_state);
        // // gpio_set_level(6, s_led_state);
        // gpio_set_level(7, s_led_state);
        /* Toggle the LED state */
        for (int i = 0; i < 80; i++)
        {
            lcd_bl_set(i,0);
            lcd_bl_set(i,1);
            lcd_bl_set(i,2);
            vTaskDelay(20 / portTICK_PERIOD_MS);
        }
        for (int i = 80; i > 0; i--)
        {
            lcd_bl_set(i,0);
            lcd_bl_set(i,1);
            lcd_bl_set(i,2);
            vTaskDelay(20 / portTICK_PERIOD_MS);
        }

        s_led_state = !s_led_state;
    }
}
View Code

 

以上就是ESP-IDF点灯了

 

posted @ 2022-07-31 17:54  ArsSama  阅读(1410)  评论(0)    收藏  举报