ESP32S3 LEDC模块实现PWM占空比自动渐变已实现呼吸灯效果

一、版本说明


- Python版本: Python 3.12.3
- ninja版本 : ninja version 1.11.1
- CMake版本 : cmake version 3.28.3
- 芯片型号  : ESP32-S3
- IDF版本   : ESP-IDF v5.4.1-dirty




二、例程步骤


/* 配置定时器 */
1. esp_err_t ledc_timer_config(const ledc_timer_config_t *timer_conf)

/* 配置通道 */
2. esp_err_t ledc_channel_config(const ledc_channel_config_t *ledc_conf)

/* 设置占空比 */
3. esp_err_t ledc_set_duty(ledc_mode_t speed_mode, ledc_channel_t channel, uint32_t duty)

/* 安装渐变函数 */
4. esp_err_t ledc_fade_func_install(int intr_alloc_flags)

/* 注册回调函数 */
5. esp_err_t ledc_cb_register(ledc_mode_t speed_mode, ledc_channel_t channel, ledc_cbs_t *cbs, void *user_arg)

/* 设置渐变时间 */
6. 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)

/* 开始渐变 */
7. esp_err_t ledc_fade_start(ledc_mode_t speed_mode, ledc_channel_t channel, ledc_fade_mode_t fade_mode)




三、例程源码


#include "pwm_fade.h"

#include "driver/ledc.h"
#include "esp_attr.h"
#include <stdbool.h>

#define LEDC_SPEED_MODE     (LEDC_LOW_SPEED_MODE)
#define LEDC_TIMER_NUM      (LEDC_TIMER_0)
#define LEDC_RESOLUTION     (LEDC_TIMER_10_BIT)
#define LEDC_FREQ_HZ        (10000)
#define LEDC_CHANNEL        (LEDC_CHANNEL_2)
#define LEDC_GPIO_NUM       (GPIO_NUM_10)
#define LEDC_FADE_TIME_MS   (500)
#define LEDC_DUTY_MIN       (0)
#define LEDC_DUTY_MAX       ((0x01 << LEDC_RESOLUTION) - 1)



static int8_t fade_dir = 0;

static IRAM_ATTR bool ledc_fade_done_cb(const ledc_cb_param_t *param, void *user_arg)
{
    uint32_t target = 0;

    if (param->event == LEDC_FADE_END_EVT)
    {
        if (fade_dir) { target = LEDC_DUTY_MIN; fade_dir = 0; }
        else          { target = LEDC_DUTY_MAX; fade_dir = 1; }

        ledc_set_fade_with_time(LEDC_SPEED_MODE, LEDC_CHANNEL, target, LEDC_FADE_TIME_MS);
        ledc_fade_start(LEDC_SPEED_MODE, LEDC_CHANNEL, LEDC_FADE_NO_WAIT);
    }

    return ESP_OK;
}

void pwm_fade_init(void)
{
    ledc_timer_config_t ledc_timer = 
    {
        .speed_mode       = LEDC_SPEED_MODE, //timer mode
        .timer_num        = LEDC_TIMER_NUM,  //timer index
        .duty_resolution  = LEDC_RESOLUTION, //resolution of PWM duty
        .freq_hz          = LEDC_FREQ_HZ,    //PWM frequency
        .clk_cfg          = LEDC_AUTO_CLK,   //automatic clock source selection
    };
    ledc_timer_config(&ledc_timer);

    ledc_channel_config_t ledc_channel = 
    {
        .channel    = LEDC_CHANNEL,      //channel number
        .timer_sel  = LEDC_TIMER_NUM,    //timer index
        .intr_type  = LEDC_INTR_DISABLE, //interrupt type
        .speed_mode = LEDC_SPEED_MODE,   //timer mode
        .gpio_num   = LEDC_GPIO_NUM,     //output IO
        .duty       = 0,                 //set duty
        .hpoint     = 0,                 //set hpoint
    };
    ledc_channel_config(&ledc_channel);


    ledc_cbs_t ledc_cbs = 
    {
        .fade_cb = ledc_fade_done_cb,
    };

    ledc_fade_func_install(0); // install fade service
    ledc_cb_register(LEDC_SPEED_MODE, LEDC_CHANNEL, &ledc_cbs, NULL);

    ESP_ERROR_CHECK(ledc_set_duty(LEDC_SPEED_MODE, LEDC_CHANNEL, LEDC_DUTY_MIN));
    ESP_ERROR_CHECK(ledc_set_fade_with_time(LEDC_SPEED_MODE, LEDC_CHANNEL, LEDC_DUTY_MAX, LEDC_FADE_TIME_MS));
    ESP_ERROR_CHECK(ledc_fade_start(LEDC_SPEED_MODE, LEDC_CHANNEL, LEDC_FADE_NO_WAIT));
}

