對于我們大多數(shù)為嵌入式系統(tǒng)編寫固件和軟件的人來說,普遍希望立即投入編碼,而忽略或很少關(guān)注關(guān)鍵的程序設(shè)計階段。不幸的是,這種沖動在我們的領(lǐng)域比在其他領(lǐng)域更為明顯。
例如,如果沒有完全開發(fā)的藍(lán)圖或原理圖,建筑商或硬件工程師永遠(yuǎn)不會開始施工。另一方面,即將推出的固件開發(fā)人員經(jīng)常直接進(jìn)入編碼階段,而沒有完全開發(fā)其程序邏輯,這通常會導(dǎo)致混亂的“意大利面條”程序(圖 1)。

在次設(shè)計之前編寫代碼是一種不好的做法,會導(dǎo)致混亂的“意大利面條”程序。
圖 1.在首次設(shè)計之前編寫代碼是一種不好的做法,會導(dǎo)致混亂的“意大利面條”程序。
他們通過以下三種方式之一來做到這一點:
他們同時嘗試設(shè)計和編碼(這種方法被稱為“設(shè)計一點,編碼一點”)
他們在開發(fā)程序的邏輯設(shè)計時過于依賴編程語言的約束
他們完全跳過設(shè)計步驟,因為他們認(rèn)為該項目“太簡單”,或者他們對自己的能力過度自信,也就是“我太聰明了”。
這種急于編寫代碼的行為可能會適得其反,并終花費更多的開發(fā)時間,因為設(shè)計不當(dāng)?shù)某绦蚩赡軙?dǎo)致許多本來可以通過仔細(xì)規(guī)劃來避免的錯誤。
例如,如果您使用“設(shè)計一點、編碼一點”的方法,那么隨著設(shè)計的不斷變化,您可能需要擦除或重新輸入很多內(nèi)容。您的程序的長度將是其應(yīng)有的兩倍,效率將是其應(yīng)有的一半。如果認(rèn)為跳過程序的設(shè)計階段會加快開發(fā)過程,并且您的嵌入式系統(tǒng)將立即啟動并運行,那么這可能是一個巨大的錯誤。
事實上,為微控制器構(gòu)建經(jīng)濟代碼的關(guān)鍵是在編寫一行代碼之前花時間系統(tǒng)地設(shè)計程序。這也稱為結(jié)構(gòu)化編程,它會導(dǎo)致代碼占用更少的內(nèi)存,需要更短的處理時間,并且通常在次嘗試時就可以正確運行。
結(jié)構(gòu)化編程意味著對問題有透徹的理解。它涉及自上而下的分析,將問題分解為越來越小的部分,直到每個部分都有明顯的解決方案或功能。同時,它還涉及使用三種控制結(jié)構(gòu)(序列、交替、重復(fù)或循環(huán))來組織或組合功能。
為此,在結(jié)構(gòu)化編程中設(shè)計程序的一種流行工具是使用 Warnier-Orr 圖,該圖以創(chuàng)建者 Jean-Dominique Warnier 和 Kenneth T. Orr 的名字命名。
Warnier-Orr 圖清晰可見
Jean-Dominique Warnier 和 Kenneth Orr 創(chuàng)建了 Warnier-Orr 圖作為可視化工具,用于顯示復(fù)雜數(shù)據(jù)或流程的層次結(jié)構(gòu)分解。它的主要用途是表示程序的邏輯結(jié)構(gòu)。
程序是一組有序指令,用于處理輸入數(shù)據(jù)以產(chǎn)生結(jié)果。您正在編程的微控制器只是一個快速信息處理工具。
輸入的數(shù)據(jù)、結(jié)果、程序都是信息文件。這些信息文件不是完全獨立的數(shù)據(jù),但可以嵌套在其內(nèi)部。也就是說,它們可以分解為子部分并以父子方式分層組織。
Warnier-Orr 圖允許您定義所需的輸出并逆向工作,分解產(chǎn)生所需結(jié)果所需的輸入和流程步驟。然后,它可以幫助您以圖形方式表示程序步驟的層次結(jié)構(gòu)以及已分解的輸入和輸出數(shù)據(jù)結(jié)構(gòu)。
Warnier-Orr 圖概述和注意事項
1. Warnier-Orr 圖用括號在頁面上水平繪制程序或數(shù)據(jù)結(jié)構(gòu)(圖 3)。

