在上一篇教學文章中,我們學會了如何操作 mbed LPC1768 這個板子上面的四顆 LED 燈號。今天這篇文章,則是要來教各位利用 LPC1768 上的 GPIO (General purpose input output, GPIO) 來做簡單的周邊控制。
開始之前
除了必備的 mbed LPC1768 之外,你還需要…
- 麵包板一塊
- LED 八顆
- 按鈕開關八個
為什麼是八個呢? 因為一個位元組是由八個位員組成的關係,這樣可以順便呼應上一篇文章所提到的位移的內容。不過如果你懶的話,可以只使用一半,也就是四顆來作實驗就可以。
基礎實驗 – GPIO 控制
事實上,前一篇所講的 LED 控制就是一種 GPIO 的應用,只不過他是預先裝在板子上面的 LED 而不是自己外接的。而接下來所要講的,則是要自己動手接線路來實作的控制。
mbed LPC1768 的板子大小恰好可以插到麵包板上,並且留有左右各一排的位置可供接線使用,所以,用力把板子插到麵包板上,我們準備進行實驗囉!
上面這是 LPC1768 的腳位圖,我們今天會用到藍色標籤的部分。
GPIO 單腳 LED 輸出
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
#include "mbed.h" DigitalOut LED(p5) main() { while(1) { LED = 0; wait(0.1); LED = 1; wait(0.1); } } |
一開始我們先從最簡單的單腳控制來做,這邊我把 mbed LPC1768 的 p5 腳位給了一個名字 LED,然後只做一個很簡單的事情,閃爍。
GPIO 多腳 LED 輸出 – DigitalOut
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
#include "mbed.h" DigitalOut LED1(p5) DigitalOut LED2(p6) DigitalOut LED3(p7) DigitalOut LED4(p8) main() { while(1) { LED1 = 0; LED2 = 0; LED3 = 0; LED4 = 0; wait(0.1); LED1 = 1; LED2 = 1; LED3 = 1; LED4 = 1; wait(0.1); } } |
p5 ~ p8 分別被命名為 LED1 ~ LED4,這是模仿上一篇文章的程式內容,動作模式也是閃爍,只不過這次是四顆 LED 閃爍。
GPIO 多腳 LED 輸出 – BusOut
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
#include "mbed.h" BusOut LEDs(p5, p6, p7, p8, p9, p10, p11, p12); main() { while(1) { LEDs = 0x00; wait(0.1); LEDs = 0xFF; wait(0.1); } } |
有一位新角色在這裡初登場,先前我們都是使用 DigitalOut
來做輸出腳位與名稱的指定,但當你要指定的同時輸出腳位有 4 個以上時,這就會是一個非常煩人的事情。還好,mbed 有提供一個 BusOut
的物件可以解決這個問題。它除了可以讓你不用一直複製貼上外,還能快速指定輸出的內容,就像範例程式呈現的那樣。
還記得上一篇文章對於 port 的解釋時的表格嗎? 在這裡也可以用同樣的方式去看。
LEDs | LED1 | LED2 | LED3 | LED4 | LED5 | LED6 | LED7 | LED8 |
對應腳位 | p5 | p6 | p7 | p8 | p9 | p10 | p11 | p12 |
如果你想看更細節的 BusOut
動作,可以用下面這個範例程式。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
#include "mbed.h" BusOut LEDs(p5, p6, p7, p8, p9, p10, p11, p12); main() { while(1) { for(int i=0; i<16; i++) { LEDs = i; wait(0.1); } } } |
GPIO 按鍵輸入 – DigitalIn
講完了輸出後,接下來我們即將進入輸入的部份。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
#include "mbed.h" DigitalIn press(p21); DigitalOut LED(LED1); int main() { while(1) { if(press) { LED = !LED; } wait(0.1); } } |
這裡出現了一位新的角色 DigitalIn
,他主要是將某一個腳位設成輸入腳位,這樣就能夠讓 mbed LPC1768 接收到外來的訊號,而不只是在內部自嗨。
在這個範例程式中,我們指定 p21
腳位為一個輸入腳,然後接上一個按鈕,這個按鈕只需要一端接上正電,另一端接到 LPC1768 的 p21
腳位即可。
當你按下按鈕時 LPC1768 上的 LED1 燈號會亮起,再點下一次便會熄滅,嘿!你的 LPC1768 可以接收到來自外界的訊號啦!
GPIO 按鍵輸入 – BusIn
既然有 BusOut
當然會有 BusIn
囉。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
#include "mbed.h" BusIn Buttons(p21, p22, p23, p24, p25, p26, p27, p28); BusOut LEDs(p5, p6, p7, p8, p9, p10, p11, p12); int main() { while(1) { LEDs = Buttons; } } |
這個程式是一個 BusIn
對應到 BusOut
的實驗,當你接好線路並按下按鈕時,就會看到相對應位置的 LED 亮起,對應關係可以透過下面的表格來對照。
按鍵 | p21 | p22 | p23 | p24 | p25 | p26 | p27 | p28 |
LED | p5 | p6 | p7 | p8 | p9 | p10 | p11 | p12 |
這個範例程式與對應關係的實驗應該可以讓你對 BusIn
和 BusOut
有更初步的了解。
InOut 合一
上述的所有範例都只是單方向的輸出或輸入,但 mbed 的能力不止如此。他還提供了兩個很有趣的物件,分別是 DigitalInOut
、 BusInOut
。從字面上的意思可以很快的了解到,這是一個將輸出入合併在同一個或多個宣告的腳位上。
也就是說,特定的腳位在某些時候,你可以將他設為輸出,而在某些時候,你可以將他設為輸入,很有趣對吧? 接下來讓我們來看看範例程式。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
#include "mbed.h" DigitalOut led(LED1); DigitalInOut pin(p5); int main() { while(1) { pin.output(); // 設為輸出 pin = 1; wait(1.0); pin = 0; // 重置為 0 wait(0.1); pin.input(); // 設為輸入 while(!pin) led = !led; wait(1.0); } } |
這邊直接看影片會比較清楚。
在影片中前半段的小問題是因為我程式中的 1 秒延遲造成的,後面你就會看到我按下按鍵時,LPC1768 上的 LED1 燈號會亮起,然後 1 秒後滅掉,接著是按鈕上方的 LED 亮起、滅掉,之後就重複一樣的動作。在這裡的按鈕與 p5 腳位式接在一起的,你可以從畫面中看到,只有一條線接到按 LPC1768 上。
至於每次我按按鈕時 LED 都會亮起一次,那是電路接線上的關係。因為我的按鈕是接在按下時通正電的狀態,而 LED 則是有正電進入時會亮起。
BusInOut
的動作原理差不多,只差在他是一次可以接收或輸出好幾個這樣。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
#include "mbed.h" DigitalOut led(LED1); DigitalInOut pins(p5, p6, p7); int main() { while(1) { pins.output(); // 設為輸出 pins = 0x03; // p6, p7 輸出 wait(1.0); pins = 0x00; // 重置為 0 wait(0.1); pins.input(); // 設為輸入 if(pins == 0x06) // 如果 p5, p6 被按下 led = !led; wait(1.0); } } |
總結
GPIO 控制是嵌入式系統開發中非常重要的一個部份,透過 GPIO 控制,嵌入式系統才能與我們人類作更多互動,例如本次範例使用的按鍵以及 LED 顯示。當然 GPIO 並不只侷限在於按鍵的輸入與 LED 的顯示,他還可以讓你控制諸如馬達、電燈、繼電器…等等需要開關的東西,也能夠接收來自不同訊號模組的資料,並透過嵌入式系統處理器處理後,再透過 GPIO 本身做你所想要的動作。
簡單來說 GPIO 是嵌入式系統核心晶片接收與傳遞他本身以外的訊息的一個方式,就如我們人類的神經系統那樣。
回到 mbed , mbed 最有趣的地方是他的 GPIO 設定並不會非常死板,你可以很自由的把某幾隻接腳透過 BusIn/BusOut 群組起來操作,你也可以透過 InOut 合一的物件,對同一個 I/O 腳位做輸出入的控制,很酷對吧?
其實關於 GPIO 還有更多的操作與使用方式,不過這屬於比較進階的操作,在本系列文章中就不去加以介紹。如果你有興趣,可以到官方網站上查看更多資料。
- mbed Handbook Digital I/O: https://developer.mbed.org/handbook/Homepage#digital-i-o