ESP8266学习历程(4)——PWM

本文深入解析了PWM(脉冲宽度调制)的工作原理及其在ESP32平台上的实现方法,介绍了PWM头文件中的关键函数,并提供了一个实际的代码示例,展示了如何在ESP32上配置PWM周期、占空比和相位。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

PWM,英文名Pulse Width Modulation,是脉冲宽度调制缩写,它是通过对一系列脉冲的宽度进行调制,等效出所需要的波形(包含形状以及幅值),对模拟信号电平进行数字编码,也就是说通过调节占空比的变化来调节信号、能量等的变化,占空比就是指在一个周期内,信号处于高电平的时间占据整个信号周期的百分比,例如方波的占空比就是50%.

PWM用途很广,像一些步进电机、舵机等等都需要用到。

PWM头文件

#include "driver/pwm.h"

提供的接口有:

esp_err_t pwm_init(uint32_t period, uint32_t *duties, uint8_t channel_num, const uint32_t *pin_num);//PWM功能初始化,包括GPIO、频率和占空比。
esp_err_t pwm_deinit(void);		//失能PWM功能。
esp_err_t pwm_set_duty(uint8_t channel_num, uint32_t duty);		//设定PWM通道的占空比,channel_num不可超过pwm_init中设定的channel_num。
esp_err_t pwm_get_duty(uint8_t channel_num, uint32_t *duty_p);	//获取一个PWM通道的占空比。
esp_err_t pwm_set_period(uint32_t period);					  //设定PWM周期,单位:us。
esp_err_t pwm_get_period(uint32_t *period_p);				  //获取PWM周期,单位:us。
esp_err_t pwm_start(void);									//开始PWM输出
esp_err_t pwm_stop(uint32_t stop_level_mask);				  //停止PWM输出,参数是停止输出后通道电平。
esp_err_t pwm_set_duties(uint32_t *duties);					  //设置所有通道的占空比,设置好后需要调用pwm_start才可生效。
esp_err_t pwm_set_phase(uint8_t channel_num, int16_t phase);	//设置PWM通道的相位,设置好后需要调用pwm_start才可生效。
esp_err_t pwm_set_phases(int16_t *phases);					  //设置所有通道的相位,设置好后需要调用pwm_start才可生效。
esp_err_t pwm_get_phase(uint8_t channel_num, uint16_t *phase_p);//获得一个PWM通道的相位。
esp_err_t pwm_set_period_duties(uint32_t period, uint32_t *duties);//设置每个PWM通道的PWM周期和占空比,设置好需要调用pwm_start才可生效。
esp_err_t pwm_set_channel_invert(uint16_t channel_mask);		//设置逆变输出PWM通道。
esp_err_t pwm_clear_channel_invert(uint16_t channel_mask);		//清除逆变输出PWM通道,此函数仅适用于已经处于反向输出状态的PWM通道。

重点函数解析

**esp_err_t pwm_init(uint32_t period, uint32_t duties, uint8_t channel_num, const uint32_t pin_num); //PWM初始化

参数解析
periodPWM周期,单位:us
duties占空比
channel_num通道数
pin_numGPIO管脚号

esp_err_t pwm_set_duty(uint8_t channel_num, uint32_t duty); //设置PWM占空比

参数解析
channel_num通道数,该通道数不可超过pwm_init()初始化中给定的通道数
duty占空比,此处的单位也是us,具体占百分几需要计算,不可超出初始化设定的周期

esp_err_t pwm_start(void); //PWM开始输出

所有针对PWM配置的修改,为了能够生效都得重新开启;


esp_err_t pwm_set_phases(int16_t phase); //设置所有通道的相位

参数解析
phase需要设置的相位

用例:初始占空比为90%,有效电平为高;20s后停止PWM输出,同时拉高PWM通道;10s后将占空比修改为50%

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/queue.h"

#include "esp_log.h"
#include "esp_system.h"
#include "esp_err.h"

#include "esp8266/gpio_register.h"
#include "esp8266/pin_mux_register.h"

#include "driver/pwm.h"

#define PWM_PERIOD      1000
static const char *TAG = "pwm example";
const uint32_t PWM_OUT_IO_NUM = 5;
uint32_t duties = 900;
int16_t phase = 0;

void app_main()
{
    pwm_init(PWM_PERIOD, &duties, 1, &PWM_OUT_IO_NUM);       //PWM的初始化,周期1ms->1KHz,各通道工作周期500us,1条通道,GPIO5
    pwm_set_phases(&phase);                                  //初始相位0
    pwm_start();                                             //开始PWM输出
    int16_t count = 0;

    while (1) {
        if (count == 20) {
            pwm_stop(0x1);                     //此处停止PWM并将引脚变成高电平
            ESP_LOGI(TAG, "PWM stop\n");
        } else if (count == 30) {
            pwm_set_duty(0, 500);              //将占空比改成50%
            pwm_start();                       //使修改占空比生效,需要再次开启
            ESP_LOGI(TAG, "PWM re-start\n");
            count = 0;
        }

        count++;
        vTaskDelay(1000 / portTICK_RATE_MS);
    }
}

运行结果:

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


我的GITHUB

我的个人博客

CSDN

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大大棋

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值