第十章 ESP32开发指南---PWM全彩LED灯显示

学习目的及目标

学习LED灯电路及硬件原理

学习ESP32 的PWM(ledc)功能的配置

掌握PWM(ledc)控制全彩LED灯渐变程序

全彩 LED 灯简介

全彩 LED 灯,实质上是一种把红、绿、蓝单色发光体集成到小面积区域中的 LED 灯,控制时对这三种颜色的灯管输出不同的光照强度,即可混合得到不同的颜色,其混色原理与光的三原色混合原理一致。

例如,若红绿蓝灯都能控制输出光照强度为[0:255]种等级,那么该灯可混合得到使用RGB888表示的所有颜色(包括以 RGB三个灯管都全灭所表示的纯黑色)。

全彩 LED 灯控制原理

本教程配套开发板中的 RGB灯就是一种全彩 LED 灯,前面介绍 LED 基本控制原理的时候,只能控制 RGB三色灯的亮灭,即 RGB每盏灯有[0:1]两种等级,因此只能组合出 8种颜色。

要使用ESP32控制 LED灯输出多种亮度等级,可以通过控制输出脉冲的占空比来实现。就是我们今天要学习的PWM功能,在ESP32中就是ledc功能。

上图列出了周期相同而占空比分别为 100%、80%、50和 20%的脉冲波形,假如利用这样的脉冲控制 LED 灯,即可控制 LED 灯亮灭时间长度的比例。若提高脉冲的频率,LED 灯将会高频率进行开关切换,由于视觉暂留效应,人眼看不到 LED 灯的开关导致的闪烁现象,而是感觉到使用不同占空比的脉冲控制 LED 灯时的亮度差别。即单个控制周期内,LED 灯亮的平均时间越长,亮度就越高,反之越暗。

把脉冲信号占空比分成 256 个等级,即可用于控制 LED 灯输出 256种亮度,使用三种这样的信号控制 RGB灯即可得到 256*256*256种颜色混合的效果。而要控制占空比,直接使用 ESP32的LEDC功能即可。

硬件设计及原理

同LED章原理图。

本实验板连接了一个 RGB彩灯,RGB彩灯实际上由三盏分别为红色、绿色、蓝色的 LED 灯组成,通过控制 RGB颜色强度的组合,可以混合出各种色彩。

LED标号

LED颜色

接至ESP32的引脚

LP2A

红色

IO2

LP2B

绿色

IO18

LP2C

蓝色

IO19

若您使用的实验板 LED 灯的连接方式或引脚不一样,只需根据我们的工程修改引脚即可,程序的控制原理相同。

软件设计

代码逻辑

ESP32的PWM(ledc)接口介绍

LEDC配置函数:ledc_channel_config();

函数原型

esp_err_t ledc_channel_config

(

const ledc_channel_config_t* ledc_conf

)

函数功能

LEDC配置函数

参数

[in] ledc_conf:ledc配置结构体ledc_channel_config_t

typedef struct {

int gpio_num;//IO编号

ledc_mode_t speed_mode;//速度

ledc_channel_t channel;//通道

ledc_intr_type_t intr_type;//中断使能

ledc_timer_t timer_sel; //定时器通道

uint32_t duty; //占空比

} ledc_channel_config_t;

返回值

ESP_OK:成功

ESP_ERR_INVALID_ARG : 参数错误

LEDC渐变安装函数:ledc_fade_func_install();

函数原型

esp_err_t ledc_fade_func_install

(

int intr_alloc_flags

)

函数功能

LEDC渐变安装使能函数

参数

[in] intr_alloc_flags:分配中断标记

返回值

ESP_OK:成功

ESP_ERR_INVALID_ARG : 参数错误

LEDC渐变函数:ledc_set_fade_with_time();

函数原型

esp_err_t ledc_set_fade_with_time

(

ledc_mode_t speed_mode,

ledc_channel_t channel,

uint32_t target_duty,

int max_fade_time_ms

)

函数功能

LEDC渐变函数

参数

[in] speed_mode:速度

[in] channel:通道

[in] target_duty:目标占空比

[in] max_fade_time_ms:到达目标占空比需要的时间

返回值

ESP_OK:成功

ESP_ERR_INVALID_ARG : 参数错误

ESP_ERR_INVALID_STATE:LEDC渐变未安装

ESP_FAIL:LEDC渐变安装失败

LEDC渐变开始函数:ledc_fade_start();

函数原型

esp_err_t ledc_fade_start

(

ledc_mode_t speed_mode,

ledc_channel_t channel,

ledc_fade_mode_t wait_done

)

函数功能

LEDC渐变开始函数

参数

[in] speed_mode:速度

[in] channel:通道

[in] wait_done:是否等待

返回值

ESP_OK:成功

ESP_ERR_INVALID_ARG : 参数错误

ESP_ERR_INVALID_STATE:LEDC渐变未安装

更多更详细接口请参考官方指南

渐变RGB彩灯源码编写

获取按键状态,等于0表示按键按下,然后死等松手,切换灯状态。

包含头文件、IO宏定义、ledc宏定义

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

#include <stdio.h>

#include "esp_system.h"

#include "esp_spi_flash.h"

