S2-02 ESP-IDF 开发 :PWM

PWM

PWM 是 Pulse Width Modulation 的缩写,中文名为脉宽调制。它是一种通过调整信号的脉冲宽度来控制信号平均值的技术。在嵌入式系统中,PWM 通常用于控制电机、LED 等外围设备的亮度、速度等参数。

PWM 技术通过不断切换高电平和低电平状态来生成一个矩形波形信号,其中高电平和低电平的持续时间称为占空比。占空比表示每个周期内高电平信号所占的时间比例,通常以百分比的形式表示。

工作原理如下:在一个固定的周期内,PWM 信号的高电平和低电平部分会分别占据一定的时间段,同时这两个时间段的长度可以由程序进行控制。即根据需要,我们可以改变高电平和低电平的时间比例,从而实现对输出信号的控制。当占空比较小时,PWM 信号的平均值也比较小;当占空比较大时, PWM 信号的平均值也相应增大。

例如,如果一个 LED 的亮度需要控制在 50% 左右,就可以使用 PWM 技术,让高电平时间和低电平时间各占一半。在每个周期内,LED 将会以高亮度发光和低亮度发光交替出现,最终呈现出平均亮度约为 50% 的状态。

在嵌入式系统中,常用的单片机都具有 PWM 模块,可以通过配置不同的参数实现对各种外围设备的精确控制。
S2-02 ESP-IDF 开发 :PWM_第1张图片

PWM的频率: 指在1秒钟内,信号从高电平到低电平再回到高电平的次数,也就是说一秒钟PWM有多少个周期,单位Hz。
PWM的周期: T=1/f,T是周期,f是频率。如果频率为50Hz ,也就是说一个周期是20ms,那么一秒钟就有 50次PWM周期。
PWM的脉宽: 指的是在一个脉冲周期内,搞定平持续的时间。
PWM的占空比: 是一个脉冲周期内,高电平的时间与整个周期时间的比例,单位是% (0%-100%)一个周期的长度。

PWM 调制电压

以ESP32单片机为例,其IO口只能输出高电平和低电平。

假设高电平为5V、低电平则为0V,那么要输出不同的模拟电压就要用到PWM。通过改变IO口输出的方波的占空比,从而获得使用数字信号模拟成的模拟电压信号。

电压是以一种脉冲序列被加到模拟负载上去的,接通时是高电平1,断开时是低电平0。接通时直流供电输出,断开时直流供电断开。通过对接通和断开时间的控制,理论上来讲,可以输出任意不大于最大电压值5V的模拟电压。

比方说,占空比为50%那就是高电平时间一半,低电平时间一半。在一定的频率下,就可以得到模拟的2.5V输出电压。那么75%的占空比,得到的电压就是3.75V,如下图所示。
S2-02 ESP-IDF 开发 :PWM_第2张图片

也就是说,在一定的频率下,通过不同的占空比即可得到不同大小的输出模拟电压,PWM就是通过这种原理实现数字模拟信号转换的。

LED呼吸灯控制

控制呼吸灯可以使用 PWM 技术,其原理是通过改变脉冲宽度的方式来控制 LED 的亮度变化,从而模拟出人类的呼吸过程。

具体来说,PWM 信号就是一种占空比可调的方波信号,周期越短,LED 在亮度上的变化越细致。通常情况下,需要对 PWM 信号进行平滑滤波,以避免频率较高的信号带来的高频噪声影响 LED 的亮度稳定性。

对于呼吸灯的实现,一般采用逐渐增加再逐渐减小的方式;在一个呼吸周期内,亮度由最暗逐渐增加到最亮,然后再逐渐变暗直至熄灭,这样就形成了类似于人类呼吸的效果。这个过程就是PWM占空比从低到高再到低的重复过程。

PWM 控制电机转速

调节占空比可以实现不同电压的输出,实现对电机转速的调节。