uint32_t get_ledc_duty_value(void)
{
    return ledc_get_duty(LEDC_SPEED_MODE, LEDC_CHANNEL);
}

在这里插入图片描述




四、主函数


#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "nvs_flash.h"
#include "esp_system.h"
#include "esp_chip_info.h"
#include "esp_psram.h"
#include "esp_flash.h"
#include "driver/gpio.h"



#include "sys_clock.h"
#include "pwm_fade.h"
#include "Ledc.h"


void app_main(void)
{
    esp_err_t ret;
    uint32_t flash_size;
    esp_chip_info_t chip_info; 

    ret = nvs_flash_init();
    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();
    }
    esp_flash_get_size(NULL, &flash_size);
    esp_chip_info(&chip_info);
    printf("内核CPU数量%d\n",chip_info.cores); 
    printf("FLASH Size:%ld MB Flash\r\n",flash_size / (1024 * 1024));
    printf("PSRAM Size:%d Bytes\r\n", esp_psram_get_size());

    // system_clock_info();
    // ledc_init();
    pwm_fade_init();

    while(1)
    {
        vTaskDelay(100);
        printf("LEDC PWM Duty Value:%ld\r\n", get_ledc_duty_value());
    }
}





五、CMakeList文件


# CMake最低版本
cmake_minimum_required(VERSION 3.16)

# 指定额外组件搜索目录
set(EXTRA_COMPONENT_DIRS components/Middlewares)

# 强制编译器彩色显示编译信息
add_compile_options(-fdiagnostics-color=always)

# 指定编译目标芯片
set(IDF_TARGET esp32s3)

# 日志输出命令
message(STATUS "Current IDF_PATH from environment: $ENV{IDF_PATH}")

# ESP-IDF核心构建脚本启动ESP-IDF构建系统
include($ENV{IDF_PATH}/tools/cmake/project.cmake)

# 定义工程名称
project(main)



idf_component_register(SRCS "main.c"
                    INCLUDE_DIRS ".")



set(src_dirs 
            Clock
            PWM
            FadePWM)

set(include_dirs 
                Clock
                PWM
                FadePWM)

set(requires    driver 
                nvs_flash 
                esp_psram 
                spi_flash)

# idf_component_register(SRC_DIRS ${src_dirs} INCLUDE_DIRS ${include_dirs} REQUIRES ${requires})
idf_component_register(SRC_DIRS ${src_dirs}
                       INCLUDE_DIRS ${include_dirs}
                       REQUIRES ${requires})
component_compile_options(-ffast-math -O3 -Wno-error=format -Wno-format)





六、运行结果

