当前位置: 首页 > news >正文

SOC-ESP32S3部分​​​​​​​:15-PWM脉冲宽度调制

飞书文档https://x509p6c8to.feishu.cn/wiki/BuoBwzcpoikwZdkOGiEcmsoonod

脉冲宽度调制(PWM)是一种在数字系统中模拟模拟信号的方法。通过改变脉冲的宽度,我们可以控制电源的输出,从而控制例如LED的亮度或电机的速度。

ESP32-S3 提供了LED PWM 控制器,简写为LEDC,用于生成控制LED 的脉冲宽度调制信号,这里仅仅是命名的区别,其实控制LEDC就是通用的PWM控制器。 LED PWM 控制器具有八个独立的 PWM 生成器(即八个通道)。每个 PWM 生成器会从四个通用定时器中选择一个,以该定时器的计数值作为基准生成 PWM 信号。

ESP32-S3的SW_PWM功能允许我们通过软件来控制PWM,而不需要额外的硬件。这意味着我们可以使用任何GPIO引脚作为PWM输出,极大地提高了系统的灵活性。

LED PWM文档参考:

https://docs.espressif.com/projects/esp-idf/zh_CN/v5.4/esp32s3/api-reference/peripherals/ledc.html

要使用ESP32-S3的SW_PWM,我们需要进行以下步骤:

  1. 配置LEDC 使用的定时器为某个定时器
  2. 配置LEDC 使用的通道为某个通道
  3. 配置LEDC 定时器占空比值

1.1、配置LEDC定时器

ledc_timer_config_t 结构体用于配置 LEDC 定时器

esp_err_t ledc_timer_config(const ledc_timer_config_t *timer_conf);
功能: ledc_timer_config 函数用于配置 LED 控制器(LEDC)的定时器。通过传递一个 ledc_timer_config_t 结构体,可以设置定时器的速度模式、占空比分辨率、定时器编号、频率和时钟源。
参数:
timer_conf: 指向 ledc_timer_config_t 结构体的指针,包含定时器的配置参数。
返回值:
ESP_OK: 定时器配置成功。
ESP_ERR_INVALID_ARG: 参数无效。
ESP_ERR_INVALID_STATE: 定时器未创建或已启用。ledc_timer_config_t 结构体用于定义和配置 LED 控制器(LEDC)的定时器。通过这个结构体,你可以指定定时器的速度模式、占空比分辨率、定时器编号、频率和时钟源。
typedef struct {ledc_mode_t speed_mode;      ledc_timer_bit_t duty_resolution; //!< LEDC duty resolutionledc_timer_t timer_num;       //!< LEDC timer numberuint32_t freq_hz;             //!< LEDC timer frequency (Hz)ledc_clk_cfg_t clk_cfg;       //!< LEDC timer clock source
} ledc_timer_config_t;ledc_mode_t speed_mode:
描述: 指定 LEDC 的速度模式。可以是以下值之一:
LEDC_LOW_SPEED_MODE: 低速模式(默认),适用于大多数应用。
LEDC_HIGH_SPEED_MODE: 高速模式,适用于需要更高频率的应用。ledc_timer_bit_t duty_resolution:
描述: 设置占空比的分辨率,即占空比的位数。分辨率越高,占空比的精度越高。
可选值包括 LEDC_TIMER_1_BIT 到 LEDC_TIMER_16_BIT,通常使用较高的分辨率如 LEDC_TIMER_13_BIT。ledc_timer_t timer_num:
描述: 指定使用的定时器编号。LEDC 支持多个定时器,每个定时器可以独立配置。
LEDC_TIMER_0: 定时器 0。
LEDC_TIMER_1: 定时器 1。
LEDC_TIMER_2: 定时器 2。
LEDC_TIMER_3: 定时器 3。uint32_t freq_hz:
描述: 设置输出 PWM 信号的频率,单位为赫兹 (Hz)。频率决定了 PWM 波形每秒的周期数。ledc_clk_cfg_t clk_cfg:
描述: 指定定时器的时钟源配置。可以选择自动选择时钟源或手动指定。
LEDC_AUTO_CLK: 自动选择时钟源。
LEDC_USE_APB_CLK: 使用 APB 时钟源。
LEDC_USE_RTC8M_CLK: 使用 RTC 8 MHz 时钟源。
LEDC_USE_XTAL_CLK: 使用晶振时钟源。
LEDC_USE_PLL_F80M_CLK: 使用 PLL 80 MHz 时钟源。
LEDC_USE_PLL_D2_CLK: 使用 PLL 分频后的时钟源。