对于直流电机来讲,电机输出端引脚是高电平电机就可以转动,当输出端高电平时,电机会转动,但是是一点一点的提速,在高电平突然转向低电平时,电机由于电感有防止电流突变的作用是不会停止的,会保持这原有的转速,以此往复,电机的转速就是周期内输出的平均电压值,所以实质上我们调速是将电机处于一种,似停非停,似全速转动又非全速转动的状态,那么在一个周期的平均速度就是我们占空比调出来的速度了。

在电机控制中,电压越大,电机转速越快,而通过PWM输出不同的模拟电压,便可以使电机达到不同的输出转速。

当然,在电机控制中,不同的电机都有其适应的频率 频率太低会导致运动不稳定,如果频率刚好在人耳听觉范围,有时还会听到呼啸声。频率太高时,电机可能反应不过来,正常的电机频率在 6-16kHZ之间为好。

PWM 控制舵机

舵机通过一个特殊的电机(内部包含针齿)与一种称为电位计的旋转传感器相连。将 PWM 信号应用于舵机,会在电机上产生脉冲信号,并根据特定的占空比转动电机。这样,在一定周期内,通过改变 PWM 的占空比,可以控制舵机的角度或位置。

舵机的工作范围通常是 0° 到 180°,对应 PWM 信号的占空比范围为 2.5% 到 12.5%。当 PWM 占空比为 2.5% 时,舵机处于最左边位置;当 PWM 占空比为 12.2% 时,舵机处于最右边位置;当 PWM 占空比为 7.5% 时,舵机处于中心位置。在实际使用中,可以根据需要将 PWM 占空比设置为不同的值,以调整舵机的位置。

舵机的频率一般为频率为50HZ,也就是一个20ms左右的时基脉冲,而脉冲的高电平部分一般为0.5ms-2.5ms范围,来控制舵机不同的转角。500-2500us的PWM高电平部分对应控制180度舵机的0-180度。

以180度角度伺服为例,那么对应的控制关系是这样的:

  • 0.5ms-------------0度;
  • 1.0ms------------45度;
  • 1.5ms------------90度;
  • 2.0ms-----------135度;
  • 2.5ms-----------180度;
    S2-02 ESP-IDF 开发 :PWM_第3张图片

要控制舵机的位置,需要在程序中定义一个 PWM 输出通道,并使用相应的 API 函数来配置该通道。一般来说,舵机会占用单个 PWM 通道,并连接到某个 GPIO 引脚上。在 ESP-IDF 中,可以使用 LEDC 控制器来实现 PWM 输出,相关的 API 函数包括 ledc_timer_config()、ledc_channel_config()、ledc_set_duty()、ledc_update_duty() 等。

LEDC相关函数

自 IDF4.0 之后,PWM 控制由原来的 driver/pwm.h 换成了 ledc 模块,需要引入 driver/ledc.h 头文件,之前的pwm函数已经过时。

LEDC库是ESP-IDF(ESP32 IoT开发框架)提供的一个硬件抽象层,用于控制LED灯条等PWM(Pulse-Width Modulation,脉宽调制)设备。

LEDC库可以在ESP32微控制器上控制16路PWM输出;每个通道都可以使用不同的分辨率,并且可以独立地配置频率和占空比。LEDC库支持的最大PWM周期为4.096毫秒,最小占空比分辨率为1/65536。

使用LEDC库可以方便快捷的实现多种效果,如呼吸灯、流水灯、闪烁灯等,同时能够控制多种不同类型的LED灯,例如单色LED、RGB LED、RGBW LED等。LEDC库还包括一个逐个淡出/淡入的函数,可以让你实现一个非常优雅的LED渐变效果。

1. ledc_timer_config

该函数用于配置 PWM 定时器,需要传入一个 ledc_timer_config_t 结构体的指针,该结构体原型如下:

typedef struct {
    uint32_t speed_mode;    /*!< LEDC速度模式,高速(0)或低速(1)。*/
    uint32_t timer_num;     /*!< 选择一个定时器编号,从LEDC_TIMER_0到LEDC_TIMER_3中选一个。 */
    uint32_t freq_hz;           /*!< PWM信号频率,单位是赫兹。 */
    uint32_t duty_resolution; /*!< LEDC通道占空比分辨率,最大可设置为18位。 */
    uint32_t clk_cfg;     /*!< LEDC定时器源时钟配置 */
} ledc_timer_config_t;
成员 描述
speed_mode PWM输出的速度模式。速度模式有两个,一个是普通速度模式(NORMAL_MODE),一个是高速速度模式(HIGH_SPEED_MODE)。在普通速度模式下,可同时使用8个PWM通道,而在高速速度模式下,则可使用16个PWM通道。
timer_num PWM的定时器编号。ESP32平台可以使用四个定时器:TIMER0、TIMER1、TIMER2和TIMER3。
freq_hz PWM的频率。单位为赫兹(Hz),表示PWM输出波形的频率。例:freq_hz = 5000 表示PWM的输出频率为5kHz。
duty_resolution LEDC通道占空比分辨率位数,比如精度为13位,则最大可以表示为8191,最大可设置为18位。
clk_cfg 定时器时钟类型的配置。选项有:LEDC_USE_APB_CLK、LEDC_USE_RTC_CLK、LEDC_USE_REF_TICK、LEDC_USE_APB_CLK_8M和LEDC_USE_RTC_CLK_DIV。

在配置 PWM 的第一步,应该先为其分配对应的定时器。

2. ledc_channel_config

该函数用于配置 WPM 通道,需要传入一个 ledc_channel_config_t 结构体的指针,该结构体原型如下:

typedef struct {
    uint32_t channel;  /*!< 选择一个LEDC通道,从LEDC_CHANNEL_0到LEDC_CHANNEL_15中选一个。*/
    uint32_t duty;     /*!< 占空比,范围是0 ~ pow(2,duty_resolution)-1。*/
    uint32_t gpio_num; /*!< GPIO引脚的编号,范围是GPIO0 ~ GPIO33。*/
    uint32_t speed_mode; /*!< LEDC速度模式,高速(LEDC_HIGH_SPEED_MODE)或低速(LEDC_LOW_SPEED_MODE)。*/
    uint32_t hpoint;  /*!< 高电平结束的点,可根据需要选择,范围是0到2^duty_resolution-1。默认值为0。*/
    ledc_timer_t timer_sel; /*!< 选择一个定时器编号,从LEDC_TIMER_0到LEDC_TIMER_3中选一个。*/
    uint32_t intr_type; /*!< 中断类型,有LEDC_INTR_DISABLE、LEDC_INTR_FADE_END等值。*/
} ledc_channel_config_t;
成员 描述
channel 选择一个 PWM 通道,从LEDC_CHANNEL_0到LEDC_CHANNEL_15中选一个。通道的数量取决于使用的LEDC定时器数量,每个定时器最多可以设置8个 PWM 通道。
duty 占空比,范围是0 ~ pow(2, duty_resolution)-1。其中,duty_resolution由LEDC定时器的参数决定。
gpio_num GPIO引脚的编号,范围是GPIO0 ~ GPIO48(不同型号CPU引脚编号不同)。与该通道关联的GPIO引脚将会产生PWM信号输出。
speed_mode LEDC速度模式,高速(LEDC_HIGH_SPEED_MODE)或低速(LEDC_LOW_SPEED_MODE)。对于低速模式,分辨率可达10位,而对于高速模式,分辨率可达13位。这里选择和配置定时器时选择一样即可
hpoint 高电平结束时间点,指示 PWM 波形上高电平的结束位置。取值范围为 0~2^ledc_timer_config_t.duty_resolution-1。
timer_sel 选择一个定时器编号,从LEDC_TIMER_0到LEDC_TIMER_3中选一个。每个LED通道都必须分别分配一个定时器。如果多路PWM通道共用同一个定时器,则它们的频率将是相同的。这里需要选择的和 ledc_timer_config 定义的一致
intr_type 中断类型,有LEDC_INTR_DISABLE、LEDC_INTR_FADE_END等值。可以设置此参数以启用特定的中断处理程序,以便在PWM信号输出完成时获取通知。
3. ledc_set_duty

