esp32s3-pwm介绍与stm32的不同原理

1.ESP32-S3 最多可同时生成 20 路独立 PWM 波形,由 LEDC 和 MCPWM 模块共同提供。

  • LEDC 模块:8 个独立通道,对应 8 路 PWM 波形。
  • MCPWM 模块:2 个单元各含 6 路输出,总计 12 路 PWM 波形。

2.通道就是独立输出 PWM 波形的硬件单元,LEDC 的 8 个通道虽然独立输出,但会共用 4 个定时器,同一定时器下的通道 PWM 周期是相同的;MCPWM 的通道独立性更强,不仅波形独立,还能灵活配置互补、死区等专属功能。

3.MCPWM 是 Motor Control PWM(电机控制脉宽调制器) ,专为电机控制、数字电源等高要求场景设计;LEDC 是 LED Control(LED 控制器),主打 LED 调光与基础 PWM 输出。两者核心区别如下:

核心定位与通道数

  • MCPWM :2 个独立单元(MCPWM0/1),每单元 3 个操作器,每操作器 2 路 PWM,总计12 路独立输出,支持互补 / 独立模式。
  • LEDC :1 个控制器,8 路独立通道,共用 4 个定时器,每通道绑定 1 个定时器生成波形。

4.选MCPWM:需要互补 PWM、死区、故障保护、输入捕获,或用于电机 / 电源等高要求控制。

LEDC:仅需基础 PWM 或 LED 渐变,追求简单配置与低 CPU 负载。

5.具体来说:

  1. STM32 定时器 PWM :核心是 ARR(自动重装载值,决定周期) + CCRx(捕获比较值,决定占空比) ,定时器计数到 CCRx 翻转电平,到 ARR 复位,本质是单阈值控制高低电平切换。
  2. ESP32 MCPWM 模块 :用 period(周期值) + cmp_a/cmp_b(两个比较阈值) ,可以灵活生成两路互补 PWM,还能通过两个阈值的差值设置死区;LEDC 模块虽然日常用duty(占空比) 配置,但底层也是基于定时器周期和比较阈值的双参数逻辑,只是封装得更简单,在两个阈值之间才会输出高电平。

6.频率:就是你说的一秒产生的 PWM 波形个数,和周期成反比,频率越高波形周期越短。

分辨率 :不是单纯的计数范围,而是计数范围对应的调节精细度,计数范围越大,分辨率越高。比如 16 位定时器计数范围 0-65535,比 8 位定时器 0-255 的分辨率高,能实现更细腻的周期或占空比调节。

占空比:有效电平的持续时间就叫占空比

复制代码
#include <stdio.h>
#include "driver/gpio.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/ledc.h"

// //初始化gpio引脚
// void ledc_flash_init(){

//     gpio_config_t ledc_cfg={
//         .pin_bit_mask=(1<<(GPIO_NUM_15)),
//         .mode=GPIO_MODE_OUTPUT,
//     };
//     gpio_config(&ledc_cfg);
// }

void ledc_breath_init(){
//初始化ledc寄存器
    ledc_timer_config_t lec_timer={
        .clk_cfg=LEDC_AUTO_CLK,//选择时钟源,自动选择时钟
        .duty_resolution=LEDC_TIMER_12_BIT,//确定计数范围,4095(2的12次方-1)
        .freq_hz=5000,//1s产生多少PWM波形
        .speed_mode=LEDC_LOW_SPEED_MODE,//时钟速度模式,ledc限制为低速模式
        .timer_num=LEDC_TIMER_0,//选择那个时钟作为输出,一共有四个来源
    };
    ledc_timer_config(&lec_timer);

//初始化PWM通道,输出pwm波
    ledc_channel_config_t ledc_channel={
        .channel=LEDC_CHANNEL_0,
        .duty=0,//有效电平的持续时间,这个是初始化
        .gpio_num=GPIO_NUM_15,
        .speed_mode=LEDC_LOW_SPEED_MODE,
        .timer_sel=LEDC_TIMER_0,
    };
    ledc_channel_config(&ledc_channel);

//启动硬件的渐变功能
ledc_fade_func_install(0);
}
void app_main(void)
{
    ledc_breath_init();
    while (1)
    {
        ledc_set_fade_with_time(LEDC_LOW_SPEED_MODE,LEDC_CHANNEL_0,4095,2000);
        //等渐变完成函数才会结束
        ledc_fade_start(LEDC_LOW_SPEED_MODE,LEDC_CHANNEL_0,LEDC_FADE_WAIT_DONE);
        
        ledc_set_fade_with_time(LEDC_LOW_SPEED_MODE,LEDC_CHANNEL_0,0,2000);
        //等渐变完成函数才会结束
        ledc_fade_start(LEDC_LOW_SPEED_MODE,LEDC_CHANNEL_0,LEDC_FADE_WAIT_DONE);
    }
    

}
相关推荐
xiangw@GZ18 小时前
CapSense底层逻辑:并行走线的强耦合干扰
单片机·嵌入式硬件
逐步前行18 小时前
STM32_ADC_寄存器操作
stm32·单片机·嵌入式硬件
LCG元19 小时前
STM32实战:基于STM32F103的智能门禁系统(RFID+指纹)
stm32·单片机·嵌入式硬件
可乐鸡翅好好吃20 小时前
NRF芯片下的ADC采集
单片机·嵌入式硬件
3壹20 小时前
LED模块控制与左移运算详解
单片机·嵌入式硬件
senijusene20 小时前
通信概念,51UART的使用,以及MODBUS的简单应用
c语言·开发语言·单片机·51单片机
Zevalin爱灰灰21 小时前
零基础入门学用物联网(ESP8266) 第一部分 基础知识篇(五)
单片机·物联网·嵌入式·esp8266
学嵌入式的小杨同学1 天前
STM32 进阶封神之路(二十二):DMA 实战全攻略 ——ADC 采集 + 串口收发 + 内存复制(库函数 + 代码落地)
c++·stm32·单片机·嵌入式硬件·mcu·硬件架构·pcb
是翔仔呐1 天前
C语言从黑框框到控硬件!51单片机零基础保姆式全系列教程 开篇前言+全书总览
c语言·开发语言·单片机·嵌入式硬件·gitee·51单片机
流浪_彩虹1 天前
MCU/DSP 与 ROS2 如何通信?XRCE-DDS 实现 rostopic 与嵌入式 Msg 无缝映射(附架构图)
单片机·嵌入式硬件