【單片機入門】(四)應用層軟體開發的單片機學習之路-esp32開發板pwm控制電機以及中斷的使用

【單片機入門】(四)應用層軟體開發的單片機學習之路-esp32開發板pwm控制電機以及中斷的使用

本課程的最後是做一個紅外遙控的智能小車

最后更新 2022/10/31 下午10:49
陈显达
预计阅读 8 分钟
分类
分享
标签
硬體相關

本文由網友投稿。

作者:陳顯達

原文標題:【單片機入門】(四)應用層軟體開發的單片機學習之路-----esp32 開發板 pwm 控制電機以及中斷的使用

原文連結:https://www.cnblogs.com/1996-Chinese-Chen/p/16846218.html

引言

各位大佬,晚上好啊,在上一篇博客中,我們講了什麼是 uart 串口通訊,以及使用 usb 轉 ttl 使得單片機可以和 c#上位機做一個串口通訊,接下來,為大家帶來 pwm 的概念原理,以及實際案例,使用 pwm 對電機進行速度調製,因為本課程的最後是做一個紅外遙控的智能小車,所以是需要電機四個,驅動四個,輪胎四個,所以 pwm 對於最後的成果也是極為重要,並且在實際開發中,pwm 也是比較常用的調速方式。

概念

pwm 全稱 pulse width modulation,中文翻譯為脈衝寬度調製,其基本原理為控制方式就是對逆變電路開關器件的通斷進行控制,使輸出端得到一系列幅值相等但寬度不一致的脈衝,用這些脈衝來代替正弦波或所需要的波形。也就是在輸出波形的半個周期中產生多個脈衝,使各脈衝的等值電壓為正弦波形,所獲得的輸出平滑且低次諧波少。按一定的規則對各脈衝的寬度進行調製,既可改變逆變電路輸出電壓的大小,也可改變輸出頻率。

可能上面對於原理的解釋過於官方,大家可能看不懂,通俗易懂的來說,就是通過對電子元器件的電路進行高低電平進行控制,在一段時間內,高低電平在輸出會形成一段波動,這個波動可以成為 pwm 波形,而我們需要使用代碼去控制 pwm 的輸出波形,高電平在這一段波動中,通電時間即高電平時間是占了總時間多少,同時在這一段 pwm 波形中,高低電平來回切換的頻率又是多少,形成了這麼一段波形,這就引入了兩個概念,占空比(duty ratio)和頻率,占空比代表著,高電平通電總時和總時的一個占比(這段波形中,高低電平的總共占用時間),而頻率則是高低電平在這段波形中,來回切換的一個頻率。

如下圖,下方在 arduino 串口繪圖器中,展示了一段鋸齒波形,看下方的 gif 我們可以看到對應的電機運動也是有快到慢的一個運動狀態。

代碼解析

void setup() {
  Serial.begin(9600);
  ledcSetup(0, 5000, 8);
  ledcAttachPin(12, 0);
}

// the loop function runs over and over again forever
void loop() {
   for (int dutyCycle = 0; dutyCycle <= 255; dutyCycle++) {
    ledcWrite(0, dutyCycle);
    delay(7);
    Serial.println(dutyCycle);
  }
}

在 arduino 中我們可以使用 ledc 來實現對 pwm 的控制,而在純 c 樂鑫的開發板中,是可以使用 mcpwm 進行控制,但是由於 arduino 在此處不能使用 mcpwm,則就有了 ledc 作為替代品,esp32 帶有一個 16 通道的一個 led pwm 控制器,對應使用的是樂鑫的 led pwm 控制,esp32 led pwm,分為 8 路高速通道和 8 路低速通道,然後我們使用不同的頻率,和占空比來實現控制電機轉速的控制。

在上面的代碼中,我們先設置了 ledc 的通道為 0,頻率為 5000,第八個低速 led 控制器,即代碼為 ledcsetup (0, 5000, 8);然後需要將通道和引腳進行管理使用 ledcattachpin(12, 0);將引腳 12 和第 0 個通道關聯起來,在 loop 代碼中,可以看到,我們寫入的最大的占空比為 255,而 0-255 總數為 256,那是因為,占空比是和通道是有關係的,上文提到,led 的 pwm 控制器一共有 16 個,此處我們使用 8,而 256 則為 2 的 8 次方的值,所以占空比最大為 256,如果取值為 10,占空比的最大值則為 1024-1;ledcwrite(0,dutycycle);則是將占空比寫入對應的通道,便完成了 pwm 對電機進行調速設置。