该函数用于设定 PWM 通道的占空比大小,函数原型如下:

esp_err_t ledc_set_duty(ledc_mode_t speed_mode, ledc_channel_t channel, uint32_t duty);
参数 描述
speed_mode LEDC速度模式,高速(LEDC_HIGH_SPEED_MODE)或低速(LEDC_LOW_SPEED_MODE)。
channel LEDC通道号,从 LEDC_CHANNEL_0 到 LEDC_CHANNEL_15 中选一个。
duty LEDC通道的占空比,取值范围为[0, (2^duty_resolution)-1],其中 duty_resolution 是LED占空比分辨率,受LEDC定时器预分频和计数器位数影响。
返回值 函数的返回值为 esp_err_t 类型,代表函数是否执行成功。如果函数执行成功,返回 ESP_OK,否则返回错误码。

ledc_set_duty() 函数的工作原理是,通过修改指定 LEDC 通道的占空比寄存器的值来改变 PWM 波形的占空比大小,从而控制 LED 灯光的强弱、电机的转速等。在调用该函数之前,需要先调用 ledc_timer_config()ledc_channel_config() 函数对 LEDC 定时器和通道进行配置。
但修改之后占空比无法马上生效,需要再次调用 ledc_update_duty() 才可以立即生效。

4. ledc_update_duty

该函数用于设置占空比后的更新,ledc_set_duty() 函数只是设置的占空比值更新到 LEDC 寄存器中,必须调用该函数更新后才能完成对 PWM 输出的控制,该函数原型如下:

esp_err_t ledc_update_duty(ledc_mode_t speed_mode, ledc_channel_t channel);
参数 描述
speed_mode LEDC速度模式,高速或低速。
channel LEDC通道号,从 LEDC_CHANNEL_0 到 LEDC_CHANNEL_15 中选一个。
返回值 函数的返回值为 esp_err_t 类型,代表函数是否执行成功。如果函数执行成功,返回 ESP_OK,否则返回错误码。
5. ledc_set_freq

该函数用于设置 PWM 的周期频率,函数原型如下:

esp_err_t ledc_set_freq(ledc_mode_t speed_mode, ledc_channel_t channel, uint32_t freq_hz);
参数 描述
speed_mode LEDC速度模式,高速或低速。
channel LEDC通道号,从 LEDC_CHANNEL_0 到 LEDC_CHANNEL_15 中选一个。
freq_hz PWM 周期频率,单位为 Hz。
返回值 函数的返回值为 esp_err_t 类型,代表函数是否执行成功。如果函数执行成功,返回 ESP_OK,否则返回错误码。

调用 ledc_set_freq() 函数可以设置指定通道的 PWM 波形的周期频率,从而改变 PWM 波形的周期。由于 PWM 波形的周期和占空比都会影响到 PWM 输出的电平和持续时间,因此通过修改 PWM 周期频率可以实现更精准的 PWM 输出控制。

需要注意的是,LED 的亮度和闪烁频率与 PWM 的周期和占空比有关,一般来说,设置合适的 PWM 周期频率可以有效减轻 LED 的闪烁现象。另外,在选择 PWM 周期频率时还需要考虑 GPIO 引脚的驱动能力和负载电流等因素,以充分发挥 LEDC 控制器的优势。

6. ledc_fade_func_install

该函数用于安装 PWM 的淡入淡出服务,在使用淡入淡出之前,必须通过该函数安装,否则会报错。函数原型如下:

esp_err_t ledc_fade_func_install(int intr_alloc_flags);

该函数有一个参数 intr_alloc_flags,表示用于分配中断的标志位,可以是多个 ESP_INTR_FLAG_* 标志的按位或。具体可参考 esp_intr_alloc.h 头文件。该参数用于控制中断的优先级和中断处理程序的运行环境。

淡入淡出效果将占用 PWM 的中断

7. ledc_set_fade_with_time

