高通台灣AI黑客松|競賽說明會
|

【Tutorial】Quark SE C1000之GPIO腳位設定技巧

   

作者:曹建國

筆者在「【Tutorial】如何用ISSM開發Intel SE C1000」一文中,提到了安裝Intel System Studio for Microcontroller 開發軟體,編譯與燒錄程式等用法,但是在嵌入式開發版開發,將對應不同的感測模組,接到其GPIO的擴充腳位進行控制。因此,本文要介紹Quark SE C1000開發板(如下圖所示)如何使用GPIO腳位設定技術。

Quark SE C1000開發板盒裝展示(圖/曹建國)

Quark SE C1000開發板正面(圖/曹建國)

Quark SE C1000開發板背面(圖/曹建國)

Quark SE C1000開發板腳位介紹

首先,如下圖所示,我們可以看到Quark SE C1000開發板正面,在開發版兩端各有雙排的2.54 的公頭腳位,下圖右邊紅框是J14的腳位,在紅框左上角紅圈處為J14第一個腳位,依序左右,向下計數一直到最下面右邊腳位,共計有50個腳位。左邊紅框是J15的腳位,紅框左上角紅圈處為J15第一個腳位,依序左右,向下計數一直到最下面右邊腳位,共44個腳位。

Quark SE C1000開發板腳位示意圖:標示腳一(圖/曹建國)

讀者可以從Intel官網所提供的Intel® QuarkTM SE Microcontroller C1000 Development Platform文件裡找到「Quark SE C1000開發板腳位對照表」,我們可以看到其94個腳位(含J14之50個腳位與J15之44個腳位),其中每一個腳位都有各自獨立的用途,由於Intel System Studio for Microcontroller 開發軟體在控制GPIO時,有使用對應的軟體元件,所以每一個軟體元件可以區分為三個功能分類,所以GPIO的控制會區分在三個功能分類所在的元件所控制。

以LED Blink範例解釋腳位的應用

先前的【Tutorial】如何用ISSM開發Intel SE C1000文中,已經提過了LED Blink範例/程式,如下圖紅框所示,我們開啟LED Blink範例程式之後。

開啟LED_Blink範例(圖/曹建國)

接下來如下圖所示,我們可以在紅框處,看到許多的程式,那都是LED Blink範例程式。

已開啟LED_Blink範例專案(圖/曹建國)

如下表所示,我們先看到LED Blink範例程式的內容,我們使用的開發版是Quark SE C1000開發板,所以我們在#define上,我們先看到下表所示的宣告內容。

LED Blink範例程式(LED_Blink)
/*

* Copyright (c) 2017, Intel Corporation

* All rights reserved.

*

* Redistribution and use in source and binary forms, with or without

* modification, are permitted provided that the following conditions are met:

*

* 1. Redistributions of source code must retain the above copyright notice,

*    this list of conditions and the following disclaimer.

* 2. Redistributions in binary form must reproduce the above copyright notice,

*    this list of conditions and the following disclaimer in the documentation

*    and/or other materials provided with the distribution.

* 3. Neither the name of the Intel Corporation nor the names of its

*    contributors may be used to endorse or promote products derived from this

*    software without specific prior written permission.

*

* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS”

* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE

* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE

* ARE DISCLAIMED. IN NO EVENT SHALL THE INTEL CORPORATION OR CONTRIBUTORS BE

* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR

* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF

* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS

* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN

* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)

* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE

* POSSIBILITY OF SUCH DAMAGE.

*/

 

/*

* LED_Blink

*

* This app will blink an LED on the development platform indefinitely.

*

* In order for this application to work correctly on the Intel(R) Quark(TM)

* Microcontroller D2000 Development Platform, jumper J3 must be set to USR.

*/

 

#include “clk.h”

#include “qm_gpio.h”

#include “qm_pinmux.h”

#include “qm_pin_functions.h”

 

/* The following defines the pin and pin mux details for each SoC. */

#if (QUARK_SE)

#define PIN_OUT 25

#define LED_PIN_ID (QM_PIN_ID_59)

#define PIN_MUX_FN (QM_PIN_59_FN_GPIO_25)

#elif(QUARK_D2000)

#define PIN_OUT 24

#define LED_PIN_ID (QM_PIN_ID_24)

#define PIN_MUX_FN (QM_PIN_24_FN_GPIO_24)

#endif

#define DELAY 250000UL /* 0.25 seconds. */

 

static void pin_mux_setup(void)

{

qm_pmux_select(LED_PIN_ID, PIN_MUX_FN);

}

 

int main(void)

