欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

ESP8266学习历程(4)——PWM

程序员文章站 2022-06-29 08:58:31
...

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初始化

参数 解析
period PWM周期,单位:us
duties 占空比
channel_num 通道数
pin_num GPIO管脚号

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);
    }
}

运行结果:

ESP8266学习历程(4)——PWM
ESP8266学习历程(4)——PWM
ESP8266学习历程(4)——PWM


我的GITHUB

我的个人博客

CSDN

相关标签: IoT入门到实战