该函数用于设定当前 PWM 在指定的时间内 PWM 的占空比从起点到终点的参数,原型如下:

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)
参数 描述
speed_mode LED 所使用的速度模式,可取值为 LEDC_LOW_SPEED_MODE 或 LEDC_HIGH_SPEED_MODE。这里的速度模式对应的是时钟频率,低速模式下时钟频率较低,适合 PWM 频率较低的应用;高速模式下时钟频率较高,可以支持更高的 PWM 频率。
channel LED所使用的通道,取值范围为 0~15;
target_duty LED的目标占空比,取值范围为 0~(2^LEDC_TIMER_13_BIT)-1,即 0~8191;
max_fade_time_ms PWM 从当前占空比到目标占空比所用的最大时长,单位为毫秒

该函数设置的目标占空比值仅在启动淡入淡出操作后才会生效。淡入淡出的实际速度和最终达到的占空比取决于多个因素,如时钟频率、PWM周期、目标占空比等。因此,需要根据实际情况调整 max_fade_time_ms 参数的值以达到预期效果。

此外,需要注意以下几点:

  • 在同一个 LEDC通道上,只能同时进行一个淡入淡出操作。如果启动了多个淡入淡出操作,则后面的操作会覆盖前面的操作。
  • 淡入淡出操作完成后,LED的占空比将自动更新为目标占空比。
  • 如果使用 ledc_set_fade_with_time() 函数设置的最长淡入淡出时间小于 PWM周期,则淡入淡出效果可能不明显。
  • 如果使用 ledc_set_fade_with_time() 函数设置的最长淡入淡出时间大于 PWM周期的整数倍,则淡入淡出效果会在每个 PWM周期内逐渐体现,并在最长时间内完成。
8. ledc_fade_start

该函数用于用于启动淡入淡出效果,并在指定时间内将 PWM 从当前占空比平滑提升或降低至目标占空比,该函数原型如下:

esp_err_t ledc_fade_start(ledc_mode_t speed_mode, ledc_channel_t channel, ledc_fade_mode_t fade_mode)
参数 描述
speed_mode LED 所使用的速度模式,可取值为 LEDC_LOW_SPEED_MODE 或 LEDC_HIGH_SPEED_MODE。这里的速度模式对应的是时钟频率,低速模式下时钟频率较低,适合 PWM 频率较低的应用;高速模式下时钟频率较高,可以支持更高的 PWM 频率。
channel LED所使用的通道,取值范围为 0~15;
fade_mode LED 的淡入淡出模式,可取值为 LEDC_FADE_NO_WAIT、LEDC_FADE_WAIT_DONE 和 LEDC_FADE_WAIT_STOP。
fade_mode 取值如下:
  • LEDC_FADE_NO_WAIT 表示启动淡入淡出后立即返回,不等待淡入淡出完成;
  • LEDC_FADE_WAIT_DONE 表示启动淡入淡出后一直等待淡入淡出完成后再返回;
  • LEDC_FADE_WAIT_STOP 表示启动淡入淡出后等待淡入淡出停止后再返回。

ledc 模块中还有很多种操作函数,具体可以参考 components/driver/include/driver/ledc.h 头文件

例程演示

1. 通过手动调整占空比实现呼吸灯效果

    // 配置LED引脚为输出
    gpio_pad_select_gpio(LED_PIN);
    gpio_set_direction(LED_PIN, GPIO_MODE_OUTPUT);
    // 配置LEDC控制器,设置13位分辨率、最大占空比为8191、频率为5000Hz
    ledc_timer_config_t ledc_timer = {
        .speed_mode = LEDC_LOW_SPEED_MODE,    // 选择低速控制器
        .duty_resolution = LEDC_TIMER_13_BIT, // PWM信号精度为13字节,最高8191
        .timer_num = LEDC_TIMER_0,            // 选择定时器0作为时钟基
        .freq_hz = LEDC_BASE_FREQ             // PWM 时钟P频率为 5000Hz
    };
    // 配置LEDC(PWM)定时器参数
    ledc_timer_config(&ledc_timer);
    // 配置LEDC通道0,设置引脚为LED引脚、通道为0、占空比为0
    ledc_channel_config_t ledc_channel = {
        .channel = LEDC_CHANNEL_0,         //
        .speed_mode = LEDC_LOW_SPEED_MODE, // 选择低速控制器,和 ledc_timer_config_t 相同
        .gpio_num = LED_PIN,               // 要控制的引脚编号
        .timer_sel = LEDC_TIMER_0,         // 选择要使用的定时器通道
        .hpoint = 0,                       // 高电平结束时间点
        .duty = 0                          // 初始占空比
    };
    // duty、hpoint:这两个成员的取值范围与占空比分辨率有关,由 ledc_timer_config_t 中的 duty_resolution 决定。
    // 例如,当 duty_resolution 为 LEDC_TIMER_13_BIT 时,占空比和结束时间点的取值范围均为 0~8191。
    ledc_channel_config(&ledc_channel);
    int32_t intensity = 0;  // 初始化 PWM 信号的占空比为0
    int direction = 1;      // 初始化 PWM 信号的占空比变化方向为递增,灯两灭的方向
    int speed = 32;         // 呼吸的速度,每次增加或减少的占空比
    while (1)
    {
        // 更新 PWM 信号的占空比
        ledc_set_duty(ledc_channel.speed_mode, ledc_channel.channel, intensity);
        // 更新完之后必须调用 ledc_update_duty 更新,否则不起作用
        ledc_update_duty(ledc_channel.speed_mode, ledc_channel.channel);
        // 修改PWM信号的占空比,以实现呼吸灯效果
        intensity += direction * speed;     // 增加或减少占空比
        if (intensity > 8191)
        { // 如果超过最大占空比,需要逆转占空比变化方向
            intensity = 8191;
            direction = -1;
        }
        else if (intensity < 0)
        { // 如果低于最小占空比,需要逆转占空比变化方向
            intensity = 0;
            direction = 1;
        }
        vTaskDelay(pdMS_TO_TICKS(10)); // 延时10ms,以产生呼吸灯动画效果
    }

2. 通过淡入淡出实现 LED 呼吸灯效果

    // 配置LED引脚为输出
    gpio_pad_select_gpio(LED_PIN);
    gpio_set_direction(LED_PIN, GPIO_MODE_OUTPUT);
    // 配置LEDC控制器,设置13位分辨率、最大占空比为8191、频率为5000Hz
    ledc_timer_config_t ledc_timer = {
        .speed_mode = LEDC_LOW_SPEED_MODE,    // 选择低速控制器
        .duty_resolution = LEDC_TIMER_13_BIT, // PWM信号精度为13字节,最高8191
        .timer_num = LEDC_TIMER_0,            // 选择定时器0作为时钟基
        .freq_hz = LEDC_BASE_FREQ             // PWM 时钟P频率为 5000Hz
    };
    // 配置LEDC(PWM)定时器参数
    ledc_timer_config(&ledc_timer);
    // 配置LEDC通道0,设置引脚为LED引脚、通道为0、占空比为0
    ledc_channel_config_t ledc_channel = {
        .channel = LEDC_CHANNEL_0,         //
        .speed_mode = LEDC_LOW_SPEED_MODE, // 选择低速控制器,和 ledc_timer_config_t 相同
        .gpio_num = LED_PIN,               // 要控制的引脚编号
        .timer_sel = LEDC_TIMER_0,         // 选择要使用的定时器通道
        .hpoint = 0,                       // 高电平结束时间点
        .duty = 0                          // 初始占空比
    };
    // duty、hpoint:这两个成员的取值范围与占空比分辨率有关,由 ledc_timer_config_t 中的 duty_resolution 决定。
    // 例如,当 duty_resolution 为 LEDC_TIMER_13_BIT 时,占空比和结束时间点的取值范围均为 0~8191。
    ledc_channel_config(&ledc_channel);
    // 在低速通道初始化淡入淡出
    ledc_fade_func_install(ESP_INTR_FLAG_LEVEL1);
    while(1){
         // 淡入
        ledc_set_fade_with_time(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_0, 8191, 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);
    }

