作者:曹建國
本文是接續先前兩篇Quark SE C1000的文章,即如何用ISSM開發Intel SE C1000及Quark SE C1000之GPIO腳位設定技巧的開發環境及介面擴充介紹後,在這基礎下來進行一個專案的開發:使用Quark SE C1000開發板的串列通訊埠連接Lumex產品:EZDISPLAY,並顯示出我們想要展現的資料。
須用到的Quark SE C1000腳位
首先,我們將上一篇中介紹到的腳位圖再拿出來說明這次要用到的部分,如下圖所示,可以看到Quark SE C1000開發板正面,在開發版兩端各有雙排的2.54 的公頭腳位,下圖右邊紅框是J14的腳位,下圖左邊紅框是J15的腳位。

Quark SE C1000開發板腳位示意圖:標示腳一(圖/曹建國)
由上圖的Quark SE C1000開發板腳位中,我們可以看到這些腳位有一些是被拉出來,開發成Arduino UNO開發版的相容腳位。在Intel官網中所提供的使用者指引文件所示的Arduino UNO開發板相容腳位對照表,這些腳位也是從Quark SE C1000開發板腳位拉出來的腳位,轉化成Arduino UNO開發版的腳位格式。
將對照表轉化成下圖所示之Arduino UNO開發版,我們可以看到第一組UART腳位, 相當於之Arduino UNO開發版的第一組串列埠,也是D0、D1的腳位(如下圖所示之橙點與黃點),腳位如下列示:
- D0(橙點):為第一組串列埠(UART)的接收腳位(RX :Reception)
- D1(黃點):為第一組串列埠(UART)的傳輸腳位(TX : Transmission)
- GND(白點):為共地腳位(Ground)

第一組UART腳位圖
Lumex顯示裝置連接Quark SE C1000開發板
將Quark SE C1000開發板連接到Lumex Inc. EZDISPLAY(型號:LDM-768-1LT-X4)顯示裝置,如下圖所示,我們先看到EZDISPLAY顯示裝置的控制器:

LDM-768-1LT-X控制器
如上圖所示,我們可以列舉控制線作用如下:
- 紅線:LDM-768-1LT-X控制器 +5V 電源輸入
- 黑線:LDM-768-1LT-X控制器 GND 電源輸入
- 黃線:LDM-768-1LT-X控制器 串列埠之輸出端(TX)
- 紅線:LDM-768-1LT-X控制器 串列埠之接收端(RX)
我們可以看到第一組UART腳位, 相當於之Arduino UNO開發版的第一組串列埠,也是D0、D1的腳位(如下圖所示之橙點與黃點),腳位如下列示:
- D0(橙點):為第一組串列埠(UART)的接收腳位(RX:Reception)
- D1(黃點):為第一組串列埠(UART)的傳輸腳位(TX : Transmission)
- GND(白點):為共地腳位(Ground)

第一組UART腳位圖
所以我們將Intel Quark SE C1000開發板與LDM-768-1LT-X控制器連接組立電路後,可得到下圖所示之電路組立圖。

電路組立
最後,如下圖所示,我們可以看到最後成品之電路組立。

實際組立之電路
以UART範例解釋腳位的應用
如何開啟ISSM的範例程式,下圖紅框所示,我們開啟UART範例程式(Universal_Asynchronous_Receiver_Transmitter__UART_)。

開啟Uart範例程式
從下圖紅框處所示,我們可以看到許多的程式,那都是UART範例程式。

