ESP8266學習歷程(4)——PWM

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

運行結果:

在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述


我的GITHUB

我的個人博客

CSDN

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章