PWM 相关的其他模组

除了 LEDC 模组,ESP-IDF 中还有以下与 PWM 相关的模组:

MCPWM

MCPWM 是 ESP32 中的 Motor Control PWM 模块,它是一个复杂的 PWM 控制器。除了基本的 PWM 功能之外,MCPWM 还能够执行很多其他任务,如输入捕捉、输出比较和硬件死区控制等。因此,它被广泛应用于电机控制、热管理、LED 照明和音频应用等领域。
MCPWM 全称为 Motor Control PWM,它是 ESP32 芯片中的一个 PWM 模块,并具有许多独特的功能,如输入捕获、死区控制等。MCPWM 可以用于电机驱动、音频放大器、LED 灯控等领域,具有以下应用:

  • 电机驱动:MCPWM 可以精确控制电机的转速及方向,支持多种模式的电机驱动,例如:单相交流电机驱动、三相无刷直流电机驱动、步进电机驱动等。
  • 音频放大器:MCPWM 提供了输入捕获模式,能够实现高精度的频率测量和比较功能,因此可以用于音频放大器的工作。
  • LED 灯控:MCPWM 的占空比解析度较高,可以实现 LED 灯的精确控制,同时还支持 LED 的呼吸灯效果(即 PWM 按照一定的规律进行升降),因此可以用于 LED 灯的调光、调色等控制。

PCNT

PCNT 全称为 Pulse Counter(脉冲计数器),是 ESP32 芯片中的一个计数器模块。PCNT 模块可以用来计数外部事件,例如测量旋转角度、线速度、频率等,同时还支持输入捕获模式、方向控制模式等。

以下是 PCNT 模块的一些主要应用:

  • 编码器接口:PCNT 可以拓展更多 GPIO 输入接口,支持反向输入、捕获等功能,因此常用于实现编码器接口的设计,例如测量电机运动速度和位置等。
  • 计数器:PCNT 可以用作计数器,支持外部触发信号的自动计数,计数器的输出可以用于实现各种复杂的逻辑控制。
  • 频率计:PCNT 同时集成了频率计功能,支持高精度的频率计算,使用简便,可以用于测量频率、脉宽等参数。
  • 触摸计数器:PCNT 还可以用于实现按钮计数器或触摸计数器等应用,通过计算计数器的增减来判断用户的操作,实现特定的控制功能。
  1. RMT:
    RMT 模块是一个遥控信号发射器,它可以通过发送红外线、射频信号或 LED 脉冲等方式来控制各种设备。RMT 的主要功能是生成和发送数据序列,它可以允许用户定义不同的协议、波特率以及发送时序等参数。

RMT

RMT 模块是 ESP32 芯片中的一个远程控制模块,全称为 Remote Control Transmitter,支持通过红外信号、射频信号等方式对外设进行远程控制。RMT 模块具有以下特点:

  • 高精度:RMT 模块支持高达 8 个通道的数据发送和接收,同时还具有非常高的时间精度(数百纳秒级别),可以精确控制信号的发送和接收。
  • 多种协议支持:RMT 支持多种红外遥控协议、RC 5/6 协议、Sony SIRC 协议、NEC 协议等,同时还支持自定义协议,可以适应不同的硬件设备和控制场景。
  • 易用性:ESP-IDF 提供了 RMT API 库,使用简便、灵活,支持配置 RMT 模块的数据格式、协议类型、通道数、发送时序等参数,同时还提供了丰富的示例代码和文档支持。
  • 硬件资源占用小:RMT 模块在硬件资源占用方面非常小,仅需要一个 IO 引脚即可实现控制,相比其他外设模块大大降低了硬件成本和设计难度。

总之,RMT 模块是 ESP32 开发中非常有用的远程控制模块,具有高精度、多协议支持、易用性等特点,可以广泛应用于各种红外遥控、机器人控制、车载控制、无线测量等领域。

你可能感兴趣的:(ESP-IDF,入门篇,ESP32,ESP-IDF,嵌入式硬件)