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; } }
以上就是ESP-IDF点灯了
作者:LetitiaRon Z
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须在文章页面给出原文连接,否则保留追究法律责任的权利。

浙公网安备 33010602011771号