在上一篇教學文章中,我們學會了如何操作 mbed LPC1768 這個板子上面的四顆 LED 燈號。今天這篇文章,則是要來教各位利用 LPC1768 上的 GPIO (General purpose input output, GPIO) 來做簡單的周邊控制。
除了必備的 mbed LPC1768 之外,你還需要…
為什麼是八個呢? 因為一個位元組是由八個位員組成的關係,這樣可以順便呼應上一篇文章所提到的位移的內容。不過如果你懶的話,可以只使用一半,也就是四顆來作實驗就可以。
事實上,前一篇所講的 LED 控制就是一種 GPIO 的應用,只不過他是預先裝在板子上面的 LED 而不是自己外接的。而接下來所要講的,則是要自己動手接線路來實作的控制。
mbed LPC1768 的板子大小恰好可以插到麵包板上,並且留有左右各一排的位置可供接線使用,所以,用力把板子插到麵包板上,我們準備進行實驗囉!
上面這是 LPC1768 的腳位圖,我們今天會用到藍色標籤的部分。
#include "mbed.h"
DigitalOut LED(p5)
main()
{
while(1)
{
LED = 0;
wait(0.1);
LED = 1;
wait(0.1);
}
}
一開始我們先從最簡單的單腳控制來做,這邊我把 mbed LPC1768 的 p5 腳位給了一個名字 LED,然後只做一個很簡單的事情,閃爍。
#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 閃爍。
#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
動作,可以用下面這個範例程式。
#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);
}
}
}
講完了輸出後,接下來我們即將進入輸入的部份。
#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 可以接收到來自外界的訊號啦!
既然有 BusOut
當然會有 BusIn
囉。
#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
有更初步的了解。
上述的所有範例都只是單方向的輸出或輸入,但 mbed 的能力不止如此。他還提供了兩個很有趣的物件,分別是 DigitalInOut
、 BusInOut
。從字面上的意思可以很快的了解到,這是一個將輸出入合併在同一個或多個宣告的腳位上。
也就是說,特定的腳位在某些時候,你可以將他設為輸出,而在某些時候,你可以將他設為輸入,很有趣對吧? 接下來讓我們來看看範例程式。
#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
的動作原理差不多,只差在他是一次可以接收或輸出好幾個這樣。
#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 還有更多的操作與使用方式,不過這屬於比較進階的操作,在本系列文章中就不去加以介紹。如果你有興趣,可以到官方網站上查看更多資料。