本帖最后由 正点原子运营 于 2025-4-22 14:51 编辑
1)实验平台:正点原子DNESP32S3开发板
2)章节摘自【正点原子】ESP32-S3使用指南—IDF版 V1.6
6)正点原子DNESP32S3开发板技术交流群:132780729
本章将介绍使用ESP32-S3 LED控制器(LEDC)。上一章节我们介绍了通过软件改变PWM占空比。那么这一章节我们将和开发者们一起来学习硬件改变PWM占空比的运用。 本章分为如下几个小节: 18.1 PWM简介 18.2 硬件设计 18.3 程序设计 18.4 下载验证
18.1 PWM简介 关于PWM的一些知识,我们在第十七章已经介绍过了,在此便不做赘述。使用硬件的方式改变PWM占空比与使用软件的方式改变PWM占空比的不同之处在于,LED PWM 控制器硬件可逐渐改变占空比的数值,要使用此功能,需用函数 ledc_fade_func_install() 使能渐变,之后用下列可用渐变函数之一配置:
18.2 硬件设计 18.2.1 例程功能 1. 通过硬件改变PWM的形式使得LED由亮到暗,再由暗到亮,依次循环。
18.2.2 硬件资源 1. LED LED -IO1 2. 定时器1 通道1 - IO1
18.2.3 原理图 本章实验使用的定时器1为ESP32-S3的片上资源,因此没有对应的连接原理图。
18.3 程序设计 18.3.1 程序流程图 程序流程图能帮助我们更好的理解一个工程的功能和实现的过程,对学习和设计工程有很好的主导作用。下面看看本实验的程序流程图: 18.3.2 HW_PWM函数解析 ESP-IDF提供了一套API来配置PWM。要使用此功能,需要导入必要的头文件: 接下来,作者将介绍一些常用的HW_PWM函数,这些函数的描述及其作用如下: 1,使能渐变 - esp_err_t ledc_fade_func_install(int intr_alloc_flags);
复制代码该函数的形参描述,如下表所示: 表18.3.2.1 函数ledc_fade_func_install()形参描述 返回值:ESP_OK表示配置成功,其他表示配置失败。 2,设置LEDC渐变功能 经过上一步渐变功能的配置后,需要设置占空比以及渐变时长,该函数原型如下所示: - esp_err_t ledc_set_fade_with_time(ledc_mode_tspeed_mode,
- ledc_channel_t channel,
- uint32_t target_duty, int max_fade_time_ms);
复制代码该函数的形参描述,如下表所示: 表18.3.2.2 函数ledc_set_fade_with_time()形参描述 返回值:ESP_OK表示配置成功,其他表示配置失败。 3,开启渐变 设置占空比以及渐变时长后,便可开启渐变功能,该函数原型如下所示: - esp_err_t ledc_fade_start(ledc_mode_tspeed_mode,
- ledc_channel_t channel,
- ledc_fade_mode_tfade_mode);
复制代码该函数的形参描述,如下表所示: 表18.3.2.3 函数ledc_fade_start()形参描述 返回值:ESP_OK表示配置成功,其他表示配置失败。
18.3.3 HW_PWM驱动解析 在IDF版的08-2_hw_pwm例程中,作者在08-2_hw_pwm \components\BSP路径下新增了一个PWM文件夹,用于存放pwm.c和pwm.h这两个文件。其中,pwm.h文件负责声明HW_PWM相关的函数和变量,而pwm.c文件则实现了HW_PWM的驱动代码。下面,我们将详细解析这两个文件的实现内容。 1,pwm.h文件 - /* 引脚以及重要参数定义 */
- #define LEDC_PWM_TIMER LEDC_TIMER_0 /* 使用定时器0 */
- #define LEDC_PWM_MODE LEDC_LOW_SPEED_MODE/* 模式设定必须使用LEDC低速模式 */
- #define LEDC_PWM_CH0_GPIO GPIO_NUM_1 /* LED控制器通道对应GPIO */
- #define LEDC_PWM_CH0_CHANNEL LEDC_CHANNEL_0 /* LED控制器通道号 */
- #define LEDC_PWM_DUTY 8000 /* 渐变的变大最终目标占空比 */
- #define LEDC_PWM_FADE_TIME 3000 /* 变化时长 */
- /* 函数声明 */
- void pwm_init(uint8_t resolution, uint16_t freq);/* 初始化PWM */
- void pwm_set_duty(uint16_t duty); /* PWM占空比设置 */
复制代码2,pwm.c文件 - /**
- *@brief 初始化PWM
- *@param resolution:PWM占空比分辨率
- * freq: PWM信号频率
- *@retval 无
- */
- void pwm_init(uint8_t resolution, uint16_t freq)
- {
- ledc_timer_config_t ledc_timer; /* LEDC定时器句柄 */
- ledc_channel_config_t ledc_channel; /* LEDC通道配置句柄 */
- /* 配置LEDC定时器 */
- ledc_timer.duty_resolution = resolution; /* PWM占空比分辨率 */
- ledc_timer.freq_hz = freq; /* PWM信号频率 */
- ledc_timer.speed_mode = LEDC_PWM_MODE; /* 定时器模式 */
- ledc_timer.timer_num =LEDC_PWM_TIMER; /* 定时器序号 */
- ledc_timer.clk_cfg =LEDC_AUTO_CLK; /* LEDC时钟源 */
- ledc_timer_config(&ledc_timer); /* 配置定时器 */
- /* 配置LEDC通道 */
- ledc_channel.gpio_num =LEDC_PWM_CH0_GPIO; /* LED控制器通道对应引脚 */
- ledc_channel.speed_mode = LEDC_PWM_MODE; /* LEDC高速模式 */
- ledc_channel.channel =LEDC_PWM_CH0_CHANNEL; /* LEDC控制器通道号 */
- ledc_channel.intr_type =LEDC_INTR_DISABLE; /* LEDC失能中断 */
- ledc_channel.timer_sel =LEDC_PWM_TIMER; /* 定时器序号 */
- ledc_channel.duty = 0; /* 占空比值 */
- ledc_channel_config(&ledc_channel); /* 配置LEDC通道 */
- ledc_fade_func_install(0); /* 使能渐变(该函数不可或缺) */
- }
- /**
- *@brief PWM占空比设置
- *@param duty:PWM占空比
- *@retval 无
- */
- void pwm_set_duty(uint16_t duty)
- {
- ledc_set_fade_with_time(LEDC_PWM_MODE,
- LEDC_PWM_CH0_CHANNEL,
- duty,
- LEDC_PWM_FADE_TIME); /* 设置占空比以及渐变时长 */
- ledc_fade_start(LEDC_PWM_MODE,
- LEDC_PWM_CH0_CHANNEL,
- LEDC_FADE_NO_WAIT); /* 开始渐变 */
- ledc_set_fade_with_time(LEDC_PWM_MODE,
- LEDC_PWM_CH0_CHANNEL,
- 0,
- LEDC_PWM_FADE_TIME); /* 设置占空比以及渐变时长 */
- ledc_fade_start(LEDC_PWM_MODE,
- LEDC_PWM_CH0_CHANNEL,
- LEDC_FADE_NO_WAIT); /* 开始渐变 */
- }
复制代码在PWM初始化函数中,我们配置好LEDC定时器的频率、占空比、定时器模式以及定时器通道,并在pwm_set_duty()函数中,调用函数ledc_set_fade_with_time ()用以设置占空比和渐变时长。此时,我们需要再次调用该函数,将占空比配置为0,最后调用函数ledc_fade_start ()开启渐变。为了方便使用,笔者将这两个函数进行了“封装”,通过传参的形式来配置PWM占空比。关于PWM初始化函数中涉及到的结构体含义,请读者们回顾第十七章节的内容。
18.3.4 CMakeLists.txt文件 打开本实验BSP下的CMakeLists.txt文件,其内容如下所示: - set(src_dirs
- PWM)
- set(include_dirs
- PWM)
- set(requires
- driver)
- idf_component_register(SRC_DIRS ${src_dirs}
- INCLUDE_DIRS ${include_dirs} REQUIRES ${requires})
- component_compile_options(-ffast-math -O3 -Wno-error=format=-Wno-format)
复制代码上述的红色HW_PWM驱动需要由开发者自行添加,以确保HW_PWM驱动能够顺利集成到构建系统中。这一步骤是必不可少的,它确保了HW_PWM驱动的正确性和可用性,为后续的开发工作提供了坚实的基础。
18.3.5 实验应用代码 打开main/main.c文件,该文件定义了工程入口函数,名为app_main。该函数代码如下。 - int main(void)
- {
- esp_err_t ret;
-
- ret=nvs_flash_init(); /* 初始化NVS */
- if (ret == ESP_ERR_NVS_NO_FREE_PAGES ||
- ret == ESP_ERR_NVS_NEW_VERSION_FOUND)
- {
- ESP_ERROR_CHECK(nvs_flash_erase());
- ret =nvs_flash_init();
- }
-
- pwm_init(13, 5000); /* 初始化PWM */
- while (1)
- {
- vTaskDelay(10);
- pwm_set_duty(LEDC_PWM_DUTY); /* 设置占空比 */
- }
- }
复制代码在主函数中,我们首先对PWM进行初始化,设置了PWM占空比分辨率为13,PWM信号频率为5000,最后在while(1)循环中配置了占空比。通过与上一个实验的对比,硬件改变占空比的方式与软件改变占空比的方式虽有不同,但一样可以实现呼吸灯的效果。开发者们可以这两个章节进行对比学习。 18.4 下载验证 在完成编译和烧录后,可以看到板子上的LED先由暗再逐渐变亮,以此循环,实现了呼吸灯的效果。
|