類比模擬輸出

學習瞭如何使用 ESP32 的 LED PWM 控制器和 Arduino IDE 來調暗 LED。

通過為信號設置正確的屬性,學到的概念可用於通過 PWM 控制其他輸出。

如何配置 ESP32 的 PWM 通道

如果你了解Arduino Uno編程,你一定看到Arduino相關板在Arduino IDE中使用analogWrite函數生成PWM。但是在 Arduino IDE 中使用不同的函數為 ESP32 產生 PWM 信號。按照以下步驟設置所有脈寬調製通道的參數:


現在讓我們看看如何在 PWM 庫中設置這些參數。為此使用了三個函數。

基本控制-1

int PWM_FREQUENCY = 1000; // 此變量用於定義頻率int PWM_CHANNEL = 0; // 此變量用於選擇通道號 int PWM_RESOUTION = 8; // 這將定義信號的分辨率,在這種情況下為 8 int GPIOPIN = 15 ; // 我們要將此通道信號附加到的 GPIO int dutyCycle = 127; // 它將定義信號的寬度 
void setup(){ledcSetup(PWM_CHANNEL, PWM_FREQUENCY, PWM_RESOUTION);ledcAttachPin(GPIOPIN, PWM_CHANNEL);}
void loop() {ledcWrite(PWM_CHANNEL, dutyCycle);}

基本控制-說明

這是生成佔空比為 50% 的脈寬調製信號的簡單代碼。在這些程序行中,我們定義了波形的參數。首先我們定義 1000 赫茲的頻率。我們選擇了通道零。但是您可以從總共 16 個頻道中選擇您想要的任何頻道。之後,我們指定了 8 位的分辨率。但是您可以選擇您想要的任何分辨率。我們將使用通用輸入輸出引腳 15 來獲得輸出。在初始化部分的最後,我們將佔空比設置為 127。在這個例子中,我們得到一個具有固定佔空比的波形。
int PWM_FREQUENCY = 1000; int PWM_CHANNEL = 0;int PWM_RESOUTION = 8; int GPIOPIN = 15 ; int dutyCycle = 127;
現在在 setup 函數中,我們需要使用我在上面解釋過的兩個函數 ledcSetup 和 ledcAttach。第一個程序將選擇通道零以及 1000 赫茲的頻率和 8 位的分辨率。使用 8 位分辨率,我們可以指定 0 和 (2^8-) = 255 之間的佔空比。因此,如果我們使用 255 作為佔空比參數,則佔空比將為 100%,而 127 佔空比將為 50%其他值也類似。第二個語句將脈寬調製通道零附加到數字引腳十五。
ledcSetup(PWM_CHANNEL, PWM_FREQUENCY, PWM_RESOUTION);ledcAttachPin(GPIOPIN, PWM_CHANNEL);在循環函數內部,我們僅使用指令生成佔空比為 127 的信號,您將看到它將生成佔空比為 50% 的信號。波形將有一半時間為高電平,一半時間為邏輯低電平,總時間段將與信號頻率成反比。所以這個 ledcWrite 函數用於產生具有特定佔空比的 PWM 信號。您只需要定義通道號和占空比值作為該函數的參數。
ledcWrite(PWM_CHANNEL, dutyCycle);因此,當您將此代碼​​上傳到您的電路板並通過 PIN 15 連接示波器時,您將獲得哪種類型的信號作為輸出?
您將看到具有以下參數的數字波形:頻率 = 1000 赫茲時間段 = 1 毫秒佔空比 = 50%準時 = 0.5 毫秒關閉時間 = 0.5 毫秒

ESP32 可變佔空比 PWM

int PWM_FREQUENCY = 1000; int PWM_CHANNEL = 0; int PWM_RESOUTION = 8; int GPIOPIN = 15 ; 
void setup(){ledcSetup(PWM_CHANNEL, PWM_FREQUENCY, PWM_RESOUTION);ledcAttachPin(GPIOPIN, PWM_CHANNEL);}
void loop() {for (int dutyCycle = 0; dutyCycle <= 255; dutyCycle++) {ledcWrite(PWM_CHANNEL, dutyCycle);delay(100);}}

如果您對脈寬調製的概念不清楚,您一定想知道可變佔空比信號是什麼意思?可變佔空比意味著我們希望在輸出端有數字波形,其占空比會隨著一些延遲從低值增加到高值。例如,當我們打開開發板時,最初的佔空比為零,然後它會開始以 1 的步長增加,並有一些延遲。完成這項任務非常容易。您只需要更改 ledcWrite 函數內的佔空比值。所以我們在最後一個例子中使用的其餘代碼將保持不變,除了可變佔空比部分而不是修復。此處給出了此示例的代碼。

除了循環功能部分外,代碼與上一個程序類似。在循環部分內部,使用了另一個 for 循環。在 for 循環內部,佔空比的起始值為零,並且隨著 for 循環的每次迭代,其值以 1 的增量遞增。每次迭代都在 100 毫秒的延遲後發生。因此,您將在示波器上觀察脈衝寬度遞增的信號。您可以在這些不同脈衝寬度的圖片中看到結果。


基本控制-2

/* * 要設置 LED 的亮度,您只需要使用 ledcWrite() 接受生成信號的通道和占空比作為參數的函數* 由於我們使用 8 位分辨率,因此將使用 0 到 255 之間的值控制佔空比。* 請注意,在 ledcWrite() 我們使用生成信號的通道,而不是 GPIO。*/// the number of the LED pin(定義 LED 連接到的引腳)const int ledPin = 4; // 4 對應於 GPIO 4
// setting PWM propertiesconst int freq = 5000; //定義 5000 Hz 的頻率(數值越大時間越長)const int ledChannel = 0; //選擇通道 0 來生成信號const int resolution = 8; //將分辨率設置為 8 位 void setup(){  //定義的屬性配置 LED PWM ledcSetup() 接受 ledChannel、頻率和分辨率作為參數的函數  ledcSetup(ledChannel, freq, resolution);    // 接受您想要獲取信號的 GPIO 以及生成信號的通道作為參數的函數  ledcAttachPin(ledPin, ledChannel);} void loop(){  // 在循環中,您將在 0 和 255 之間改變佔空比以增加 LED 亮度  for(int dutyCycle = 0; dutyCycle <= 255; dutyCycle++){       //透過 PWM 改變 LED 亮度    ledcWrite(ledChannel, dutyCycle);    delay(15);  }
  // 降低 LED 亮度 在 255 和 0 之間降低亮度  for(int dutyCycle = 255; dutyCycle >= 0; dutyCycle--){    // 透過 PWM 改變 LED 亮度    ledcWrite(ledChannel, dutyCycle);       delay(15);  }}

進階控制

在不同的 GPIO 上獲得相同的信號

// LED 引腳數量const int ledPin = 4;  // 4 對應於 GPIO 4const int ledPin2 = 0; // 0 對應於 GPIO 0const int ledPin3 = 2;  // 2 對應於 GPIO 2
// 設定 PWM 屬性const int freq = 5000;const int ledChannel = 0;const int resolution = 8; void setup(){   // 配置 LED PWM 功能  ledcSetup(ledChannel, freq, resolution);    // 將通道連接到要控制的GPIO  ledcAttachPin(ledPin, ledChannel);  ledcAttachPin(ledPin2, ledChannel);  ledcAttachPin(ledPin3, ledChannel);} void loop(){   // 增加LED亮度  for(int dutyCycle = 0; dutyCycle <= 255; dutyCycle++){      // 透過 PWM 改變 LED 亮度    ledcWrite(ledChannel, dutyCycle);    delay(15);  }
  //降低 LED 亮度  for(int dutyCycle = 255; dutyCycle >= 0; dutyCycle--){    // 透過 PWM 改變 LED 亮度    ledcWrite(ledChannel, dutyCycle);       delay(15);  }}