Warnier-Orr 圖的示例。 A 分為子部分 B、C 和 D。D 分為子部分 E、F、J 和 H。
圖 3.Warnier -Orr 圖示例。A 分為子部分 B、C 和 D。D 分為子部分 E、F、J 和 H。
每個括號代表括號前面的數(shù)據(jù)項或流程步驟的功能細(xì)分。括號代表單獨的層次級別,每個括號內(nèi)的項目在邏輯上是相關(guān)的。
2. Warnier 圖在括號內(nèi)從左到右、從上到下閱讀。
3. 對于程序結(jié)構(gòu)表示,Warnier-Orr 圖的每個括號都是一個視覺提示,表示已完成程序中的子例程。
4. 當(dāng)一個項目或函數(shù)下面帶有符號 (0,1) 時,表示它存在或不存在、選擇或未選擇、或假或真。
5. “+”表示包含 OR。當(dāng)括號中的兩個或多個項目或步驟用“+”分隔時,表示包括其中之一或另一個,或兩者都包括在內(nèi)。
6. 符號“?”表示異或。當(dāng)括號內(nèi)的兩個或多個項目或步驟用“?”分隔時,表示包括或執(zhí)行其中一項,但不是兩項。
7. 符號“(n, N)”表示函數(shù)將被執(zhí)行的次數(shù)(圖 4)。

使用 Wanier-Orr 圖分解智能鎖數(shù)據(jù)。
圖 4.使用 Wanier-Orr 圖分解智能鎖數(shù)據(jù)。
8. 符號“?N”符號表示要測試的條件以確定將選擇哪個功能。圖 5 所示圖表的腳注詳細(xì)介紹了這些條件。
已分解為子部分的程序的邏輯表示。
圖 5.已分解為子部分的程序的邏輯表示。圖片由分析師和程序員圖表技術(shù)提供
9. 當(dāng)表示一個程序時,每個層級或子功能都由三個部分組成。它們是開始、流程步驟和結(jié)束。
現(xiàn)在,有了 Warnier-Orr 工具,您就可以為下一個嵌入式系統(tǒng)項目設(shè)計程序了。
邏輯設(shè)計微控制器程序的步驟
為微控制器構(gòu)建良好的程序需要系統(tǒng)的方法。Jean Warnier 和其他作者在《編程技術(shù)》一書中介紹了四個設(shè)計步驟,幫助您設(shè)計的程序,并從導(dǎo)致我們首先創(chuàng)建它們的問題中得出它們。
第 1 步:識別輸出
步也是重要的一步是確定程序所需的輸出。您必須問自己這個問題:“我希望程序做什么?” 確保您盡可能清楚地回答這個問題。
步驟 2:定義邏輯數(shù)據(jù)庫
一旦明確定義了輸出,您就可以識別所需的輸入,并定義這些輸入的屬性。此步驟有助于確??紤]到所有必要的輸入,以及一刻的添加,例如“哎呀,我忘了輸入一些內(nèi)容到。..。..”。。?!?。保持在限度。
當(dāng)您能夠回答步驟一和步驟二中的問題時,您就完成了別的設(shè)計。
第三步:設(shè)計程序結(jié)構(gòu)
接下來,設(shè)計程序結(jié)構(gòu)分兩步完成:自上而下的分析和綜合。
自上而下的分析:
自上而下的分析涉及將程序分解為許多更詳細(xì)的子功能。從別開始,這是描述整體功能的單個塊,然后逐步將該功能擴展為詳細(xì)的子功能。通過此步驟,不必太擔(dān)心程序中子函數(shù)的執(zhí)行順序。你只關(guān)心應(yīng)該做什么,而不關(guān)心應(yīng)該如何做。
由于其中大部分內(nèi)容都是直觀的,因此請慢慢開始該過程,不要試圖太快地開發(fā)太多細(xì)節(jié)。
合成:
完成自頂向下的分析后,您已將程序簡化為基本組件的集合。綜合涉及決定應(yīng)以什么順序執(zhí)行功能。組織這些函數(shù)的三個基本邏輯結(jié)構(gòu)是序列、if-then-else 和循環(huán)。這些的組合可用于構(gòu)建復(fù)雜的函數(shù)。
第 4 步:使用 Warnier-Orr 圖來表示您的設(shè)計
使用 Warnier-Orr 圖將其轉(zhuǎn)化為概述。整個圖應(yīng)該只包含邏輯語句,而不包含代碼。這使得文檔易于理解。
評論