#include "esp_wifi.h"

#include "esp_event_loop.h"

#include "esp_log.h"

#include "esp_err.h"

#include "nvs_flash.h"

#include "freertos/FreeRTOS.h"

#include "freertos/task.h"

#include "driver/ledc.h"

#include <stdio.h>

#include "freertos/FreeRTOS.h"

#include "freertos/task.h"

#include "driver/ledc.h"

#define LED_R_IO 2

#define LED_G_IO 18

#define LED_B_IO 19

#define LEDC_MAX_DUTY                (8191) //2的13次方-1(13位PWM)

#define LEDC_FADE_TIME     (1000) //渐变时间(ms)

RGB灯PWM(ledc)配置,并使能渐变函数

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

/*

* void ledc_init(void):定时器0用在PWM模式,输出3通道的LEDC信号

*/

void ledc_init(void)

{

//定时器配置结构体

ledc_timer_config_t ledc_timer;

//定时器配置->timer0

ledc_timer.duty_resolution = LEDC_TIMER_13_BIT; //PWM分辨率

ledc_timer.freq_hz = 5000;                        //频率

ledc_timer.speed_mode = LEDC_HIGH_SPEED_MODE;   //速度

ledc_timer.timer_num = LEDC_TIMER_0;            // 选择定时器

ledc_timer_config(&ledc_timer); //设置定时器PWM模式

//PWM通道0配置->IO2->红色灯

g_ledc_ch_R.channel    = LEDC_CHANNEL_0; //PWM通道

g_ledc_ch_R.duty       = 0; //占空比

g_ledc_ch_R.gpio_num   = LED_R_IO; //IO映射

g_ledc_ch_R.speed_mode = LEDC_HIGH_SPEED_MODE; //速度

g_ledc_ch_R.timer_sel  = LEDC_TIMER_0; //选择定时器

ledc_channel_config(&g_ledc_ch_R); //配置PWM

//PWM通道1配置->IO18->绿色灯

g_ledc_ch_G.channel    = LEDC_CHANNEL_1; //PWM通道

g_ledc_ch_G.duty       = 0; //占空比

g_ledc_ch_G.gpio_num   = LED_G_IO; //IO映射

g_ledc_ch_G.speed_mode = LEDC_HIGH_SPEED_MODE; //速度

g_ledc_ch_G.timer_sel  = LEDC_TIMER_0; //选择定时器

ledc_channel_config(&g_ledc_ch_G); //配置PWM

//PWM通道2配置->IO19->蓝色灯

g_ledc_ch_B.channel    = LEDC_CHANNEL_2; //PWM通道

g_ledc_ch_B.duty       = 0; //占空比

g_ledc_ch_B.gpio_num   =LED_B_IO ; //IO映射

g_ledc_ch_B.speed_mode = LEDC_HIGH_SPEED_MODE; //速度

g_ledc_ch_B.timer_sel  = LEDC_TIMER_0; //选择定时器

ledc_channel_config(&g_ledc_ch_B); //配置PWM

//使能ledc渐变功能

ledc_fade_func_install(0);

}

主函数:渐变RGB灯

RGB灯由0%到100%渐变(暗到亮),历时1秒

RGB灯由100%到0%渐变(亮到暗),历时1秒

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

/*

 * 应用程序的函数入口

*/

void app_main()

{    

ledc_init();//ledc初始化

    while(1)

{

//ledc 红灯渐变至100%,时间LEDC_FADE_TIME

ledc_set_fade_with_time(g_ledc_ch_R.speed_mode,

                                     g_ledc_ch_R.channel,

         LEDC_MAX_DUTY,

                                     LEDC_FADE_TIME);

//渐变开始

ledc_fade_start(g_ledc_ch_R.speed_mode,

      g_ledc_ch_R.channel,

      LEDC_FADE_NO_WAIT);

//略过

           vTaskDelay(LEDC_FADE_TIME / portTICK_PERIOD_MS);

//ledc 红灯 渐变至0%,时间LEDC_FADE_TIME

ledc_set_fade_with_time(g_ledc_ch_R.speed_mode,

                                      g_ledc_ch_R.channel,

          0,

                                      LEDC_FADE_TIME);

//渐变开始

ledc_fade_start(g_ledc_ch_R.speed_mode,

      g_ledc_ch_R.channel,

      LEDC_FADE_NO_WAIT);

//略过

           vTaskDelay(LEDC_FADE_TIME / portTICK_PERIOD_MS);

}

}

硬件连接

开发板默认已经连接好RGB灯,下载程序即可,使用其他开发板需要修改程序或者修改硬件连接皆可。

效果展示

RGB灯由暗到亮,再由亮变暗,如此循环。

PWM(ledc)总结

渐变在指示灯处比较常用。

不用渐变的时候可以使用,设置占空比函数直接怼。

设置占空比ledc_set_duty();

还有几个常用的ledc库函数,请参考ledc.h文件,太简单不做介绍。

源码地址:https://github.com/xiaolongba/wireless-tech

点我->更多ESP32开发指南系列目录

发布了45 篇原创文章 · 获赞 48 · 访问量 11万+

猜你喜欢

转载自blog.csdn.net/qq_24550925/article/details/85335629