已開啟UART範例專案
簡化UART範例講解
由於範例程式:Universal_Asynchronous_Receiver_Transmitter__UART_,實在太過於複雜,因此簡化成Lora_tx的專案,大家可以從Github網站中,下載Lora_tx 的檔案 Import到專案工作區。
下表是UART簡化範例程式,雖然已經簡化到152行,大家可能還是難以閱讀,所以接下來我會一步步的解釋:
UART簡化範例程式(Lora_tx\ main.c) |
/*
* 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. */
/* * Author :BruceTsao Modified from Sertek 盧育德 Senior Manager *Uart Sample for TX *
*/
#include “qm_pinmux.h” #include “clk.h” #include “qm_common.h” #include “qm_gpio.h” #include “qm_pin_functions.h”
#include “qm_uart.h”
#define DELAY 250000UL /* 0.25 seconds. */ /* Define aon3 for UART mux pin*/ #define AON3 3 /* Wait time (us). */ #define WAIT_1MSEC (1000)
static void pin_mux_setup() { // Mux out STDOUT_UART TX/RX pins and enable input for RX.
qm_pmux_select(QM_PIN_ID_17, QM_PIN_17_FN_UART1_RXD); qm_pmux_select(QM_PIN_ID_16, QM_PIN_16_FN_UART1_TXD); qm_pmux_input_en(QM_PIN_ID_17, true);
}
int uint2str(unsigned int no, uint8_t *p) { int ret = 0 ; // int tmp = 0 ; if (no <10) { *p = 0x30 + no ; ret = 1 ; } else if (no <100) {
*(p+1) = 0x30 + (no % 10) ; *p = 0x30 + (int)(no/10) ; ret = 2 ;
}else if (no <1000) { *(p+2) = 0x30 + (no % 10) ; *(p+1) = 0x30 + (int)((no/100) / 10) ; *p = 0x30 + (int)(no/100) ; ret = 3 ;
}else if (no <10000) { *(p+3) = 0x30 + (no % 10) ; *(p+2) = 0x30 + (int)((no % 100) %10) ; *(p+1) = 0x30 + (int)((no % 100) / 10) ; *p = 0x30 + (int)(no/1000) ; ret = 4 ;
} return ret ; }
int main(void) { int strlen = 0;
qm_uart_config_t uart1_cfg ; qm_gpio_port_config_t aon_cfg;
pin_mux_setup();
uart1_cfg.baud_divisor = QM_UART_CFG_BAUD_DL_PACK(0, 17, 6); uart1_cfg.line_control = QM_UART_LC_8N1; uart1_cfg.hw_fc = false;
aon_cfg.direction = BIT(AON3); /* Set AON3 pins as output. */
qm_gpio_set_config(QM_AON_GPIO_0, &aon_cfg); qm_uart_set_config(QM_UART_1, &uart1_cfg);
uint8_t uart1_message[] = “PM2.5:”; uint8_t uart1_message1[20] ;
while(1){
clk_sys_udelay(WAIT_1MSEC);
for (int i = 50 ; i <120; i++) { strlen = uint2str(i, &uart1_message1[0]) ; qm_uart_write_buffer(QM_UART_1, uart1_message, sizeof(uart1_message)); qm_uart_write_buffer(QM_UART_1, uart1_message1, strlen) ; clk_sys_udelay(DELAY*5); }
}
return 0; }
|
Include講解
下圖的程式碼是整個系統必要的含括檔(include files)。

Lora_tx include程式
由於我們需要用到ARD_D0與ARD_D1,這是屬於AP_GPIO_SS9_ADC17_UART1_RXD與AP_GPIO_SS8_ADC16_UART1_TXD(參考下表之SC1000腳位對照表),UART1_TX與UART1_RX使用到QM_PIN的功能,所以必須要包含下列三個含括檔:
- #include “qm_pinmux.h”
- #include “qm_pin_functions.h”
- #include “qm_common.h”
由於它仍是GPIO的GPIO_SS[8]與GPIO_SS[9] ,所以必須要包含下列一個含括檔:
- #include “qm_gpio.h”
因此我們在GPIO的運用上,必須要使用這些含括檔。

SC1000腳位對照表(簡表)
使用 UART的資源,同時也關係到UART的QM Function的控制,所以在UART1_TX與UART1_RX使用到Function的控制,必須要包含: #include “qm_uart.h”
在時間延遲顯示上的需要,會用到系統時間控制,在最後必須要包含: #include “clk.h”
所以當我們操作時,需要配合GPIO、通訊埠控制與時間延遲等運用上,必須加入上述這些含括檔。
Define宣告講解

Define宣告程式
在設定時間延遲上,我們會先定義時間的單位。Intel Quark SE C1000開發板的運行是μs := micro second,一秒鐘為一百萬μs,所以0.25秒為250000UL,由下列變數來定義時間的單位:#define DELAY 250000UL
Intel Quark SE C1000開發板的UART 1與Intel System Studio for Microcontroller:ISSM 軟體的Debug Port共用(參考下圖所示),所以如果沒有將FTDI與UART 多工器切換,所有串列埠的訊號,只會傳到Debug Port,而Intel Quark SE C1000開發板的UART 1腳位,卻完全沒有訊號。

FTDI與UART 多工器線路圖
基於上述原因,所以需要做下列的變數定義: #define AON33
有時候雖然軟體會進行多工器設定,但常常會看到FTDI與UART 多工器切換其實有時候不太靈光。因此,我們為了確定可以將Intel Quark SE C1000開發板的UART 1腳位完全作用,我們透過硬體方式將AO3腳位接到地線(如下圖)。

AO3腳位接地圖
時間延遲函數需要,所以我們要先定義延遲時間的內容,將變數定義為:#define WAIT_1MSEC (1000)
為了通訊埠控制與時間延遲等運用,是必須使用define定義這些變數。
函式內容講解(pin_mux_setup)
我在上面提到,我們需要用到QM Function。這些QM Function需要用到GPIO腳位,在GPIO使用時必須要對腳位進行輸入、輸出等宣告,如下表所示,宣告與產生的pin_mux_setup()函式來進行上述的用途。

pin_mux_setup函式
函式內容講解(uint2str)
這次的專案主要是要把PM2.5感測器的感測數值,顯示在EZDISPLAY大型顯示裝置上,但顯示裝置只接收文字字串,所以宣告一個數字的轉字串需要自訂函數:uint2str()函數來達到這個功能。

uint2str函式
Main主程式講解
下表為main主程式的內容,我們會一一分功能區段,介紹如下:

main主程式
Main主程式:變數宣告
當PM2.5感測器得到的數值資料,轉成文字字串時,其數值顯示的長度為何,我們使用:int strlen = 0;
針對QM UART功能進行通訊時所需要的速率、開始位元、結束位元與7 bits / 8 bits等設定,對物件變數為:qm_uart_config_t uart1_cfg ;
UART與Debug Port多工器切換中其多工器變數AON3,宣告物件變數:qm_gpio_port_config_t aon_cfg;
Main主程式:Setup區
由於GPIO的設定,之前我們已經介紹pin_mux_setup(); 函式,必須在使用GPIO腳位之前,執行pin_mux_setup(); 函式內容,所以我們有下列敘述:pin_mux_setup();
Main主程式:通訊設定
在通訊設定上,有三個步驟
第一步,我們需要設定UART通訊速率,由於Lumex Inc. EZDISPLAY顯示裝置的傳輸速率為115200 bps,所以我們必須將UART的通訊速率設為115200 bps,以達到同步,我們有下列敘述:uart1_cfg.baud_divisor = QM_UART_CFG_BAUD_DL_PACK(0, 17, 6);
再來,我們需要設定UART 通訊方式與格式,主樣把通訊格式設為8N1,就是使用8位元傳送,不送Parity bit,停止位元為 bit 1,所以下列敘述為:uart1_cfg.line_control = QM_UART_LC_8N1;
最後,我們需要設定UART 是否使用硬體流量控制(flow control及hardware flow control),由於我們並沒有使用CTS與RTS,所以我們將硬體流量控制關閉,將下列敘述設定為:uart1_cfg.hw_fc = false;
上面介紹了QM UART功能所訂的物件變數:qm_uart_config_t uart1_cfg ,經過上述一連串的設定內容之後,我們需要將這些設定寫入周邊。使用qm_uart_set_config()函數寫入時,我們有下列敘述:qm_uart_set_config(QM_UART_1, &uart1_cfg);
Main主程式:多工器設定
UART與Debug Port多工器切換,我們需要告知多工器為只有使用UART輸入,所以我們有下列敘述:aon_cfg.direction = BIT(AON3);
上面介紹了UART與Debug Port多工器切換的必要,將這些設定寫入周邊,我們使用qm_gpio_set_config()函數寫入時,需要有下列敘述:qm_gpio_set_config(QM_AON_GPIO_0, &aon_cfg);
Main主程式:顯示內容變數
接下來,將資訊送往Lumex Inc. EZDISPLAY顯示裝置時,由於資訊前方仍需資訊顯示欄位說明,所以我們需要資訊顯示欄位說明變數與資訊內容變數,將設定為:
uint8_t uart1_message[] = “PM2.5:”;
uint8_t uart1_message1[20] ;
其uart1_message[]為資訊顯示欄位說明變數,而uart1_message1[20]為資訊內容變數。
Main主程式:loop()區段
一般熟悉Arduino 開發版開發系統的讀者,都會了解Arduino 開發版固定有一個loop()迴圈的程式區段,這段是固定的區域,而且在Arduino 開發時,固定有一塊loop()迴圈的程式區段,這段程式區段是必須且一定存在的,然而在Intel Quark SE C1000開發板,是遵循一般c語言開發方式,所以並沒有像Arduino 開發時,固定有一塊loop()迴圈的程式區段,所以我們用永久迴圈來達到這個效果。如下表所示,我們可以看到我們用while(1){……}的方式來達到類似loop()迴圈的程式區段。

loop程式區塊
因為顯示內容不一定跟上感測器偵測速率等因素,所以必須要用延遲等待的函數如delay()(Arduino 指令)。使用我們之前系統的函數clk_sys_udelay()來達到時間延遲的效果,敘述為:clk_sys_udelay(WAIT_1MSEC); 其WAIT_1MSEC為一百萬的us,所以延遲一秒鐘。
Main主程式:模擬感測器不同資料輸出
此篇只介紹顯示的電路與程式內容,所以暫且沒有動態資訊的輸入,但是如果只有重複數據顯示,可能會造成我們無法辨識是否正常輸出或當機等問題,所以如下表所示,我們用一個for迴圈來達到模擬感測器不同資料輸出所以我們有下列敘述:

模擬感測器不同資料輸出之程式區塊
我們只會取得數值,而數值的型態無法傳送到Lumex Inc. EZDISPLAY顯示裝置,必須將數值進行字串的轉換函式,使用uint2str()將數值轉換成字串:strlen = uint2str(i, &uart1_message1[0]) ; 在正式將轉換數值為字串之後,我們使用strlen取得與紀錄字串長度。
Main主程式:顯示感測資料說明欄位
當一切資料就緒後,我們使用qm_uart_write_buffer()將顯示內容輸出到UART的通訊埠:qm_uart_write_buffer(QM_UART_1, uart1_message, sizeof(uart1_message));
我們先行顯示uart1_message1的內容,就是『PM2.5:』的內容。
Main主程式:顯示模擬感測資料
接下來,一切資料就緒後,我們使用qm_uart_write_buffer()將顯示內容輸出到UART的通訊埠:qm_uart_write_buffer(QM_UART_1, uart1_message1, strlen) ;
我們先前顯示uart1_message1的內容,就是使用了for迴圈產生的『模擬感測資料』的內容。
Lumex Inc. EZDISPLAY顯示裝置接收資料與顯式的特性,如果小於100ms,Lumex Inc. EZDISPLAY顯示裝置會將資料一起顯示,而不會清掉螢幕,所以我們必須要做時間延遲,我們使用clk_sys_udelay()來進行時間延遲,所以我們宣告下列變數:clk_sys_udelay(DELAY*5);
先前提過DELAY為0.25秒,DELAY*5為1.25秒,所以我們約1.25秒顯示感測資料。
燒錄測試
我們點選下圖紅框處,選Lora_tx(Flash to Board),進行燒錄程式到Intel Quark SE C1000開發板的燒錄功能是否正確。

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

燒錄程式到開發板進行中
如下圖所示,如果沒有任何錯誤的訊息出現,則代表我們已經完成燒錄程式到開發板的作業。

執行內容
結語
本篇主要是介紹Intel Quark SE C1000開發板如何使用Quark SE C1000開發板的串列通訊埠連接Lumex產品:EZDISPLAY,並顯示出我們想要展現的資料,接下來這專案準備延伸與空氣盒子連結,進而可以顯示空氣污染的即時資訊。
(責任編輯:葉于甄)
◎加入我們的Line,獲得更多及時文章更新&活動資訊→
- 【大氣監控站台開發案例(下)】環境監控即時監控看板 - 2021/11/25
- 【大氣監控站台開發案例(中)】環境監控雲端平台系統介紹 - 2021/11/02
- 【大氣監控站台開發案例(上)】 大氣監控站建置實例介紹 - 2021/10/18
訂閱MakerPRO知識充電報
與40000位開發者一同掌握科技創新的技術資訊!