应用参考:

    ledc_timer_config_t ledc_timer = {.speed_mode       = LEDC_LOW_SPEED_MODE,   // 设置为低速模式.duty_resolution  = LEDC_TIMER_13_BIT,     // 设置占空比分辨率为 13 位.timer_num        = LEDC_TIMER_0,          // 使用定时器 0.freq_hz          = 4000,                  // 设置输出频率为 4 kHz.clk_cfg          = LEDC_AUTO_CLK          // 自动选择时钟源};//ledc_timer_config 函数用于配置 LEDC(LED 控制器)定时器的参数。ESP_ERROR_CHECK(ledc_timer_config(&ledc_timer));

2.1、配置LEDC通道参数

ledc_channel_config_t用于配置 LEDC PWM 通道,并将其应用到指定的 GPIO 引脚。

esp_err_t ledc_channel_config(const ledc_channel_config_t *ledc_conf);
功能: ledc_channel_config 函数用于配置 LED 控制器(LEDC)的通道。通过传递一个 ledc_channel_config_t 结构体,可以设置通道的速度模式、通道编号、关联的定时器、中断类型、GPIO 引脚、初始占空比和高电平起点。
参数:
ledc_conf: 指向 ledc_channel_config_t 结构体的指针,包含通道的配置参数。
返回值:
ESP_OK: 通道配置成功。
ESP_ERR_INVALID_ARG: 参数无效。
ESP_ERR_INVALID_STATE: 通道未创建或已启用。ledc_channel_config_t 结构体用于定义和配置 LED 控制器(LEDC)的通道。通过这个结构体,你可以指定通道的速度模式、通道编号、关联的定时器、中断类型、GPIO 引脚、初始占空比和高电平起点。
typedef struct {ledc_mode_t speed_mode;      ledc_channel_t channel;       //!< LEDC channel numberledc_timer_t timer_sel;       //!< LEDC timer number to be usedledc_intr_type_t intr_type;   //!< LEDC interrupt typegpio_num_t gpio_num;          //!< GPIO number to be useduint32_t duty;                //!< Initial duty cycleuint32_t hpoint;              //!< Initial high point of duty cycle
} ledc_channel_config_t;
功能:
ledc_mode_t speed_mode:
描述: 指定 LEDC 的速度模式。可以是以下值之一:
LEDC_LOW_SPEED_MODE: 低速模式。
LEDC_HIGH_SPEED_MODE: 高速模式。ledc_channel_t channel:
描述: 指定使用的 LEDC 通道编号。可以是以下值之一:
LEDC_CHANNEL_0 到 LEDC_CHANNEL_15可选。ledc_timer_t timer_sel:
描述: 指定关联的定时器编号。定时器决定了该通道的频率和占空比分辨率。可以是以下值之一:
LEDC_TIMER_0: 定时器 0。
LEDC_TIMER_1: 定时器 1。
LEDC_TIMER_2: 定时器 2。
LEDC_TIMER_3: 定时器 3。ledc_intr_type_t intr_type:
描述: 指定是否启用中断以及中断触发条件。
#define GPIO_INTR_DISABLE     0     /*!< 禁用 GPIO 中断                             */
#define GPIO_INTR_POSEDGE     1     /*!< GPIO 中断类型 : 上升沿触发                  */
#define GPIO_INTR_NEGEDGE     2     /*!< GPIO 中断类型 : 下降沿触发                 */
#define GPIO_INTR_ANYEDGE     3     /*!< GPIO 中断类型 : 上升沿和下降沿触发          */
#define GPIO_INTR_LOW_LEVEL   4     /*!< GPIO 中断类型 : 低电平触发                  */
#define GPIO_INTR_HIGH_LEVEL  5     /*!< GPIO 中断类型 : 高电平触发                  */gpio_num_t gpio_num:
描述: 指定使用的 GPIO 引脚编号。PWM 信号将通过这个引脚输出uint32_t duty:
描述: 设置初始占空比。占空比决定了高电平时间与周期时间的比例。uint32_t hpoint:
描述: 高电平起点,用于某些特殊模式(如相位控制)。对于普通 PWM 应用,通常设置为 0。

应用参考:

// 准备并应用 LEDC PWM 通道配置
ledc_channel_config_t ledc_channel = {.speed_mode     = LEDC_LOW_SPEED_MODE, // 设置为低速模式.channel        = LEDC_CHANNEL_0,      // 使用通道 0.timer_sel      = LEDC_TIMER_0,        // 关联定时器 0.intr_type      = LEDC_INTR_DISABLE,   // 禁用中断.gpio_num       = 5,                   // 定义输出 GPIO 引脚为 GPIO 5.duty           = 0,                   // 设置初始占空比为 0%.hpoint         = 0                    // 设置高电平起点为 0
};
ESP_ERROR_CHECK(ledc_channel_config(&ledc_channel));

3.1、更新PWM占空比

ledc_set_dutyledc_update_duty 是用于设置和更新 LEDC 通道占空比的两个关键函数。

esp_err_t ledc_set_duty(ledc_mode_t speed_mode, ledc_channel_t channel, uint32_t duty);
参数
speed_mode::LEDC 的速度模式,可以是低速模式或高速模式。
channel:指定使用的 LEDC 通道编号。
duty:要设置的占空比值。这个值是一个无符号整数,范围取决于定时器的占空比分辨率。
示例中设置为 4096,表示 50% 的占空比(因为占空比分辨率为 13 位,即 (2^{13} = 8192),所以 50% 占空比对应 4096)。esp_err_t ledc_update_duty(ledc_mode_t speed_mode, ledc_channel_t channel);
参数
speed_mode:LEDC 的速度模式,可以是低速模式或高速模式。
channel:指定使用的 LEDC 通道编号。

使用参考

    // 设置占空比为 50%//(4096) // 设置占空比为 50%。 (2 ** 13) * 50% = 4096ESP_ERROR_CHECK(ledc_set_duty(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_0, 4096));// 更新占空比以应用新值ESP_ERROR_CHECK(ledc_update_duty(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_0));

最终参考代码

这里我们使用PWM控制GPIO9上的LED亮度值为一半,我们可以通过修改占空比改变它的亮灭程度

#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/ledc.h"
#include "esp_err.h"static void ledc_init(void)
{// 准备并应用 LEDC PWM 定时器配置ledc_timer_config_t ledc_timer = {.speed_mode       = LEDC_LOW_SPEED_MODE,   // 设置为低速模式.duty_resolution  = LEDC_TIMER_13_BIT,     // 设置占空比分辨率为 13 位.timer_num        = LEDC_TIMER_0,          // 使用定时器 0.freq_hz          = 4000,                  // 设置输出频率为 4 kHz.clk_cfg          = LEDC_AUTO_CLK          // 自动选择时钟源};ESP_ERROR_CHECK(ledc_timer_config(&ledc_timer));// 准备并应用 LEDC PWM 通道配置ledc_channel_config_t ledc_channel = {.speed_mode     = LEDC_LOW_SPEED_MODE, // 设置为低速模式.channel        = LEDC_CHANNEL_0,      // 使用通道 0.timer_sel      = LEDC_TIMER_0,        // 关联定时器 0.intr_type      = LEDC_INTR_DISABLE,   // 禁用中断.gpio_num       = 9,                   // 定义输出 GPIO 引脚为 GPIO 9,对应LED引脚.duty           = 0,                   // 设置初始占空比为 0%.hpoint         = 0                    // 设置高电平起点为 0};ESP_ERROR_CHECK(ledc_channel_config(&ledc_channel));
}void update_duty(uint32_t duty) {ESP_ERROR_CHECK(ledc_set_duty(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_0, duty));ESP_ERROR_CHECK(ledc_update_duty(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_0));
}void app_main(void)
{// 设置 LEDC 外设配置ledc_init();// 设置占空比为 50%ESP_ERROR_CHECK(ledc_set_duty(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_0, 8000)); //设置占空比为50%。(2^13)*50%=4096// 更新占空比以应用新值ESP_ERROR_CHECK(ledc_update_duty(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_0));int duty = 0;while (1){duty = duty + 100;if(duty >= 8192)duty = 0;//硬件电路上,LED1灯是低电平点亮的,所以我们可以看到占空比越低灯越亮update_duty(duty);vTaskDelay(100 / portTICK_PERIOD_MS);}}

相关文章:

  • 赋能低空经济 | 奇妙智能已掌握AI+无人机智慧巡检技术
  • 浅谈Mysql的MVCC机制(RC与RR隔离级别)
  • 定时清理流媒体服务器录像自动化bash脚本
  • 为My Retro应用添加安全防护
  • 线程池详解:原理、使用与优化
  • 机器学习算法-- K 近邻算法(KNN)
  • 关于空调温度控制仿真模型的详细技术文档,包含数学模型、Python实现和系统分析
  • 丰富案例库:解锁智能门锁行业唯创语音交互方案的应用优势
  • 小土堆pytorch--现有网络模型的使用及修改
  • 在PyTorch中,有了y = x + y,为什么还需要y += x,有什么好处呢?
  • cursor使用mcp
  • 基于Matlab实现各种光谱数据预处理
  • 数据库相关问题
  • 工控安全审计与网络流量监控系统的协同防御
  • 字节跳动推出开源多模态模型 BAGEL 从图像生成到世界建模
  • Solana账户创建与Rust实践全攻略
  • 什么是Windows内存压缩? win10/11系统启用和禁用内存压缩的教程
  • 图标变白,开始菜单栏无法打开程序(以jupyter为例)
  • 让jupyter notebook显示目录
  • Lua中的`self`参数:揭秘隐藏的“对象上下文”
  • 兰州网站建设公司/软文写作范文500字
  • 智能网站建设软件/东莞网站公司哪家好
  • 网站导航内链建设/2022智慧树互联网与营销创新
  • 网站建设实训的认识/网站如何优化流程
  • 自己公司产品网站的好处/郑州百度推广seo
  • 给别人做网站收钱违法吗/现在感染症状有哪些