ESP32 LEDC 调节占空比或频率

#include <Arduino.h>
// #include <driver/rtc_clk.h>
#include <stdio.h>
#include "driver/ledc.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_log.h"
// 定义 LED 连接的 GPIO 引脚
#define LEDC_PIN 12
// 定义 LEDC 通道和定时器
#define LEDC_TIMER LEDC_TIMER_0
#define LEDC_MODE LEDC_LOW_SPEED_MODE  // ESP32-C3 仅支持低速模式
#define LEDC_CHANNEL LEDC_CHANNEL_0
#define LEDC_DUTY_RES LEDC_TIMER_10_BIT // 设置占空比 
void ledc_init(void)
{
      //ESP32-C3 不支持 LEDC 模块的高速模式。
    // 配置 LEDC 定时器
    ledc_timer_config_t ledc_timer = {
        .speed_mode = LEDC_MODE,
        .duty_resolution = LEDC_DUTY_RES,
        .timer_num = LEDC_TIMER,
        .freq_hz = 1000,  // 初始频率 1kHz
        .clk_cfg = LEDC_AUTO_CLK
    };
    ESP_ERROR_CHECK(ledc_timer_config(&ledc_timer));

    // 配置 LEDC 通道
    ledc_channel_config_t ledc_channel = {
        .gpio_num = LEDC_PIN,
        .speed_mode = LEDC_MODE,
        .channel = LEDC_CHANNEL,
        .timer_sel = LEDC_TIMER,
        .duty = 0,  // 初始占空比为 0%
        .hpoint = 0
    };
    ESP_ERROR_CHECK(ledc_channel_config(&ledc_channel));
}
// 设置PWM波占空比
int ledc_duty(int duty)
{
  int ret;
  ret  = ledc_set_duty(LEDC_MODE, LEDC_CHANNEL, duty);
  ret  = ledc_update_duty(LEDC_MODE, LEDC_CHANNEL);
  return ret;
}
//设置PWM波频率
int ledc_freq(int freq)
{
  int ret;
  ret  =  ledc_set_freq(LEDC_MODE, LEDC_TIMER, freq);
  return ret;
}

void led_control_task(void *arg)
{
    // 逐渐增加占空比到 50%
    for (int duty = 0; duty <= 511; duty += 10) {
        // ledc_set_duty(LEDC_MODE, LEDC_CHANNEL, duty);
        // ledc_update_duty(LEDC_MODE, LEDC_CHANNEL);
        ledc_duty(duty);
        vTaskDelay(100 / portTICK_PERIOD_MS);  // 延迟 100ms
    }

    // 保持 50% 占空比一段时间
    vTaskDelay(2000 / portTICK_PERIOD_MS);  // 延迟 2s

    // 逐渐降低占空比到 0%
    for (int duty = 511; duty >= 0; duty -= 10) {
        // ledc_set_duty(LEDC_MODE, LEDC_CHANNEL, duty);
        // ledc_update_duty(LEDC_MODE, LEDC_CHANNEL);
        ledc_duty(duty);
        vTaskDelay(100 / portTICK_PERIOD_MS);  // 延迟 100ms
    }
    ledc_set_duty(LEDC_MODE, LEDC_CHANNEL, 255);
    ledc_update_duty(LEDC_MODE, LEDC_CHANNEL);
    // 动态修改频率
    for (int freq = 1000; freq <= 50000; freq += 1000) {
        //ledc_set_freq(LEDC_MODE, LEDC_TIMER, freq);
        ledc_freq(freq);
        printf("Frequency changed to %d Hz\n", freq);
        vTaskDelay(200 / portTICK_PERIOD_MS);  // 延迟 2s
    }
 
    // 也可以从高频逐渐降低频率
    for (int freq = 50000; freq >= 1000; freq -= 1000) {
        //ledc_set_freq(LEDC_MODE, LEDC_TIMER, freq);
        ledc_freq(freq);
        printf("Frequency changed to %d Hz\n", freq);
        vTaskDelay(200 / portTICK_PERIOD_MS);  // 延迟 2s
    }
    // 任务完成后删除任务
    vTaskDelete(NULL);
}
void setup() {
  // put your setup code here, to run once:
  //ESP32-C3 不支持 LEDC 模块的高速模式。
  ledc_init();

  // 启动一个任务来控制 PWM 信号
  xTaskCreate(led_control_task, "led_control_task", 2048, NULL, 5, NULL);
}

void loop() {
  // put your main code here, to run repeatedly:

}

 

posted @ 2025-03-05 20:38  辛河  阅读(195)  评论(0)    收藏  举报