ESP32学习11:PWM
一、PWM簡介
? ? ? ? PWM 是 Pulse Width Modulation 的縮寫,中文意思就是脈沖寬度調制,簡稱脈寬調制。它是利用微處理器的數字輸出來對模擬電路進行控制的一種非常有效的技術,其控制簡單、靈活和動態響應好等優點而成為電力電子技術最廣泛應用的控制方式,其應用領域包括測量,通信,功率控制與變換,電動機控制、伺服控制、調光、開關電源,甚至某些音頻放大器,因此學習 PWM 具有十分重要的現實意義。
? ? ? ? 其實我們也可以這樣理解,PWM 是一種對模擬信號電平進行數字編碼的方法。通過高分辨率計數器的使用,方波的占空比被調制用來對一個具體模擬信號的電平進行編碼。PWM 信號仍然是數字的,因為在給定的任何時刻,滿幅值的直流供電要么完全有(ON),要么完全無(OFF)。電壓或電流源是以一種通(ON)或斷(OFF)的重復脈沖序列被加到模擬負載上去的。通的時候即是直流供電被加到負載上的時候,斷的時候即是供電被斷開的時候。只要帶寬足夠,任何模擬值都可以使用 PWM 進行編碼。
PWM 對應模擬信號的等效圖,如下所示:
? ? ? ? 從圖中可以看到,上圖 a 是一個正弦波即模擬信號,b 是一個數字脈沖波形即數字信號。我們知道在計算機系統中只能識別是 1 和 0,對于單片機,要么輸出高電平(3.3V),要么輸出低電平(0),假如要輸出 1.5V 的電壓,那么就必須通過相應的處理,比如本章所要講解的 PWM 輸出,其實從上圖也可以看到,只要保證數字信號脈寬足夠就可以使用 PWM 進行編碼,從而輸出 1.5V 的電壓。
? ? ? ? 個人理解的PWM脈寬調制:以LED燈亮度說明PWM脈寬調制。其實對于單片機來說,其輸出的狀態只有0和1兩種,因此對于燈泡來說,也應該只有亮滅兩種狀態,不應該有亮度區分之說。比如我們有一個占空比為50%的周期2秒鐘的PWM脈沖,那么看到的現線就應該是LED燈亮1秒鐘,然后又熄滅1秒鐘,并周而復始。同理,如果占空比分別為25%及75%,其表現出來的狀態也應該是亮滅時間上的不同,不會有亮度的不同,實際其實就是這樣的。但是,如果我們調快頻率,快到人眼分辨不出的時候,我們真是看到的現線是,LED燈一直亮著,只是占空比25%時燈光最暗,其次是50%,最亮是75%。這是因為我們人眼的視覺暫留現線,我們會覺得LED燈一直亮著,但是25%占空比時,一個周期內燈光滅的時間長,因此,其亮度最暗,因此,我們利用PWM脈寬調制,可以模擬出任何數值的電壓。
?二、ESP32控制LED燈亮度
? ? ? ? ?根據上一節提到的PWM脈寬調制原理,我們利用ESP32,控制輸出脈沖的占空比,就可以控制LED燈的亮度。
?ESP32的PWM(ledc)接口介紹:
- LEDC 配置函數:ledc_channel_config();
| 函數原型? | esp_err_t? ledc_channel_config ( ? ? const ledc_channel_config_t* ledc_conf ) |
| 函數功能 | LEDC配置函數 |
| 參數 | [in] ledc_conf:?ledc 配置結構體 ledc_channel_config_t ? ? uint32_t duty; //占空比 |
| 返回值 | ESP_OK:成功 ESP_ERR_INVALID_ARG : 參數錯誤 |
- ?LEDC 漸變安裝函數:ledc_fade_func_install();
| 函數原型 | esp_err_t ledc_fade_func_install ( ? ? int intr_alloc_flags ) |
| 函數功能 | LEDC 漸變安裝使能函數 |
| 參數 | [in] intr_alloc_flags:分配中斷標記 |
| 返回值 | ESP_OK:成功 ESP_ERR_INVALID_ARG : 參數錯誤 |
?LEDC 漸變函數:ledc_set_fade_with_time();
| 函數原型 | 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 ) |
| 函數功能 | LEDC 漸變函數 |
| 參數 | [in] speed_mode:速度 [in] channel:通道 [in] target_duty:目標占空比 [in] max_fade_time_ms:到達目標占空比需要的時間 |
| 返回值 | ESP_OK:成功 ESP_ERR_INVALID_ARG : 參數錯誤 ESP_ERR_INVALID_STATE:LEDC 漸變未安裝 ESP_FAIL:LEDC 漸變安裝失敗 |
- ?LEDC 漸變開始函數:ledc_fade_start();
| 函數原型 | esp_err_t ledc_fade_start ( ? ? ?ledc_mode_t speed_mode, ? ? ?ledc_channel_t channel, ? ? ?ledc_fade_mode_t wait_done ) |
| 函數功能? | LEDC 漸變開始函數 |
| 參數? | [in] speed_mode:速度 [in] channel:通道 [in] wait_done:是否等待 |
| 返回值? | ESP_OK:成功 ESP_ERR_INVALID_ARG : 參數錯誤 ESP_ERR_INVALID_STATE:LEDC 漸變未安裝 |
三、程序編寫:
?PWM控制LED亮度.h文件內容:
#ifndef COMPONENTS_MYPWM_INCLUDE_MYPWM_H_ #define COMPONENTS_MYPWM_INCLUDE_MYPWM_H_#include <stdio.h> #include "esp_system.h" #include "esp_wifi.h" #include "esp_event_loop.h" #include "esp_log.h" #include "esp_err.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "driver/ledc.h"#define LED_R 2 //LED的GPIO接口 #define LEDC_MAX_DUTY (8191) //2的13次方-1(13位PWM) #define LEDC_FADE_TIME (1000) //漸變時間(ms)//LEDC配置結構體 extern ledc_channel_config_t g_ledc_ch_R;void ledc_init(void);#endif /* COMPONENTS_MYPWM_INCLUDE_MYPWM_H_ */?PWM控制LED亮度.c文件內容:
#include "mypwm.h"ledc_channel_config_t g_ledc_ch_R; //PWM配置結構體/* * void ledc_init(void):定時器0用在PWM模式,輸出3通道的LEDC信號 * @param[in] void :無 * @retval void :無 */ void ledc_init(void){/*** 定時器參數配置結構體**/ledc_timer_config_t ledc_timer={.duty_resolution = LEDC_TIMER_13_BIT, //PWM分辨率.freq_hz = 5000, //頻率.speed_mode = LEDC_HIGH_SPEED_MODE, //速度.timer_num = LEDC_TIMER_0, //選擇定時器};ledc_timer_config(&ledc_timer); //設置定時器PWM模式//PWM通道0配置->IO2->紅色燈g_ledc_ch_R.channel = LEDC_CHANNEL_0; //PWM通道g_ledc_ch_R.duty = 0; //占空比g_ledc_ch_R.gpio_num = LED_R; //IO映射g_ledc_ch_R.speed_mode = LEDC_HIGH_SPEED_MODE; //速度g_ledc_ch_R.timer_sel = LEDC_TIMER_0; //選擇定時器ledc_channel_config(&g_ledc_ch_R); //配置PWM//使能ledc漸變功能ledc_fade_func_install(0); //注冊LEDC服務,參數標志是否容許中斷 }??PWM控制LED亮度main.c函數內容:
void app_main(void) {ledc_init();while(1){//ledc 紅燈漸變至100%,時間LEDC_FADE_TIMEledc_set_fade_with_time(g_ledc_ch_R.speed_mode,g_ledc_ch_R.channel,LEDC_MAX_DUTY,LEDC_FADE_TIME);//漸變開始ledc_fade_start(g_ledc_ch_R.speed_mode,g_ledc_ch_R.channel,LEDC_FADE_NO_WAIT);//延時LEDC_FADE_TIME,給LEDC控制時間vTaskDelay(LEDC_FADE_TIME / portTICK_PERIOD_MS);//ledc 紅燈 漸變至0%,時間LEDC_FADE_TIMEledc_set_fade_with_time(g_ledc_ch_R.speed_mode,g_ledc_ch_R.channel,0,LEDC_FADE_TIME);//漸變開始ledc_fade_start(g_ledc_ch_R.speed_mode,g_ledc_ch_R.channel,LEDC_FADE_NO_WAIT);//延時LEDC_FADE_TIME,給LEDC控制時間vTaskDelay(LEDC_FADE_TIME / portTICK_PERIOD_MS);} }四、結束
? ? ? ? 本文介紹了PWM脈寬調制的內容,并通過PWM實現LED呼吸燈。
總結
以上是生活随笔為你收集整理的ESP32学习11:PWM的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 0343基于STM32单片机的茶园大棚环
- 下一篇: 【随笔】7月休假:粤港澳大湾区旅程记录