應用前述功能方塊結構體型態,功能方塊結構體內容初始化巨集,以及功能方塊步級執行函式可以架構出一個軟體功能方塊。在正式介紹軟體功能方塊的建構前,以下我們先研究一下完整程式的分區塊架構,然後再介紹功能方塊各元素應佈建在程式架構的那個區塊內。
完整程式的分區架構
常見的程式完整架構會以主程式 main()為核心。在 main()函式之前,main()內部,以及 main()之後,依前後順序可以區分為
• 宣告定義區段:在 main()函式之前區段程式碼會分佈
◦ 引入.h 檔:
◦ 巨集定義
◦ 變數型態及結構體型態定義
◦ 廣域變數宣告定義及初始化
◦ 函式原型宣告
• 主程式區段:在主函式 main()內部有前後兩個區段
◦ 初始化及設定區段:主函式 main()前面區段,先後執行
▪ 內部變數定義及初始化。
▪ 週邊硬體設定。
◦ 永久輪詢迴路區段:主函式 main()後面區段,以 while(1){}永久迴路包圍,主程式內部執行計算,判斷,以及呼叫其他函式之程式碼。
• 函式定義區段:在主函式 main()之後,羅列各個預備被呼叫的函式。各函式內部也可分為前後兩區段。
◦ 內部變數定義:前段設定區域變數
◦ 執行程式碼:後段執行,輸出入運算並於完成後 RETURN。
功能方塊各元素佈建
建構軟體功能方塊,需要定義功能方塊結構體的型態,宣告結構體初始值巨集,再以該型態來定義定義功能方塊結構體並以初始值巨集初始它,之後即可呼叫使用它的功能方塊步級執行函式。其各元素佈建步驟如下:
• 宣告定義區段:
◦ 定義功能方塊結構體型態:定義結構體要有欄位容納功能方塊內部步
級更新變數。
◦ 宣告結構體初始值巨集:以指名初始化方式宣告結構體各欄位初值。
◦ 定義並初始化功能方塊結構體:由使用者自定結構體名稱,以結構體
型態定義結構體,並以等式等於結構體初始值巨集完成初始化。
◦ 宣告功能方塊步級執行函式原型:由使用者自定函式名稱。參數中必
需要有它的功能方塊結構體指標,以及輸出入參數。
• 主程式區段:
◦ 初始化及設定區段:無有關功能方塊之工作。
◦ 永久輪詢迴路區段:呼叫功能方塊步級執行函式。
• 函式定義區段:撰寫定義功能方塊步級函式。
範例:電子計算器軟體功能方塊架構
圖 8-2 軟體系統整體方塊圖
圖 8-2 是電子計算器軟體系統整體功能方塊圖,其中白色為外部連接的硬體模組,黃色涉及硬體電路的驅動函式,藍色為計算機軟體功能方塊。
鍵盤驅動函式:鍵盤驅動函式會掃瞄鍵盤,回傳有無新鍵入值並輸出其編號。鍵號解譯器(KeyResolver):查詢新鍵編號對應 ASCII 碼並解譯新鍵的分類及涵意,包括鍵入的是否為數字,如是數字,其數值大小,若不是數值,則是那種運算符號,然後將這此分類及涵意傳遞給後級,累加進位器,以及運算執行器等做鍵入值後續處理的參考。
累加進位器(KeyInCumulator):依據由鍵號解譯器所得,若新鍵入值的數字,它會被累加進位以算出輸入之多位數輸入數值。這個數值會再傳遞交給他的後級,顯示選擇器,或運算執行器來執行顯示或運算。
運算執行器(Calculator):會依由鍵號解譯器所得非數字鍵涵意來判斷是否執行運算,如需運算,會由累加進位器取得新值,並由先前己存記的內存值,依非數字鍵涵意執行各式運算。運算結果會交由顯示選擇器處理。
顯示選擇器(DisplaySelector):會依由鍵號解譯器所得輸入鍵特性,來判斷時機,選擇應顯示的是什麼資料,並將要顯示的數值切割 4 位數及小數點位數。
顯示器驅動函式(ShowOn7Segment):接手顯示選擇器輸出 4 位數及小數點位數,轉碼成 7 節管碼後,在適當位數加入小數點後驅動七節管顯示數值。
以此一系統為範例,其程式區塊架構可以說明如下:
typedef struct {
:
} KeyBoardReadStr_t;//鍵盤讀取結構體型態定義
#define KEYBOARDREADSTR_INIT { \
: \}
KeyBoardReadStr_t KeyBoardRead_str= KEYBOARDREADSTR_INIT;//鍵盤讀取結構體定義
uint8_t KeyBoardRead_step(...) //鍵盤讀取函式原型宣告
typedef struct {
:
} KeyResolverStr_t;//鍵盤解譯結構體型態定義
#define KEYRESOLVERSTR_INIT { \
: \}
KeyResolverStr_t KeyResolver_str= KEYRESOLVERSTR_INIT;//鍵盤解譯結構體定義
uint8_t KeyResolver_step(....,); //鍵盤解譯函式原型宣告
typedef struct {
:
} KeyInCumulatorStr_t;//累加器結構體型態定義:
#define KEYINCUMULATORSTR_INIT { \
: \}
KeyInCumulatorStr_t KeyInCumulator_str= KEYINCUMULATORSTR_INIT;//累加器結構
體定義
uint8_t KeyInCumulator_step(...); //累加器函式原型宣告
typedef struct {
:
} CalculatorStr_t;//運算執行器結構體型態定義:
#define CALCULATORSTR_INIT { \
: \}
CalculatorStr_t Calculator_str= CALCULATORSTR_INIT;//運算執行器結構體定義:
uint8_t Calculator_step(...); //運算執行器函式原型宣告
typedef struct {
:
} DisplaySelectorStr_t;//顯示選擇器結構體型態定義:
#define DISPLAYSELECTORSTR_INIT { \
: \}
DisplaySelectorStr_t DisplaySelector_str= DISPLAYSELECTORSTR_INIT;//顯示選擇
器結構體定義:
uint8_t DisplaySelector_step(...); //顯示選擇器函式原型宣告
typedef struct {
:
} ShowOn7SegmentStr_t;//七節管顯示結構體型態定義:
#define SHOWON7SEGMENTSTR_INIT { \
: \}
ShowOn7SegmentStr_t ShowOn7Segment_str= SHOWON7SEGMENTSTR_INIT;//七節管顯示
結構體定義:
uint8_t ShowOn7Segment_step(...); //七節管顯示函式原型宣告
main()
{
//傳參變數定義區塊
: //其它傳參變數
//功能方塊及驅動函式設定區塊
: //其它函式設定
//永久迴路,迴路內依功能方塊前後順序呼叫所有的驅動函式及功能函式
while(1) {
KeyBoardRead_step(...); //以鍵號變數傳址做為 Data 呼叫鍵盤驅動函式
KeyResolver_step(...); // 以鍵號變數傳值做為功能方塊輸入呼叫鍵盤
KeyInCumulator_step(...); //呼叫累加器函式。
Calculator_step(...); //運算執行器函式
DisplaySelector_step (...); //呼叫顯示選擇器函式
ShowOn7Segment_step(...); //呼叫顯示器驅動函式
}
}
uint8_t KeyBoardRead_step(...){
:
}
uint8_t KeyResolver_step(....,){
:
}
: