LED 實驗可以說是嵌入式系統設計課程中的「Hello, world!」,所以不免俗地,我們還是要用 mbed 控制 LED 來 say hello 啦!
開始之前
作為本站 mbed 系列教學文章的第一篇,要先跟大家說說這系列文章所採用的實驗環境與硬體,當然,大部份都是可以被其他設備取代的,只是會有些微的不同。
實驗板
這系列文章主要使用 LPC1768 這一個板子,考量的原因有:
- 輕巧
- 穩定
- 可以直接插在麵包板上
- 我手上現有
但這塊板子比較貴,要價將近 2000 台幣,且 I/O 較少,所以你可以選用另一片較低價的 ST Nucleo STM32F401 這個實驗板。它的體積較大,不過 I/O 眾多,且便宜(約 600 台幣)。
當然還有更多的實驗版可以選擇,我只是因為我手上只有這兩片,所以推薦這兩片給各位參考參考。
而關於這兩片板子的內容可以參考先前的文章:ARM mbed 開發 ARM Cortex-M 系列的利器!
操作環境
我在寫這系列文章時所採用的作業環境主要是 MacBook Air ,其他系統的操作方式大同小異,最主要原因是因為他的編譯器採用線上編譯器的關係,因此你只需要準備:
- 可以使用瀏覽器的電腦
- 可以連上網路的電腦
- 至少一個 USB 連接埠
- 支援 mbed 的實驗板
準備好基本設備後,你還需要持續開著 Single.9 這系列的教學文章,然後,接下來我們就可以開始了。
mbed 基本使用方式
這部分我想一樣參考ARM mbed 開發 ARM Cortex-M 系列的利器!這篇文章就可以略知一二了,所以在這我就不花太多時間解釋與描述。
但那篇文章缺少了一個很重要的事情,那就是註冊。
註冊 mbed 帳號
你買回來的 mbed 板子裡面其實有一個 .HTML 的檔案,當你雙點這個檔案後,會進入到 mbed 的登入畫面,若你有帳號的話,請在左邊輸入完資料後就可以登入到 mbed 的雲端編譯器,並將 LPC1768 設為你目前所使用的板子。
若沒有帳號,請點選右側的 SIGNUP 進行註冊。
這邊也選右側的 No, I haven’t created an account before.
填寫好資料,並到信箱收取驗證信啟用之後,你的雲端 compiler 就可以使用啦!
OK,看到這,我相信你應該躍躍欲試了吧?什麼?沒有?好吧,那你可以左轉出去了,這篇文章可能不大適合你…XD
無論如何,我想要藉由一些基本的實驗與控制,讓你可以逐步了解 mbed 所帶來的威力,並且掌握 LPC1768 這個實驗板的應用。
基礎實驗 – LED 控制
LPC1768 上有四顆可以讓使用者自定義的 LED ,今天我們的實驗非常簡單,就是想辦法讓這四顆 LED 亮起來,並且讓它各種閃爍或跑起來~
LED 閃爍
不想說太多,我們先上第一部份的程式碼
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
#include "mbed.h" DigitalOut myled0(LED1); DigitalOut myled1(LED2); DigitalOut myled2(LED3); DigitalOut myled3(LED4); int main() { while(1) { myled0 = 1; myled1 = 1; myled2 = 1; myled3 = 1; wait(0.1); myled0 = 0; myled1 = 0; myled2 = 0; myled3 = 0; wait(0.1); } } |
這一個範例程式很簡單的就只是讓 4 個 LED 亮起與滅掉而已,接下來講講它的運作方式。
mbed 是用 C++ 作為它的開發語言,所以在這邊不叫函式(function)而是方法(method),而既然是方法,就有使用的方式,而這邊目前用到的方法則是下面這幾個。
首先,你會看到開頭不久宣告的DigitalOut
這個物件,它是用來控制各個被你所指定的 I/O 腳的物件,使用方式:
1 2 3 4 5 |
// 格式 DigitalOut oo_name(pin_name); // 範例 DigitalOut myled0(LED1); |
以範例來說,這樣你就為被定義為 LED1 的腳位命名成 myled0,並且將腳位設定為輸出腳。這樣的語法設計雖然在程式開始時會比較繁瑣,但因為 ARM 原始語法的設定非常繁雜,不能像是在寫 8051 那樣直接用 define 的方式去定義,所以這已經是簡化非常多的版本了。
再來是wait(0.1)
這個小小的方法,其實相等於你常見到的delay(0.1)
,他語法的設計是這樣的:
1 2 3 4 5 |
// 浮點數:秒 wait(fload s) // 整數:毫秒 wait(int ms) |
所以在這個範例中,是等待 0.1 秒,也就是 100 毫秒的意思。
執行結果
跑馬燈
常見的另外一種 LED 控制,這個執行結果就是,你會看到燈號一直在往特定方向延伸。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
#include "mbed.h" DigitalOut myled0(LED1); DigitalOut myled1(LED2); DigitalOut myled2(LED3); DigitalOut myled3(LED4); void port4bit_LED(char portin) { myled0 = portin; myled1 = portin>>1; myled2 = portin>>2; myled3 = portin>>3; } int main() { int count = 0, port = 0; while(1) { port = 0x01; for(count = 0;count < 4;count++) { port4bit_LED(port); port <<= 1; wait(0.1); } } } |
DigitalOut 的部份就不多說了,在這邊我們新增了一個 port4bit_LED()
函式,主要用來決定哪一個 LED 該亮起來。
這不份的講解稍為複雜一些,先從位移(shift)這個概念說起。
在 mbed 的 C 語言中 port <<= 1
表示的是 port = port << 1
的縮寫。
意思是說,將 port 這個變數的內容像左移 1 位,也就是乘 2 的意思,不過在這裡是乘 2 加 1,也就是會自動補 1 進來的意思,整個運作方式如圖解一樣(圖片中的移位其實是位移)。
這是 port
這變數在 while(1)
迴圈中所做的事情,而執行完四遍後,port
會再從 0x01 開始。而 port
這變數在這裡是做為資料傳遞的角色,從最低位元(LSB)到第三個位元分別對應到:
變數資料位元 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
對應LED | – | – | – | – | LED 4 | LED 3 | LED 2 | LED 1 |
接下來再來講講 port4bit_LED()
函式在幹些什麼事情。
因為嵌入式系統中的單一腳位控制有個有趣的特性,就是他只讀取一長串位元中的最低位元(LSB),所以我們只要把這串燈號顯示資料對應到相對的 LED 上就可以很快的顯示出我們要的結果。在這裡,我們也採用與剛剛相同的位移方式來達成目標。只不過這次是向右分別移1、2、3個位元,這樣就能達到操作對應位元上的 LED 了!
執行結果
P.S. 本系列文章每週一出文,偶爾會休刊,但(應該)不會富奸
so cool!
好文太晚看到