{

static qm_gpio_port_config_t cfg;

 

/* Set the GPIO pin muxing. */

pin_mux_setup();

 

/* Set the GPIO pin direction to out and write the config. */

cfg.direction = BIT(PIN_OUT);

qm_gpio_set_config(QM_GPIO_0, &cfg);

 

/* Loop indefinitely while blinking the LED. */

while (1) {                qm_gpio_set_pin(QM_GPIO_0, PIN_OUT);

clk_sys_udelay(DELAY);

qm_gpio_clear_pin(QM_GPIO_0, PIN_OUT);

clk_sys_udelay(DELAY);

}

}

下面這段程式碼,我們因為使用Quark SE C1000開發板,所以我們只需要看『#if (QUARK_SE)』與『#elif(QUARK_D2000)』之間的程式。

接下來我們將表格 1 Quark SE C1000開發板腳位對照表內,有關於QM_PIN_ID_59節錄下來得到下表:

首先,由於我們使用Intel® QMSI GPIO Pin Mapping的功能,我們必須要將PMUX用於控制0~68腳位,透過一組連續的暫存器進行設定,接下來我們要將GPIO 25設為輸出控制,所以我們將使用GPIO 25 指定為輸出,可以看到:#define PIN_OUT 25

而GPIO 25參考上表,又為『QM_PIN_ID_59』,需要用到實際運用的QM原件來管理腳位,請將實際的QM_PIN_ID_59 ,透過define來設定為LED_PIN_ID,可以看到:#define LED_PIN_ID (QM_PIN_ID_59)

接下來我們要用到PMUX的功能,需先宣告腳位的 PMUX功能:#define PIN_MUX_FN (QM_PIN_59_FN_GPIO_25)

也就是將GPIO 25代表QM_PIN_59的功能腳位,所以我們宣告PIN_MUX_FN為(QM_PIN_59_FN_GPIO_25)。

接下來因為我們用到Intel® QMSI GPIO Pin Mapping的功能,我們必須要將PMUX進行腳位初始化設定,這須要有一個固定該有得函數pin_mux_setup(),所以我們宣告的下列函式:

 

static void pin_mux_setup(void)

{

qm_pmux_select(LED_PIN_ID, PIN_MUX_FN);

}

由上表所示,我們使用Intel® QMSI GPIO Pin Mapping的功能,用qm_pmux_select()函式,告訴系統將LED_PIN_ID(即是QM_PIN_ID_59)設定為PIN_MUX_FN的功能,那系統將會知道它用到GPIP 25,也就是QM_PIN_59。

Main主程式解釋

接下來,我們要解釋主程式main()的內容,下表為主程式內容:

一般而言,在Arduino程式開發之中,我們必須要先做GPIO腳位設定:pinMode(腳位,輸入或輸出);在這裡我們需要用 pin_mux_setup() 來替代這個指令,而pin_mux_setup()這個函式,上面已經介紹過了,不再多敘述。

GPIO腳位輸入輸出設定

除了上面的腳位狀態設定後,我們仍需要告訴系統,讓系統知道其腳位是否是輸出或輸入。這裡Intel® QMSI GPIO Pin Mapping的功能,是將所有GPIO腳位的輸出或輸入變成一個32bits的狀態暫存器,而這個32bits的暫存器必須要一次全部給Intel® QMSI GPIO Pin Mapping,所以我們先行宣告這個32bits的狀態暫存器,如下所示:static qm_gpio_port_config_t cfg;

所以cfg就是32bits的狀態暫存器。接下來就是要宣告GPIO 25(第25號腳位)為輸出,所以我們將設定cfg這個結構的direction,如下所示:

     cfg.direction = BIT(PIN_OUT);

BIT(PIN_OUT)就是將第PIN_OUT(25)位元,設為1,如此再將32bits的狀態暫存器存回cfg.direction 完成狀態暫存器內容設定。

接下來我們根據表格 1 Quark SE C1000開發板腳位對照表內,我們發現GPIO[25]是由功能0所定義,由於我們使用Intel® QMSI GPIO Pin Mapping的功能,而功能0是由GPIO controller 0所控制,所以我們必須設定QM_GPIO_0來當控制器,並透過cfg這個結構變數來指定輸入、輸出的狀態,如下所示:

qm_gpio_set_config(QM_GPIO_0, &cfg);

如此我們完成所有GPIO腳位的輸入、輸出的狀態設定。

閃爍迴圈控制