I (63) boot:  0 nvs              WiFi data        01 02 00009000 00006000
I (70) boot:  1 phy_init         RF data          01 01 0000f000 00001000
I (76) boot:  2 factory          factory app      00 00 00010000 001f0000
I (83) boot:  3 vfs              Unknown data     01 81 00200000 00a00000
I (89) boot:  4 storage          Unknown data     01 82 00c00000 00400000
I (96) boot: End of partition table
I (99) esp_image: segment 0: paddr=00010020 vaddr=3c020020 size=0b668h ( 46696) map
I (113) esp_image: segment 1: paddr=0001b690 vaddr=3fc94300 size=02f4ch ( 12108) load
I (116) esp_image: segment 2: paddr=0001e5e4 vaddr=40374000 size=01a34h (  6708) load
I (123) esp_image: segment 3: paddr=00020020 vaddr=42000020 size=1cadch (117468) map
I (146) esp_image: segment 4: paddr=0003cb04 vaddr=40375a34 size=0e8a0h ( 59552) load
I (158) esp_image: segment 5: paddr=0004b3ac vaddr=600fe100 size=0001ch (    28) load
I (165) boot: Loaded app from partition at offset 0x10000
I (165) boot: Disabling RNG early entropy source...
I (176) octal_psram: vendor id    : 0x0d (AP)
I (176) octal_psram: dev id       : 0x02 (generation 3)
I (176) octal_psram: density      : 0x03 (64 Mbit)
I (178) octal_psram: good-die     : 0x01 (Pass)
I (182) octal_psram: Latency      : 0x01 (Fixed)
I (187) octal_psram: VCC          : 0x01 (3V)
I (191) octal_psram: SRF          : 0x01 (Fast Refresh)
I (196) octal_psram: BurstType    : 0x01 (Hybrid Wrap)
I (201) octal_psram: BurstLen     : 0x01 (32 Byte)
I (205) octal_psram: Readlatency  : 0x02 (10 cycles@Fixed)
I (210) octal_psram: DriveStrength: 0x00 (1/1)
I (215) MSPI Timing: PSRAM timing tuning index: 5
I (219) esp_psram: Found 8MB PSRAM device
I (223) esp_psram: Speed: 80MHz
I (226) cpu_start: Multicore app
I (661) esp_psram: SPI SRAM memory test OK
I (670) cpu_start: Pro cpu start user code
I (670) cpu_start: cpu freq: 240000000 Hz
I (670) app_init: Application information:
I (670) app_init: Project name:     main
I (674) app_init: App version:      1
I (677) app_init: Compile time:     Feb 10 2026 14:55:07
I (682) app_init: ELF file SHA256:  c5f217a63...
I (686) app_init: ESP-IDF:          v5.4.1-dirty
I (691) efuse_init: Min chip rev:     v0.0
I (694) efuse_init: Max chip rev:     v0.99 
I (698) efuse_init: Chip rev:         v0.2
I (702) heap_init: Initializing. RAM available for dynamic allocation:
I (709) heap_init: At 3FC97BE8 len 00051B28 (326 KiB): RAM
I (714) heap_init: At 3FCE9710 len 00005724 (21 KiB): RAM
I (719) heap_init: At 3FCF0000 len 00008000 (32 KiB): DRAM
I (724) heap_init: At 600FE11C len 00001ECC (7 KiB): RTCRAM
I (729) esp_psram: Adding pool of 8192K of PSRAM memory to heap allocator
I (736) spi_flash: detected chip: generic
I (740) spi_flash: flash io: qio
I (743) sleep_gpio: Configure to isolate all GPIO pins in sleep state
I (749) sleep_gpio: Enable automatic switching of GPIO sleep configuration
I (756) main_task: Started on CPU0
I (759) esp_psram: Reserving pool of 32K of internal memory for DMA/internal allocations
I (767) main_task: Calling app_main()
FLASH Size:16 MB Flash

PSRAM Size:8388608 Bytes

LEDC PWM Duty Value:248

LEDC PWM Duty Value:498

LEDC PWM Duty Value:748

LEDC PWM Duty Value:998

LEDC PWM Duty Value:798

LEDC PWM Duty Value:548

LEDC PWM Duty Value:298

LEDC PWM Duty Value:48

LEDC PWM Duty Value:201

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

更多推荐