arduino 針對 esp32 樂鑫 pwm 的封裝,目前已知的有 ledc,不需要安裝,默認就可以使用,而其他的也有對於 pwm 的封裝,個人測試了一兩個倒也沒有這個好用,後續各位朋友也可以繼續探索其他好用的 pwm 庫進行開發。

中斷

在上面講完 pwm 之後,我們再來講一下中斷,以及中斷的一個實際案例。中斷,顧名思義,是在程式執行期間,遇到某一個事件的時候,將暫停手上的工作先去執行某一件事情,這個事情則是我們中斷當下工作,去執行的事情,這個動作,稱之為中斷。雖然在代碼中,可以註冊一個後台任務(在純 c 中),進行不停的 while,但是這樣在性能上還是無法發揮單片機的功效,所以這種場景下我們便需要使用中斷,來實現我們的某種功能,例如使用按鈕,來判斷是否需要打開 led,或者是其他的行為。

在 arduino 中,我們可以使用 attachinterrupt 函數來進行對引腳增加中斷以及使用 detachinterrupt 來移除中斷,

attachinterrupt 函數需要三個參數,第一個為中斷需要使用的引腳 pin,第二個為中斷觸發的函數,第三個為中斷的類型,對於 esp32 的中斷,在 arduino 中,其方法名前面必須加一個 iram_attr 標記其為中斷函數,第一個函數中的 digitalpintointerrupt 為將 27 和中斷進行一個綁定,同時還有其他方法,但是官方均不推薦,

在下方的代碼中,我們定義了一個 change 的函數用來處理 esp32 27 引腳的中斷,用 27 引腳的電平控制 led 引腳 2 的電平,以此來控制是否點亮 led 燈,先設置引腳 2 為輸出模式,27 引腳為上拉輸入模式,可以理解為上拉電阻的一般都需要用到這種模式,然後我們將引腳 27 和中斷進行關聯,設置中斷函數為 change,模式為 change。然後在 loop 函數中,我們給引腳 2 寫入 state 的值,當進入 change 中斷函數中,會將 state 取反,然後進入 loop 寫入值。以此實現控制 led 的顯示和不顯示,在這裡,提醒一下,由於在單片機中,中斷以及定時器都是非阻塞模式,而 serial.println 函數是阻塞寫入緩衝區,會導致中斷函數會不斷的輸出錯誤,錯誤:guru meditation error: core 1 panic'ed (interrupt wdt timeout on cpu1).

這是因為 println 函數阻塞導致定時器無法繼續執行,所過非要使用此函數,可以嘗試設置中間變量,然後在 loop 函數中判斷是否改變值,然後進行輸出信息到串口。

可以在下方 gif 看到,我們使用按鈕進行控制 led 的顯示和不顯示。

volatile byte state = LOW;

void IRAM_ATTR change()
{
   state=!state;
}
void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  pinMode(2, OUTPUT);
  pinMode(27, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(27), change, CHANGE);
}

void loop() {
  digitalWrite(2, state);// put your main code here, to run repeatedly:
}

可以看到第二個方法是傳入一個 interrupt 的中斷編號,但是 esp32 上面的中斷編號,不在官方資料中,所以我們只有需要第一個方法來進行引腳和中斷函數的關聯,當然了可能最後一個也是可以,只是此處我沒有嘗試,感興趣的可以進行嘗試,

在 mode 中,arduino 是支持五種模式,第一種為 low,,看翻譯我們知道,這個是在電平處於低電平時會觸發中斷函數,

第二個 change 是不管是高到低,還是低到高,都會觸發

第三種是引腳在由低電平到高電平時觸發,而不是已經到了高電平觸發,

第四種是下降,當電平由高到低時會觸發中斷函數,

第五種是電平處於高電平時會觸發中斷函數。

結語

今天講了 pwm 還有中斷的使用,可能一次性講的有點多,有點難以消化,有什麼不懂的可以及時問我,以及後面我更新的時間會稍微慢一點,防止講的過快,一時間不明白,後面還會有對於 iic,spi 的一個案例講解,在這些講完後,我會開始準備最終極的目標,做一個智能小車,其中會需要的配件,這兩天我會總結好發到群里,以及購買連結。有感興趣的同學可以加 qq 群,一起學習,一起討論,博主也是一個剛開始玩單片機的學徒,後面也會研究 stm32 系列單片機,歡迎大家加入討論,學習。

Keep Exploring

延伸阅读

更多文章
同分类 2025/8/13

推薦一款高性能狀態機管理解決方案

在實際軟體開發中,尤其是工業軟體,每一款設備都有複雜的狀態以及狀態之間的切換的功能需求,在這種情況下,如何管理狀態以及狀態之間切換,和對應狀態下的功能控制,成為非常重要的一個問題。

继续阅读