一般熟悉Arduino 開發版開發系統的讀者,都會了解Arduino 開發版固定有一個loop()迴圈的程式區段,這段程式區段是必須且一定存在的,然而在Quark SE C1000開發板,是遵循一般 C 語言開發方式,並沒有像Arduino 開發時,固定有一塊loop()迴圈的程式區段,所以我們用永久迴圈來達到這個效果。如下表所示,我們可以看到我們用while(1){……}的方式來達到類似loop()迴圈的程式區段。

      while (1) {

qm_gpio_set_pin(QM_GPIO_0, PIN_OUT);

clk_sys_udelay(DELAY);

qm_gpio_clear_pin(QM_GPIO_0, PIN_OUT);

clk_sys_udelay(DELAY);

}

輸出GPIO高電位來點亮燈炮

由上表的程式,我們透過qm_gpio_set_pin()函式來將GPIO設為高電位的狀態,如下所示:qm_gpio_set_pin(QM_GPIO_0, PIN_OUT);

由於該GPIO 25為GPIO controller 0所控制,所以我們必須要使用:QM_GPIO_0來當做控制器參數輸入到函式之中,而PIN_OUT則是當做腳位參數輸入到函數之中,這樣我們就可以輕易將GPIO 25設為高電位的狀態。

輸出GPIO低電位來熄滅燈炮

由上表的程式,我們透過qm_gpio_clear_pin ()函式來將GPIO設為低電位的狀態,如下所示:qm_gpio_clear_pin(QM_GPIO_0, PIN_OUT);

由於該GPIO 25為GPIO controller 0所控制,所以我們必須要使用:QM_GPIO_0來當做控制器參數輸入到函式之中,而PIN_OUT則是當做腳位參數輸入到函數之中,這樣我們就可以輕易將GPIO 25設為低電位的狀態。

高低電位之延遲動作

由上表的程式,我們透過clk_sys_udelay()函式當做延遲函式,像Arduino 開發板的delay()函式相同功能,內容如下所示:clk_sys_udelay(DELAY);

而延遲多久,則傳入”DELAY”變數來決定,我們可以看到之前,”DELAY”變數的內容如下所示:#define DELAY 250000UL;

這裡先說明,由於這裡的單位是微秒,是10−6次方秒,所以1000000為一秒鐘,所以250000UL為25萬微秒,即為0.25秒。

編譯測試

我們用Project(專案)–> Bulid All(全部重新編譯),進行編譯LED Blink範例程式,看看是否正常。

LED_Blink測試編譯(圖/曹建國)

如下圖,我們可以看到LED Blink範例程式編譯中。

LED_Blink測試編譯中(圖/曹建國)

由下圖紅框區所示,若沒有特殊的錯誤產生,則代表Intel System Studio for Microcontroller 開發軟體正確安裝完成。

LED_Blink測試編譯成功(圖/曹建國)

燒錄測試

我們點選下圖標示的紅框處,選取Led Blink(Flash to Board),進行燒錄程式到Intel Quark SE C1000開發板的燒錄功能是否正確。

燒錄程式到開發板(圖/曹建國)

在下圖的紅框區所示,如果綠色的圖示有出現,代表Intel Quark SE C1000開發板正確連接,且可開始燒錄。

燒錄程式到開發板進行中(圖/曹建國)

如果沒有任何錯誤的訊息出現,則代表我們完成燒錄程式到開發板的作業。

完成燒錄程式到開發板(圖/曹建國)

實體執行測試

如果Intel Quark SE C1000開發板紅框區有燈閃爍(不是最上方的綠燈,那是電源燈),那代表Intel Quark SE C1000開發板已經可以執行LED Blink範例程式,可以將板載的LED燈點亮。

開發板顯示LED Blink效果(圖/曹建國)

到此我們已經可以了解Intel Quark SE C1000開發板的開發中,GPIO的設定、給值等程式技巧。

(責任編輯:葉于甄)


◎加入我們的Line,獲得更多及時文章更新&活動資訊→

加入好友

曹永忠

訂閱MakerPRO知識充電報

與40000位開發者一同掌握科技創新的技術資訊!

Author: 曹永忠

國立中央大學資訊管理學系博士,目前在國立暨南國際大學電機工程學系兼任助理教授、國立高雄科技大學商務資訊應用系兼任助理教授自由作家,專注於軟體工程、軟體開發與設計、物件導向程式設計、物聯網系統開發、Arduino開發、嵌入式系統開發。長期投入資訊系統設計與開發、企業應用系統開發、軟體工程、物聯網系統開發、軟硬體技術整合等領域,並持續發表作品及相關專業著作,並通過台灣圖霸的專家認證。

Share This Post On
468 ad

Submit a Comment

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *