第4章 程序設(shè)計(廣西大學(xué))_第1頁
第4章 程序設(shè)計(廣西大學(xué))_第2頁
第4章 程序設(shè)計(廣西大學(xué))_第3頁
第4章 程序設(shè)計(廣西大學(xué))_第4頁
第4章 程序設(shè)計(廣西大學(xué))_第5頁
已閱讀5頁,還剩73頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認(rèn)領(lǐng)

文檔簡介

1、第第4章章 程序設(shè)計程序設(shè)計 教學(xué)目標(biāo)教學(xué)目標(biāo) 介紹單片機匯編程序設(shè)計方法介紹單片機匯編程序設(shè)計方法 介紹單片機匯編程序常用結(jié)構(gòu)及設(shè)計方法介紹單片機匯編程序常用結(jié)構(gòu)及設(shè)計方法 介紹介紹典型智能儀表單片機系統(tǒng)應(yīng)用軟件設(shè)計典型智能儀表單片機系統(tǒng)應(yīng)用軟件設(shè)計 介紹介紹目前流行的目前流行的MCS-51單片機高級語言單片機高級語言C51 學(xué)習(xí)要求學(xué)習(xí)要求 熟悉單片機編程的步驟、方法和技巧熟悉單片機編程的步驟、方法和技巧 掌握單片機匯編程序的常用結(jié)構(gòu)及設(shè)計方法掌握單片機匯編程序的常用結(jié)構(gòu)及設(shè)計方法 掌握典型匯編語言應(yīng)用程序的編制掌握典型匯編語言應(yīng)用程序的編制 了解單片機高級程序設(shè)計語言了解單片機高級程序設(shè)

2、計語言C51 單片機系統(tǒng)設(shè)計由硬件設(shè)計和軟件單片機系統(tǒng)設(shè)計由硬件設(shè)計和軟件 設(shè)計兩部分組成,設(shè)計兩部分組成,后者就是設(shè)計程 序、編制表格,以指揮單片機完成 用戶交付的任務(wù)。本章介紹MCS-51 單片機匯編語言程序設(shè)計的基本步 驟、方法和技巧,并在最后簡單地 介紹了C51高級程序設(shè)計。 4.1編程的步驟、方法和技巧編程的步驟、方法和技巧 單片機常用于工業(yè)測控裝置和智能儀表等, 這些應(yīng)用場所往往對實時性提出了要求。使用 匯編語言設(shè)計程序,雖然比高級語言煩瑣,但 它能最充分地發(fā)揮指令系統(tǒng)的功能與效率,獲 得最簡練的目標(biāo)程序,能滿足實時性要求。用 匯編語言設(shè)計單片機應(yīng)用程序往往要經(jīng)歷以下 幾個步驟:

3、(1)軟件任務(wù)分析; (2)數(shù)據(jù)類型和數(shù)據(jù)結(jié)構(gòu)規(guī)劃; (3)資源分配; (4)編程與調(diào)試。 4.1.1軟件任務(wù)分析軟件任務(wù)分析 軟件任務(wù)分析是為軟件設(shè)計作一個總體規(guī) 劃。從功能來看,軟件可分為兩大類:一類是 執(zhí)行軟件,它能完成各種實質(zhì)性的功能,如測 量、計算、顯示、打印、輸出控制和通信等; 另一類是監(jiān)控軟件,它是專門用來協(xié)調(diào)各執(zhí)行 模塊和操作者的關(guān)系,在系統(tǒng)軟件中充當(dāng)組織 調(diào)度角色的軟件。這兩類軟件的設(shè)計方法各有 特色,執(zhí)行軟件的設(shè)計偏重算法效率,與硬件 關(guān)系密切。監(jiān)控軟件著眼全局,邏輯嚴(yán)密。 軟件任務(wù)分析時,應(yīng)將各執(zhí)行模塊 一一列出,并為每一個執(zhí)行模塊進行功 能定義和接口定義(輸入、輸出定義

4、)。在 為各執(zhí)行模塊進行定義時,將要牽涉到 的數(shù)據(jù)結(jié)構(gòu)和數(shù)據(jù)類型的問題也一并規(guī) 劃好。 各執(zhí)行模塊規(guī)劃好后,就可以規(guī)劃 監(jiān)控程序了。首先根據(jù)系統(tǒng)功能和鍵盤 設(shè)置選擇一種最合適的監(jiān)控程序結(jié)構(gòu)。 相對來講,執(zhí)行模塊任務(wù)明確單純,比 較容易編程。而監(jiān)控程序較易出問題。 任務(wù)分析的另一個內(nèi)容是如何安排監(jiān)控軟 件和各執(zhí)行模塊。整個系統(tǒng)軟件可分為后臺程 序和前臺程序。后臺程序指主程序及其調(diào)用的 子程序,這類程序?qū)崟r性要求不是很高,延 誤幾十毫秒甚至幾百毫秒也沒關(guān)系,故通常將 監(jiān)控程序(鍵盤管理程序)、顯示程序和打印程 序等與操作者打交道的程序放在后臺程序中來 執(zhí)行。而前臺程序安排一些實時性要求較高的 內(nèi)

5、容,如定時系統(tǒng)和外部中斷。在一些特殊場 合,也可以將全部程序均安排在前臺,后臺為 踏步等待循環(huán)或睡眠狀態(tài)。 4.1.2數(shù)據(jù)類型和數(shù)據(jù)結(jié)構(gòu)規(guī)劃數(shù)據(jù)類型和數(shù)據(jù)結(jié)構(gòu)規(guī)劃 前面的軟件任務(wù)分析只是一個粗糙的分析 和大體上的安排,還不能開始編程。 為了避免 系統(tǒng)中各個執(zhí)行模塊之間的脫節(jié)現(xiàn)象,就必須 嚴(yán)格規(guī)定好各個接口條件,即各接口參數(shù)的數(shù) 據(jù)結(jié)構(gòu)和數(shù)據(jù)類型。 從數(shù)據(jù)類型上來分類,可分為邏輯型和數(shù) 值型,但通常將邏輯型數(shù)據(jù)歸到軟件標(biāo)志中去 考慮。而將數(shù)據(jù)類型分類理解為數(shù)值類型分類。 數(shù)值類型可分為定點數(shù)和浮點數(shù)。 如果一個參數(shù)的變化范圍有限,就可用定 點數(shù)來表示,以簡化程序設(shè)計和加快運行速度; 當(dāng)參數(shù)的變化

6、范圍太寬時,只好采用浮點數(shù)來 表示。 如果某參數(shù)是一系列有序數(shù)據(jù)的集合,如 采樣信號系列,則不光有數(shù)據(jù)類型問題,還有 一個數(shù)據(jù)存放格式問題,即數(shù)據(jù)結(jié)構(gòu)問題。在 單片機應(yīng)用系統(tǒng)中,數(shù)據(jù)結(jié)構(gòu)比較簡單,大多 采用線性結(jié)構(gòu),這樣有利于數(shù)據(jù)處理。由于受 RAM空間的限制,隊列結(jié)構(gòu)廣泛采用環(huán)行隊列 結(jié)構(gòu),為此應(yīng)規(guī)劃好兩樣?xùn)|西:隊列區(qū)域和隊 尾(首)指針,并計算出總共需要的RAM字節(jié)數(shù)。 對于數(shù)組,一般采用順序存放的格式。這樣就 可以用簡單的下標(biāo)運算來訪問數(shù)組中的任何一 個元素。 4.1.3資源分配資源分配 完成數(shù)據(jù)類型和數(shù)據(jù)結(jié)構(gòu)的規(guī)劃后,便可開始分 配系統(tǒng)的資源了。在微機測控系統(tǒng)中,往往需要定時 檢測某個

7、物理參數(shù),或按一定的時間間隔來進行某種 控制等。這種定時的獲得常采用定時/計數(shù)器,它還可 以對某種事件進行計數(shù),然后根據(jù)計數(shù)結(jié)果來進行控 制;單片機在及時處理實時測、控中的許多隨機的參 數(shù)和信息、對外界異步事件包括故障的處理常使用中 斷,在任務(wù)分析時一般要將定時/計數(shù)器和中斷源等資 源分配好。ROM資源用來存放程序和表格,這也是明 顯的。系統(tǒng)資源ROM、RAM、定時/計數(shù)器、中斷源 等。因此,資源分配的主要工作是RAM資源的分配。 片外RAM的容量比片內(nèi)RAM大,通常用來存放大批量 的數(shù)據(jù),如采樣數(shù)據(jù)系列。真正需要認(rèn)真考慮的是片 內(nèi)RAM的分配。 片內(nèi)RAM指00H7FH單元。這128個字節(jié)

8、的功能并不完全相同,分配時應(yīng)注意充分發(fā)揮 各自的特長,做到物盡其用。 00H1FH這32個字節(jié)可以作為工作寄存器, 其中00H0FH用來作為0區(qū)、1區(qū)工作寄存器。 在一般的應(yīng)用系統(tǒng)中,后臺程序用0區(qū)工作寄 存器,前臺程序用1區(qū)工作寄存器。如果有高 級中斷,則高級中斷可用2區(qū)工作寄存器 (10H17H)。如果前臺程序中不使用工作寄存 器,則系統(tǒng)只需0區(qū)工作寄存器。未作為工作 寄存器的其它單元便可以轉(zhuǎn)為其它目的使用了。 系統(tǒng)上電復(fù)位時,自動定義0區(qū)為工作寄存器, 1區(qū)為堆棧,并向2區(qū)、3區(qū)延伸。如果前臺程 序要用1區(qū)、2區(qū)作為工作寄存器,就應(yīng)將堆棧 空間重新規(guī)劃 。 在工作寄存器的8個單元中,R0

9、和R1具有 指針功能,是編程的重要角色,應(yīng)充分發(fā)揮其 作用,盡量避免用來做其它事情。 20H2FH這16個字節(jié)具有位尋址功能,用 來存放各種軟件標(biāo)志、邏輯變量、位輸入信息、 位輸出信息副本、狀態(tài)變量、邏輯運算的中間 結(jié)果等。當(dāng)這些項目安排好后,保留一兩個字 節(jié)備用,剩下的單元才可改作其它用途。 30H7FH為一般通用寄存器,只能存入整 字節(jié)信息。通常用來存放各種參數(shù)、指針、中 間結(jié)果,或用作數(shù)據(jù)緩沖區(qū)。也常將堆棧安排 在片內(nèi)RAM的高端,如68H7FH。 如果將系統(tǒng)的各種開銷安排后,所剩單元 很少,這往往不是好的兆頭。應(yīng)該留有足夠的 余地,因為現(xiàn)在還處于規(guī)劃階段,隨著軟件設(shè) 計的發(fā)展進程,幾乎

10、都會出現(xiàn)新的資源要求。 如果在規(guī)劃階段資源已經(jīng)很緊張,建議修改硬 件設(shè)計,增加RAM資源。 RAM資源規(guī)劃好后,應(yīng)列出一張RAM資源 的詳細(xì)分配清單,作為編程依據(jù)。 4.1.4編程與調(diào)試編程與調(diào)試 上述各項準(zhǔn)備工作都完成后,就可以開始編程了。 軟件設(shè)計有兩種方法:一種是自上而下,逐步細(xì)化; 一種是自下而上,先設(shè)計出每一個具體的模塊(子程序), 然后再慢慢擴大,最后組成一個系統(tǒng)。兩種方法各有 優(yōu)缺點。 單片機由于本身沒有開發(fā)能力,故編程均在各種 類型的開發(fā)系統(tǒng)上進行?;具^程是相同的:用編輯 軟件編輯出源程序,再用編譯軟件生成目標(biāo)代碼,如 果源程序中有語法錯誤則返回編輯過程,修改源程序 后再繼續(xù)

11、編譯,直到通過這一關(guān)。然后對程序進行測 試,糾正測試中發(fā)現(xiàn)的錯誤。接著就在開發(fā)系統(tǒng)上仿 真運行,試運行中將會發(fā)現(xiàn)不少設(shè)計錯誤(不是語法錯 誤),再從頭修改源程序,如此反復(fù)直到基本成功,就 可以投入實際環(huán)境中使用。 4.24.2匯編語言源程序的編輯和匯編匯編語言源程序的編輯和匯編 用助記符和標(biāo)號地址編寫的程序稱 為匯編語言源程序;而將助記符翻譯成機 器碼以及將標(biāo)號地址換算成實際地址的 工作都由計算機通過一種稱為匯編程序 的軟件完成,這種翻譯和換算的過程一 般就稱為匯編。 4.2.1匯編語言源程序的格式匯編語言源程序的格式 一般來講,匯編語言源程序由四部分組成,即標(biāo) 號、操作碼、操作數(shù)和注釋。每兩

12、個部分之間要用分 隔符隔開,而每一部分內(nèi)部不采用分割符??梢圆捎?的分割符有:空格“ ”、冒號“:”、分號“;”, 空格的數(shù)目可以不止一個。 匯編語言源程序的一般形式為: 標(biāo)號:操作碼 操作數(shù) ;注釋 方括號 在實際程序中并不書寫,也不輸入到計算機里, 只是表示方括號內(nèi)的項是任選項,此項可有可無,若 不需要時,在某一行可以不包括此項。故對每一行源 程序來說,只有操作碼是必不可少的,其余三部分都 可視情況而定。 匯編程序只處理分號“;”以前的 字符,對于注釋部分,計算機在匯編時 不予處理。注釋部分便于程序的使用者 更好地理解程序的功能,有助于程序的 交流使用。軟件工作者從一開始就要養(yǎng) 成寫好注釋

13、的良好習(xí)慣。 對于有些指令,操作數(shù)不止一個, 有兩個甚至三個,在輸入計算機時,各 操作數(shù)之間要用逗號作分割符。 一、標(biāo)號一、標(biāo)號 標(biāo)號由標(biāo)號由8個或個或8個以下的字母數(shù)字構(gòu)成,第個以下的字母數(shù)字構(gòu)成,第 一個必須是字母。一個必須是字母。另外還允許使用一個下橫線 符號“ ”。其它的符號都不允許在標(biāo)號中使 用。此外,系統(tǒng)中保留使用的字符或字符組不 能用作標(biāo)號,以免引起混淆。如各種特殊功能 寄存器名、各個位地址記憶符、各種偽指令等 都不能用作標(biāo)號。 以下是一些合法的標(biāo)號:A1,LOOP等。 以下的字符串不能用作標(biāo)號:4G,F(xiàn)-G, DB,EQU(后兩種為保留字)。 標(biāo)號不是每一行都必須要有,而只是在

14、需 要時才使用。 二、操作數(shù)二、操作數(shù) 對于立即數(shù)#data來說,使用時,一般都在 #后面跟一個具體的數(shù)。這個數(shù)可以是二進制 數(shù),應(yīng)以字母“B”作為結(jié)束,如#10010011B; 也可以是十六進制數(shù),則以字母“H”結(jié)尾,如 88H,但若最高位為AF之中的字母,則前面 還要加一個數(shù)字“0”,如#0ABH。如果這個0 忘了加上,匯編程序?qū)⒄J(rèn)為所寫的是一個編號。 如果數(shù)字的最后沒有結(jié)束字母,則認(rèn)為是十進 制數(shù),如#10。 立即數(shù)的data也可以用定義過的標(biāo)號來代 替,這種定義要用到偽指令EQU等。 對于直接地址direct來說,在實際使用時, 也可以有多種選擇: 1.二進制數(shù),十進制數(shù)或十六進制數(shù),

15、如:MOV A,30H等; 2.標(biāo)號地址,如:MOV A,SUM等,SUM應(yīng)該在 程序中某處加以定義; 3.帶加減的表達(dá)式,如:MOV A,SUM+9,SUM 為已定義的符號地址; 4.特殊功能寄存器名,如:MOV A,SP等。 對于偏移量rel,除了可以采用上面提到的各種數(shù) 值、標(biāo)號地址以及表達(dá)式之外,還可以采用一個專門 的符號“$”,它表示相對轉(zhuǎn)移指令所在的地址,例如: LJMP $ 這條指令實際上是一條自身跳轉(zhuǎn)的死循環(huán)。在實 際 編 程 時 , 凡 是 指 令 中 用 到 地 址 的 地 方 (rel,addr11,addr16)都用標(biāo)號地址代替實際地址,而將復(fù) 雜的地址運算交給匯編程序

16、完成。 4.2.2偽指令偽指令 每種匯編語言都會定義若干偽指令, 用來對匯編過程進行某種控制,或?qū)Ψ?號、標(biāo)號賦值。偽指令和指令是完全不 同的。在匯編過程中,由于偽指令并不 執(zhí)行可執(zhí)行的目的代碼,因而大部分偽 指令甚至不會影響存儲器中的內(nèi)容。對 不同版本的匯編語言,偽指令的符號和 含義可能不同,但基本的用法是相似的。 下面就介紹一些常用的偽指令。 一、一、ORG(匯編起始命令匯編起始命令) 其功能是規(guī)定下面的目標(biāo)程序的起始地址,指令 格式為: 標(biāo)號:ORG addr16 其中括號內(nèi)是任選項,可以沒有,例如: ORG 1000H LAB:MOV A,#3H 即,規(guī)定了標(biāo)號LAB所在的起始地址為1

17、000H, 第一條指令就從1000H開始存放。 一般在一個匯編語言源程序的開始,都用一條 ORG偽指令來規(guī)定程序存放的起始位置,故稱 為匯編起始命令。 二、二、END(匯編結(jié)束命令)(匯編結(jié)束命令) END是匯編語言源程序的結(jié)束標(biāo)志,在END以后 所寫的指令,匯編程序都不予處理。一個源程序只能 有一個END命令。在同時包含有主程序和子程序的系 統(tǒng)中,也只能有一個END命令,并存放到所有指令的 最后,否則,就有一部分指令不能被匯編。其格式為: 標(biāo)號:END 三、三、EQU(等值命令)(等值命令) 其功能是將一個數(shù)或者特定的匯編符號賦予規(guī)定 的符號名稱,其格式為: 字符名稱 EQU數(shù)或匯編符號 例

18、如: INPEQUP1 MOV A,INP 這里將INP等值為匯編符號P1,在指令中INP就可以代 替P1來使用。 四、四、DATA(數(shù)據(jù)地址賦值命令)(數(shù)據(jù)地址賦值命令) 其功能是將數(shù)據(jù)地址或代碼地址賦予規(guī)定的字符 名稱,其格式為: 字符名稱DATA表達(dá)式 DATA偽指令的功能和EQU有些相似,使用時要注意 它們的差別: (1)EQU偽指令定義的符號必須先定義后使用,而 DATA偽指令的符號可以先使用后定義; (2)用EQU偽指令可以把一個匯編符號賦給一個字符 名稱,而DATA偽指令則不能。 (3)DATA偽指令可將一個表達(dá)式的值賦給一個字符 名稱,所定義的字符名稱也可以出現(xiàn)在表達(dá)式中,而

19、用EQU定義的字符則不能這樣使用。 (4)DATA偽指令常在程序中用來定義數(shù)據(jù)地址。 五、五、DB(定義字節(jié)指令)(定義字節(jié)指令) 其功能是從規(guī)定的地址單元開始,定義若干個8位內(nèi) 存單元的內(nèi)容,其格式為: 標(biāo)號:DB8位數(shù)據(jù)表 這個偽指令是在程序存儲器的某一部分存入一組規(guī) 定好的8位二進制數(shù),或者是將一個數(shù)據(jù)表格存入程序 存儲器。這個偽指令在匯編后,將影響程序存儲器的 內(nèi)容。例如: TAB1: DB3FH,55,8,C TAB2: DB10100B 設(shè)TAB1的對應(yīng)地址為2000H,則以上偽指令經(jīng)匯編 以后,將對2000H開始的若干內(nèi)存單元賦值: (2000H)=3FH(2001H)=37H

20、(2002H)=38H(2003H)=43H (2004H)=14H 六、六、DW(定義字命令)(定義字命令) 其功能是從指定地址開始,定義若干個16位數(shù)據(jù), 其格式為: 標(biāo)號:DW16位數(shù)據(jù)表 每個16位數(shù)據(jù)要占ROM的兩個單元,在MCS-51系 統(tǒng)中,16位二進制數(shù)的高8位先存入低地址字節(jié),低8 位后存入高地址字節(jié)。這和MCS-51指令中的16位數(shù)據(jù) 存放的方式一致。 例如: ORG1000H DW 3964H,6H,20 匯編以后結(jié)果為: (1000H)=39H(1001H)=64H(1002H)=00H (1003H)=6H (1004H)=00H(1005H)=14H 七、七、BIT

21、(位地址符號命令)(位地址符號命令) 其功能是將位地址賦予所規(guī)定的字符名稱, 其格式為: 字符名稱 BIT位地址 例如: RECORD BITP2.2 PLAYBITP2.3 這樣就把兩位位地址分別賦給兩個變量 RECORD和PLAY,在編程中它們可當(dāng)作位地 址來使用。但不是所有的MCS-51匯編程序都 有這條偽指令。當(dāng)不具備BIT命令時,可以使 用EQU命令來定義位地址變量,但這時所賦的 值應(yīng)該是具體的位地址,例如P1.0就要具體地 用90H來代替。 4.2.3源程序的編輯和匯編源程序的編輯和匯編 源程序的編輯可以使用任何可編輯和存儲文本格 式的文件編輯器,如Windows操作系統(tǒng)提供的寫字

22、板 (Wordpad)和筆記本(Notebook)、Word文字處理器和各 種單片機集成開發(fā)軟件如MEDWIN、MPLAB、WAVE 等。 用文本文件編輯器編輯和匯編單片機程序的過程如 下: (1)用文件編輯器編輯匯編語言源程序,它的擴展 名為.ASM; (2)經(jīng)檢查無明顯的語法錯誤后,再采用單片機匯 編程序ASM51進行匯編,產(chǎn)生擴展名為.LST的列表輸 出文件和擴展名為.HEX的目標(biāo)代碼文件; 列表輸出文件:包含源程序語句所匯編成的代碼,以及有 關(guān)的地址、語句和符號表等; 目標(biāo)代碼文件:包含源程序語句所匯編成的代碼,不包含 任何符號信息或助記符。 用單片機集成開發(fā)軟件編輯和匯編單片機程序的

23、過程如下: (1)在集成開發(fā)環(huán)境中編輯器編輯匯編語言源程序,它的擴 展名為.ASM; (2)在集成開發(fā)環(huán)境中設(shè)置編譯所采用的正確匯編程序(一般 為ASM51)后,用鼠標(biāo)點擊編譯工具條或菜單可直接進行匯編。若 源程序無語法錯誤,會產(chǎn)生擴展名為.LST的列表輸出文件和擴展 名為.BIN(或.HEX)的目標(biāo)代碼文件;若源程序有語法錯誤,一般 不會產(chǎn)生列表輸出文件和目標(biāo)代碼文件,但會彈出一個信息窗口, 指示出錯位置和錯誤類型。用鼠標(biāo)點擊出錯指示信息,會直接跳 到源程序出錯語句,修改正確后,再一次編譯,則會彈出信息窗 口指示匯編成功,源程序無語法錯誤,并產(chǎn)生相應(yīng)的目標(biāo)代碼文 件和列表輸出文件。 4.34

24、.3匯編語言程序設(shè)計匯編語言程序設(shè)計 4.3.14.3.1程序流程圖設(shè)計及子程序設(shè)計程序流程圖設(shè)計及子程序設(shè)計 一、程序流程圖一、程序流程圖 1 概述概述 編制程序的正確做法是先畫程序流程圖,再開始 編程,而不是編完程序后再補畫程序流程圖。程序流 程圖在“高級語言程序設(shè)計”相關(guān)課程中大家已熟悉, 它是一種以框圖形式表示程序結(jié)構(gòu)的。畫程序流程圖 的過程是進行程序的邏輯設(shè)計過程,這中間的任何錯 誤或忽視將會導(dǎo)致程序出錯或可靠性下降??梢哉J(rèn)為 真正的程序設(shè)計過程是流程圖設(shè)計,而上機編程是將 設(shè)計好的程序流程圖轉(zhuǎn)換成程序設(shè)計語言而已。 2. 程序流程圖的畫法程序流程圖的畫法 正確的流程圖畫法是先粗后細(xì)

25、、一步一個腳印, 只考慮邏輯結(jié)構(gòu)和算法,不考慮或少考慮具體指令。 這樣畫流程圖就可以集中精力考慮程序的結(jié)構(gòu),從根 本上保證程序的合理性和可靠性,剩下來的任務(wù)只是 進行指令代換,這時只要消除語法錯誤,一般就能順 利編出源程序,并且很少大返工。下面用一個例子來 說明流程圖的畫法:有一數(shù)據(jù)采集系統(tǒng),將采集到的 一批數(shù)據(jù)存放在片外RAM中,數(shù)據(jù)類型為雙字節(jié)十六 進制整數(shù),存放格式為順序存放,高字節(jié)在前(低地 址),低字節(jié)在后(高地址),數(shù)據(jù)塊的首址已知, 數(shù)據(jù)總個數(shù)(不超過256)也已知。現(xiàn)要設(shè)計一個程序, 計算下列公式的值: 式中,n為數(shù)據(jù)總個數(shù),Xi為某個數(shù)據(jù),為這n個 數(shù)據(jù)的平均值。要求最后結(jié)果

26、以BCD碼百分?jǐn)?shù) 表示,并精確到0.1%。 第一步第一步,先進行最原始的規(guī)劃,畫第一張 程序流程圖,如圖4-2所示。在畫第一張程序流 程圖時,將總?cè)蝿?wù)分解成若干個子任務(wù),安排 好它們之間的相互關(guān)系,暫不管各個子任務(wù)如 何完成。這一步看起來簡單,但千萬不能出錯, 這一步錯誤是屬于宏觀決策錯誤,有可能造成 整體推倒重來。 %100)( 1 11 2 1 n i i XX nX V 圖4-2 開始 求X 求 求 開平方 求V 結(jié)束 n i i XX 1 2 1 1 n 第二步第二步,將第一張流程圖的各個子 任務(wù)進行細(xì)化。決定每個子任務(wù)采用哪 種算法,而暫不考慮如何為數(shù)據(jù)指針、 計數(shù)器、中間結(jié)果配置存

27、放單元等具體 問題。由于內(nèi)容比第一張詳細(xì),如果全 圖畫在一起不方便,可以分開畫,但要 注意各分圖之間的連接關(guān)系。第二張流 程圖如圖4-3所示。 圖圖4-3 開始 初始化累加和SUM=0; 數(shù)據(jù)指針i=1;計數(shù)器 m=n SUM=SUM+Xi i=i+1 M=m-1 M=0? 初始化SUM=0; i=1;m=n i=i+1;M=m-1 M=0? 調(diào)開平方子程序 V=100%P 調(diào)用子程序 轉(zhuǎn)換為BCD碼 結(jié)束 YY NN US i XXi ii i 2 2 i SUMSUM XSP/ nSUMX/ )1/(nSUMX 畫出第二張流程圖后,還不能馬上就進行編程, 這時往往需要畫第三張流程圖,用它來

28、指導(dǎo)編程。第 三張流程圖以資源分配為策劃重點,要為每一個參數(shù)、 中間結(jié)果、各種指針、計數(shù)器分配工作單元,定義數(shù) 據(jù)類型和數(shù)據(jù)結(jié)構(gòu)。在進行這一步工作時,要注意上 下左右的關(guān)系,本模塊的入口參數(shù)和出口參數(shù)的格式 要和全局定義一致,本程序要調(diào)用低級子程序時,要 和低級 子程序發(fā)生參數(shù)傳遞,必須協(xié)調(diào)好它們之間的數(shù) 據(jù)格式。本模塊中各個環(huán)節(jié)之間傳遞中間結(jié)果時,其 格式也要協(xié)調(diào)好。在定點數(shù)系統(tǒng)中,中間結(jié)果存放格 式要仔細(xì)設(shè)計,避免發(fā)生溢出,精度損失。一般中間 結(jié)果要比原始數(shù)據(jù)范圍大,精度高,才能使最終結(jié)果 可靠。 設(shè)數(shù)據(jù)塊首址在3EH和3FH,數(shù)據(jù)總個數(shù) 在3DH中。在求平均值的子任務(wù)中,用R2、R3、

29、R4存放累加和,用DPTR作數(shù)據(jù)指針,用R7作 計數(shù)器,R5和R6作機動單元。這樣規(guī)劃后,第 三張流程圖的求子程序部分就可以畫出來,如 圖4-4所示。與第二張流程圖相比,每一個變量 都使具體的,由此來編程就很容易了。 對于編程經(jīng)驗比較豐富的人員,有時可以 不畫第三張程序流程圖,在設(shè)計好第二張程序 流程圖后,再編制一張資源分配表,用這張資 源分配表對照第二張程序流程圖就可以開始進 行編程。 圖圖4.4 開始 初始化R2,R3,R4 =0;DPTR=(3F、3EH )R7=(3DH) 讀取Xi并暫存R5,R6=Xi R7=0? (R2,R3,R4)= (R2, R3,R4)+(R5,R6) 調(diào)整D

30、PTR,指向下一個數(shù)據(jù) R7= R7-1 R7=(3DH) (R3,R4,R5)=(R2,R3,R4)/R7 3.從程序流程圖到程序從程序流程圖到程序 畫好程序流程圖后,就可以比較方便地進行編程 了。從流程圖到程序的過程發(fā)生了兩個變化,形式上 從二維圖形變成了一維的程序,內(nèi)容上從功能描述變 成了具體的指令實現(xiàn)。 將功能描述變成具體指令實現(xiàn)的過程,一般不會 有什么問題,因為算法過程和資源分配已經(jīng)規(guī)劃好了。 如實現(xiàn)(R2,R3,R4)= (R2, R3,R4)+(R5,R6)的指令串如下: MOV A,R6 ADDA,R4 MOV R4,A MOV A,R5 ADDCA,R3 MOV A,R2 A

31、DDCA,#0 MOV R2,A 二、子程序設(shè)計二、子程序設(shè)計 1.結(jié)構(gòu)化的程序設(shè)計風(fēng)格結(jié)構(gòu)化的程序設(shè)計風(fēng)格 不僅總體應(yīng)用程序要設(shè)計成模塊式結(jié)構(gòu),子程序 也應(yīng)按結(jié)構(gòu)化設(shè)計成具有模塊特性:一個輸入口和一 個輸出口,且子程序的內(nèi)部也設(shè)計成由若干個小模塊 組成。這種模塊特性對測試很有利,功能擴展也很方 便,要增加新功能,只要增加新模塊就能實現(xiàn),象搭 積木一樣。模塊有如下四種基本結(jié)構(gòu): (1) 順序結(jié)構(gòu)(DO結(jié)構(gòu)) 模塊內(nèi)各個子過程按先后次序排列和執(zhí)行。如圖4-2所示 流程圖即為順序結(jié)構(gòu)。 (2) 選擇(分支)結(jié)構(gòu)(IF結(jié)構(gòu)) 模塊內(nèi)各個子過程是相互排斥的。按某條件進行選擇, 被選中的子過程被執(zhí)行,如

32、圖4-6(a)所示。A、B子過 程中可以有一個是空過程,如圖4-5(a)中的b選擇結(jié)構(gòu) 就有一邊是空過程。 IF BA IF A IF CB IF CAB Y N Y N Y N (a) (b) (c) 圖圖4-6 IF結(jié)構(gòu)結(jié)構(gòu) 選擇結(jié)構(gòu)有兩種常用變形。如果圖4-6(a)中的B執(zhí)行塊本身也 是選擇結(jié)構(gòu),就變?yōu)閳D4-6(b)所示的多級選擇結(jié)構(gòu),常稱為分選 (篩選)結(jié)構(gòu);如果互斥的執(zhí)行塊較多,常用一種“散轉(zhuǎn)”結(jié)構(gòu), 如圖4-6(c)所示,通過對某一索引值進行運算,直接選中某一執(zhí)行 塊。 (3)循環(huán)結(jié)構(gòu)(WHILE或FOR結(jié)構(gòu)) WHILE結(jié)構(gòu) 模塊內(nèi)只有一個執(zhí)行塊,但在執(zhí)行前要先對某條件進行檢查,

33、 當(dāng)條件成立(為真)時執(zhí)行該模塊,如果條件不成立(為假)則 退出該模塊。執(zhí)行后繼續(xù)檢查條件,如果仍然成立,則還要執(zhí)行, 如圖4-7所示。 FOR結(jié)構(gòu) 這種結(jié)構(gòu)和WHILE結(jié)構(gòu)有相似的地方,且可多次執(zhí)行,但控制 次數(shù)方法不同,如圖4-8所示。這種結(jié)構(gòu)引入一個循環(huán)控制變量I, 在進入模塊時,對I進行初始化,賦以初值I0,然后執(zhí)行其中的實 質(zhì)程序塊(循環(huán)體),執(zhí)行完一遍后控制變量進行調(diào)整,增加一 個步長量,例如加1,再和預(yù)定終值比較,達(dá)到或超過終止值就停 止循環(huán),退出模塊,否則繼續(xù)執(zhí)行。 N Y N Y N Y 圖4-7 WHILE 結(jié)構(gòu) 圖4-8 FOR結(jié)構(gòu) 圖4-9 REPEAT結(jié)構(gòu) 判斷 執(zhí)行

34、塊判斷 執(zhí)行塊 IIe 循環(huán)體 I=I0 I=I+ (3)重復(fù)結(jié)構(gòu)(重復(fù)結(jié)構(gòu)(REPEAT結(jié)構(gòu))結(jié)構(gòu)) 這種結(jié)構(gòu)和WHILE結(jié)構(gòu)類似,模塊中也只有一個 執(zhí)行塊和一個條件判斷過程,但先后次序不同,如圖 4-9所示。這種結(jié)構(gòu)是先執(zhí)行后判斷,如果某條件尚未 成立則反復(fù)執(zhí)行,直到某條件成立為止,故有時又稱 這種結(jié)構(gòu)叫“直到”結(jié)構(gòu)。 2.參數(shù)的傳遞參數(shù)的傳遞 子程序在執(zhí)行過程中,有時要使用一些數(shù)據(jù);子 程序運行后,產(chǎn)生的一些數(shù)據(jù)有時要被主程序使用。 也就是參數(shù)在主程序和子程序之間的傳遞問題。以主 程序傳遞參數(shù)給子程序為例,基本上可分為三種方法: (1)通過存儲單元傳遞。子程序有自己的參數(shù)存放 單元,如工

35、作寄存器R0R7,主程序?qū)⒁獋鬟f的參數(shù) 復(fù)制到工作寄存器指定的單元中,就可以調(diào)用該子程 序了。 例例4-1 用這種方法調(diào)用雙字節(jié)十六進制整數(shù)轉(zhuǎn)換成雙字節(jié) BCD碼整數(shù)的子程序HTB2,待轉(zhuǎn)換的雙字節(jié)十六進制 整數(shù)在R7R6中,轉(zhuǎn)換后三字節(jié)BCD碼整數(shù)在R5R4R3 中,主程序和子程序如下: MAIN: MOV R7,#12H MOV R6,#34H ACALL HTB2 HTB2:CLR A MOV R3,A MOV R4,A MOV R5,A MOV R2,#10H RLC A MOV R7,A HTB3:MOV A,R7 RET (2)通過指針傳遞。主程序?qū)χ羔槪ɡ鏡0,R1) 進行賦值

36、,使它指向要傳遞的參數(shù)存放的位置,然后 調(diào)用子程序。子程序通過指針,用間接尋址的方式來 使用參數(shù)。 例例4-2 用這種方法調(diào)用將RAM數(shù)據(jù)區(qū)清零子程序SUBBT的主程序和子程 序為: MAIN: MOV R0,#30H;傳遞RAM數(shù)據(jù)區(qū)的起始地址 MOV R7,#0AH;傳遞RAM數(shù)據(jù)區(qū)的長度 ACALL SUBBT SUBBT:MOV A,#00H;將片內(nèi)RAM的一組單元清零子程序 LOOP: MOV R0,A INC R0 DJNZ R7,LOOP RET (3)通過堆棧傳遞參數(shù) 例例4-3 仍以RAM數(shù)據(jù)區(qū)清零為例,假定數(shù)據(jù)區(qū)的起始地址預(yù)先存放在70H單 元,被清零單元的個數(shù)預(yù)先存放在7

37、1H單元,則主程序為: MAIN: PUSH 70H;將起始地址送堆棧 PUSH 71H;將數(shù)據(jù)區(qū)長度送堆棧 ACALL SUBBT;調(diào)用清零子程序 為了適應(yīng)這種方法,子程序SUBBT應(yīng)作如下變動: SUBBT:POP DPH;將返回地址送到DPTR中暫存 POP DPL POP R7;取出數(shù)據(jù)區(qū)長度 POP R0;取出數(shù)據(jù)區(qū)首址 SUB1: MOV A,#00H LOPP: MOV R0,A INC R0 DJNZ R7,LOOP PUSH DPL;將返回地址送堆棧 PUSH DPH RET (3)通過堆棧傳遞參數(shù)通過堆棧傳遞參數(shù)。通過PUSH,POP指令完成對參數(shù)的 交換工作。 例例4-3

38、仍以RAM數(shù)據(jù)區(qū)清零為例,假定數(shù)據(jù)區(qū)的起始地址預(yù)先存放在 70H單元,被清零單元的個數(shù)預(yù)先存放在71H單元,則主程序為: MAIN: PUSH 70H;將起始地址送堆棧 PUSH 71H;將數(shù)據(jù)區(qū)長度送堆棧 ACALL SUBBT;調(diào)用清零子程序 為了適應(yīng)這種方法,子程序SUBBT應(yīng)作如下變動: SUBBT:POP DPH ;將返回地址送到DPTR中暫存 POP DPL POP R7;取出數(shù)據(jù)區(qū)長度 POP R0;取出數(shù)據(jù)區(qū)首址 SUB1: MOV A,#00H LOPP: MOV R0,A INC R0 DJNZ R7,LOOP PUSH DPL;將返回地址送堆棧 PUSH DPH RET

39、(4)隱含參數(shù)傳遞方式隱含參數(shù)傳遞方式。主程序直接調(diào)用子程序, 要使用的參數(shù)已隱含在子程序之中了。例如固定延時 子程序和特定操作子程序等。在這種參數(shù)傳遞方法中, 有的是以立即數(shù)方式在指令中給出,有的是以絕對地 址方式給出參數(shù)存放地址。 3子程序設(shè)計其它要求 子程序的設(shè)計要求滿足:對主程序具有很好的透 明性;各子程序具有相容性,即一個子程序的出口現(xiàn) 場與后續(xù)子程序的入口條件互相兼容,主程序不需要 進行協(xié)調(diào)工作,只要為每個子程序補充新的操作數(shù)就 可以了;子程序容錯性,即子程序除了能在正常情況 下完成指定功能外,還應(yīng)能處理異常情況,及時發(fā)現(xiàn) 并妥善處理,從而保證系統(tǒng)不出現(xiàn)重大事故。 4.3.2 順序

40、程序設(shè)計順序程序設(shè)計 順序結(jié)構(gòu)程序是指一種無分支的直接執(zhí)行程序, 即從第一條指令開始依次執(zhí)行每一條指令,直到最后 一條,程序就算執(zhí)行完。這種程序雖然比較簡單,但 也能完成一定的功能,并且往往也是構(gòu)成復(fù)雜程序的 基礎(chǔ)。 例例4-44-4 將十六進制數(shù)表示的ASCII代碼轉(zhuǎn) 換成4位二進制數(shù)。 我們知道,“字符0”“字符9”的ASCII碼值為 “30H”“39H”,它們與30H之差恰好為“00H”“09H”, 結(jié)果均0則轉(zhuǎn)移到LOP1 MOV A,#0FFH;X0則Y=-1 SJMP LOP2 LOP1:MOV A,#01H LOP2:MOV DATA2,A 01 00 01 X X X Y ,

41、, , 二、散轉(zhuǎn)程序 散轉(zhuǎn)程序是一種并行分支程序,它能根據(jù)某種輸 入或運算結(jié)果分別轉(zhuǎn)向各個操作程序。在MCS-51中, 提供了散轉(zhuǎn)指令JMP A+DPTR來實現(xiàn)散轉(zhuǎn)。該指令 把累加器A的8位無符號數(shù)與16位數(shù)據(jù)指針的內(nèi)容相加, 并把相加的結(jié)果裝入程序計數(shù)器PC,控制程序轉(zhuǎn)向目 標(biāo)地址去執(zhí)行。 1采用轉(zhuǎn)移指令表的散轉(zhuǎn)程序 在許多場合下,需要根據(jù)標(biāo)志單元的內(nèi)容是0,1, 2,n分別轉(zhuǎn)向散轉(zhuǎn)操作程序0,1,2,n。這 時,可以先用無條件轉(zhuǎn)移指令A(yù)JMP或LJMP按序組成 一個轉(zhuǎn)移表,將標(biāo)志單元的內(nèi)容裝入累加器A作為變址 值,然后執(zhí)行指令: JMP A+DPTR 實現(xiàn)轉(zhuǎn)移。 例例4-6 要求根據(jù)R7的

42、內(nèi)容轉(zhuǎn)向各個操作程序。即當(dāng) R7=0,轉(zhuǎn)向OP0 R7=1,轉(zhuǎn)向OP1 R7=n,轉(zhuǎn)向OPn 程序清單如下: JMPP1:MOV DPTR,#JPTAB;指向轉(zhuǎn)移表 MOV A,R7 ADD A,R7;修正變址值 JNC NADD;判斷有否進位 INC DPH;有進位加到高字節(jié)地址 NADD:JMP A+DPTR;轉(zhuǎn)向形成的散轉(zhuǎn)地址 JPTAB:AJMP OP0;轉(zhuǎn)移指令表 AJMP OP1 AJMP OPn 2采用地址偏移量表的散轉(zhuǎn)程序采用地址偏移量表的散轉(zhuǎn)程序 如果散轉(zhuǎn)點較少,而且所有操作程序處在同一頁(256B)內(nèi), 則可以使用地址偏移量表的方法實現(xiàn)散轉(zhuǎn)。 例例4-7 要求按R7的內(nèi)容轉(zhuǎn)

43、向5個操作程序。程序清單如下: JMPP2:MOV A,R7 MOV DPTR,#TAB2;指向地址偏移量表 MOVC A,A+DPTR;散轉(zhuǎn)點入口地址在A中 JMP A+DPTR;轉(zhuǎn)向相應(yīng)的操作程序入 TAB2:DB OP0-TAB2;地址偏移量表 DB OP1-TAB2 DB OP2-TAB2 DB OP3-TAB2 DB OP4-TAB2 OP0: (操作程序0) OP1: (操作程序1) OP2: (操作程序2) OP3: (操作程序3) OP4: (操作程序4) 3采用轉(zhuǎn)向地址表的散轉(zhuǎn)程序采用轉(zhuǎn)向地址表的散轉(zhuǎn)程序 前面討論的采用地址偏移量表的方法,其轉(zhuǎn)向范圍局限于一頁之內(nèi),在使 用時

44、,受到較大的限制。若需要轉(zhuǎn)向較大的范圍,可以建立一個轉(zhuǎn)向地址表,即 將所要轉(zhuǎn)向的二字節(jié)地址組成一個表,在散轉(zhuǎn)時,先用查表的方法獲得表中的轉(zhuǎn) 向地址,并將該地址裝入數(shù)據(jù)指針DPTR中,然后清除累加器A,執(zhí)行JMP A+DPTR指令,便能轉(zhuǎn)向到相應(yīng)的操作程序中去。 例例4-8 要求根據(jù)R7的內(nèi)容轉(zhuǎn)向相應(yīng)的操作程序中去。設(shè)各操作程序的轉(zhuǎn)向地址分別為OP0, OP1,OPn。 程序清單如下: JMPP3:MOV DPTR,#TAB3;指向轉(zhuǎn)向地址表 MOV A,R7 ADD A,R7 JNC NADD INC DPH NADD:MOV R3,A MOVC A,A+DPTR;取轉(zhuǎn)向地址高8位 XCH A

45、,R3 INC A MOVC A,A+DPTR;取轉(zhuǎn)向地址低8位 MOV DPL,A MOV DPH,R3 CLR A JMP A+DPTR TAB3:DW OP0 DW OP1 DW OPn 4.3.44.3.4循環(huán)程序設(shè)計循環(huán)程序設(shè)計 前面講過,循環(huán)有WHILE和FOR兩種結(jié)構(gòu), 為了構(gòu)成循環(huán)程序,DJNZ指令是很有用的, 特別是在根據(jù)計數(shù)器的值決定循環(huán)是否結(jié)束時 可以直接使用。但也可以根據(jù)其它條件來判斷 循環(huán)結(jié)束條件。 例例4-94-9 內(nèi)存中以STRING開始的區(qū)域有若干 個字符和數(shù)字,一般稱為一個字符串,最末一 個字符為“$”,試統(tǒng)計這些字符數(shù)字的數(shù)目, 結(jié)果存入NUM單元。 本題可

46、采用WHILE結(jié)構(gòu),用CJNE指令來和關(guān)鍵字 符作比較,比較時要將關(guān)鍵字符用其對應(yīng)的ASCII碼來 表示。符號“$”的ASCII碼是24H。 NUMDATA20H STRINGDATA21H CLR A;A作為計數(shù)器,先清零 MOV R0,#STRING;首地址送R0 LOP: CJNE R0,#24H,LOP2;與$比較,不等轉(zhuǎn)移 SJMP LOP3;找到$,結(jié)束循環(huán) LOP2:INC A;計數(shù)器加1 INC R0;修改地址指針 SJMP LOP;循環(huán) LOP3: INC A;再計這個$字符 MOV NUM,A;存結(jié)果 4.3.5查表程序設(shè)計查表程序設(shè)計 如果一元單值函數(shù)的解析式比較復(fù)雜,那

47、么,基 于這種函數(shù)關(guān)系,采用查表法往往使得問題得解決要 簡單得多。所謂查表法,就是預(yù)先將滿足一定精度要 求的表示變量x與函數(shù)y=f(x)值之間關(guān)系的一張表求出, 然后把這張表存于單片機的程序存儲器中。這時自變 量值為單元地址,相應(yīng)的函數(shù)值為該地址單元中的內(nèi) 容。而查表就是根據(jù)給定的自變量x,在表格中查找y, 使y=f(x)。 在MCS-51中,查表時的數(shù)據(jù)表格是存放在程序 ROM而不是數(shù)據(jù)RAM中。相應(yīng)地,用于查表的指令有 兩條: MOVC A,A+DPTR MOVC A,A+PC 使用DPTR作為基地址查表比較簡單,可通過三步 操作來完成: (1)將所查表格的首地址存入DPTR數(shù)據(jù)指針寄存器

48、; (2)將所查表格的項數(shù)(即在表中的位置是第幾項)送累加器 A; (3)執(zhí)行查表指令MOVC A,A+DPTR進行讀數(shù),查表結(jié)果 送回累加器A。 若使用PC作為基地址查表,則操作有所不同,也可 分為三步: (1)將所查表格的項數(shù)送累加器A,在MOVC A,A+PC指令 之前先寫上一條ADD A,#data指令,data的值待定; (2)計算從MOVC A,A+PC指令執(zhí)行后的地址到所查表的首 地址之間的距離(以字節(jié)數(shù)表示),用這個計算結(jié)果取代加法指 令中的data,作為A的調(diào)整量; (3)執(zhí)行查表指令MOVC A,A+PC進行查表,查表結(jié)果送回 累加器A。 例例4-10 在一個溫度測量裝置中

49、,測出的 電壓與溫度為非線性關(guān)系。設(shè)測得電壓值為x, 用10位二進制數(shù)表示(占2B)?,F(xiàn)要求采用查 表法實現(xiàn)線性化處理。 這個問題的解決辦法是,先通過實驗測出 與1024(210)個電壓值相對應(yīng)的溫度值,并按 電壓由小到大的順序構(gòu)造一個表,表中存放溫 度值y(一個定字長數(shù),高字節(jié)在前),則: 存放溫度值y的單元地址=表首址+(x*2) 設(shè)測得電壓值x已存放在20H,21H單元中(高字 節(jié)在20H),查表得到的溫度值y存放在22H, 23H(高字節(jié)在22H單元)。查表程序如下: STB1:MOV DPTR,#TAB;首址送DPTR MOV A,21H;(20H)(21H)乘2 CLR C RLC

50、 A MOV 21H,A MOV A,20H RLC A MOV 20H,A MOV A,21H;表首址+(x*2) ADD A,DPL MOV DPL,A MOV A,20H ADDC A,DPH MOV DPH,A CLR A MOVC A,A+PC ;查表得溫度值高位字節(jié) MOV 22H,A;存放高字節(jié) INC DPTR;指向溫度低位字節(jié) CLR A MOVC A,A+PC ;查表得溫度值高低字節(jié) MOV 23H,A;存放低字節(jié) RET TAB:DW ;溫度值表 4.4綜合程序應(yīng)用編程綜合程序應(yīng)用編程 單片機常用于測控領(lǐng)域,其中智能儀表是最典型的 單片機應(yīng)用系統(tǒng)。它具有典型的硬件電路和軟

51、件結(jié)構(gòu)。 因此,智能儀表系統(tǒng)最有可能實現(xiàn)硬件的標(biāo)準(zhǔn)化和軟 件的模塊化。本節(jié)以智能儀表的應(yīng)用軟件設(shè)計為例說 明綜合程序應(yīng)用編程的問題。 4.4.1智能儀表的典型軟件結(jié)構(gòu)智能儀表的典型軟件結(jié)構(gòu) 智能儀表是一種較完整的單片機應(yīng)用系統(tǒng)。一般硬 件電路除基本擴展部分外,都配置有采集電路、顯示 器、按鍵、打印機等。相應(yīng)的軟件有采集控制、數(shù)據(jù) 處理、顯示、結(jié)果打印等。 圖4-10是智能儀表的一種典型軟件結(jié)構(gòu)。按其功能 可分為三部分,即初始化監(jiān)視程序、鍵功能散轉(zhuǎn)程序 和系統(tǒng)控制程序。 圖4-10智能儀表典型軟件結(jié)構(gòu) 圖4-11初始化監(jiān)視程序 正常? 系統(tǒng)測試 初始化 提示符顯示 鍵盤掃描 鍵按下? 初始化 監(jiān)

52、視程序 上電復(fù)位 鍵功能 散轉(zhuǎn)程序 系統(tǒng)控 制程序 4.5 C51程序設(shè)計簡介程序設(shè)計簡介 當(dāng)單片機用于一般商用和民用場合, 如作為掌上電腦微處理器時,對實時性 要求不高,但對編程的簡單和使用的方 便性提出了較高要求,這時采用高級語 言來設(shè)計單片機應(yīng)用程序就顯得較合適。 在這里介紹一種目前流行的MCS-51單片 機高級語言C51。 4.5.1 C51程序結(jié)構(gòu)程序結(jié)構(gòu) C51程序結(jié)構(gòu)與一般C語言沒有什么差別。一個C51程序大體上是一個 函數(shù)定義的集合,在這個集合中有且僅有一個名為main的函數(shù)(主函 數(shù))。主函數(shù)是程序的入口,主函數(shù)中的所有語句執(zhí)行完畢,則程序執(zhí) 行結(jié)束。在這里,其它函數(shù)稱為子函

53、數(shù)。下面所示一個C51程序的大體結(jié) 構(gòu): #include/*頭文件(包含庫函數(shù))*/ #define uint unsigned int/*數(shù)據(jù)類型符號定義*/ #define uchar unsigned char unchar bdata FLAG/*變量,數(shù)組等定義*/ void inport(uchar state)/*子函數(shù)*/ /*相關(guān)語句*/ main()/*主函數(shù)*/ /*相關(guān)語句*/ inport()/*子函數(shù)調(diào)用*/ 函數(shù)定義由類型、函數(shù)名、參數(shù)表和函數(shù)體四部 分組成。函數(shù)名是一個標(biāo)識符,標(biāo)識符都是大小可區(qū) 別的,最長為255個字符。參數(shù)表是用圓括號括起來的 若干參數(shù),項

54、項之間用逗號隔開。函數(shù)體是用大括號 括起來的若干C語句,語句與語句之間用分號隔開,最 后一個語句一般是return語句(在主函數(shù)中可以省略)。 每一個函數(shù)都返回一個值,該值由return語句中的表達(dá) 式指定(省略時為零)。函數(shù)的類型就是返回值的類 型。函數(shù)類型(除整型外)均需在函數(shù)名前加以指定。 C51函數(shù)的一般格式為函數(shù)的一般格式為: 類型 函數(shù)名(參數(shù)表) 參數(shù)說明; 數(shù)據(jù)說明部分; 執(zhí)行語句部分; 一個函數(shù)在程序中可以三種形態(tài)出現(xiàn)一個函數(shù)在程序中可以三種形態(tài)出現(xiàn):函數(shù)定義、 函數(shù)調(diào)用和函數(shù)說明。函數(shù)定義相當(dāng)于匯編中的一般 子程序。函數(shù)調(diào)用相當(dāng)于調(diào)用子程序的CALL語句,在 C51中,要普

55、遍地規(guī)定函數(shù)調(diào)用可以出現(xiàn)在表達(dá)式中。 函數(shù)定義和函數(shù)調(diào)用不分先后,但若調(diào)用在定義之前, 那么在調(diào)用前必須先進行函數(shù)說明。函數(shù)說明是一個 沒有函數(shù)體的函數(shù)定義,而函數(shù)調(diào)用則要求有函數(shù)名 和實參數(shù)表。 C51中函數(shù)分兩大類中函數(shù)分兩大類:一類是庫函數(shù),一類是用戶 定義函數(shù)。庫函數(shù)是C51在庫文件中已定義的函數(shù),其 函數(shù)說明在相關(guān)的頭文件中。這類函數(shù),用戶在編程 時只要用include預(yù)處理指令將頭文件包含在用戶文件 中,直接調(diào)用即可。用戶自己定義、自己調(diào)用的一類 函數(shù)。從某種意義上來看,C編程實際上是對一系列用 戶函數(shù)的定義和調(diào)用。 C51程序的編程要點總結(jié)如下程序的編程要點總結(jié)如下: 1C51語

56、言是由函數(shù)構(gòu)成的。一個C51源程序至少包含一個 函數(shù)(main),也可以包含一個main函數(shù)和其它子函數(shù)。因此, 函數(shù)是C程序的基本單位。被調(diào)用的函數(shù)可以是編譯器提供的庫 函數(shù),也可以是用戶根據(jù)需要自己編制設(shè)計的函數(shù)。 2一個函數(shù)由兩部分組成: (1)函數(shù)說明部分。包括函數(shù)名、函數(shù)類型、函數(shù)屬性、 函數(shù)參考(行參)、形式參數(shù)類型。一個函數(shù)名后 面必須跟一個圓括號,函數(shù)參數(shù)可以沒有,如main()。 (2)函數(shù)體,即函數(shù)說明部分下面的大括號內(nèi)部分。 如果一個函數(shù)內(nèi)有多個大括號,則最外層的一對 為函數(shù)體的范圍。 函數(shù)體一般包括: 變量定義。 執(zhí)行部分。由若干語句組成。 當(dāng)然,在某些情況下也可以沒有

57、變量定義部分。甚至既無變量 定義也無執(zhí)行部分。 3一個C51程序總是從main函數(shù)開始執(zhí)行,而不 論main函數(shù)在整個程序中的位置如何。 4C51程序書寫格式自由,一行內(nèi)可以寫幾個語 句,一個語句可以分寫在多行上。C51程序無行號。 5每個語句和數(shù)據(jù)定義的最后必須由一個分號。 分號是C51語句的必要組成部分。分號不可少,即使是 程序中最后一個語句也應(yīng)包含分號。 6C51語言本身沒有輸入輸出語句。輸入和輸出 的操作是由庫函數(shù)scanf和printf等函數(shù)來完成的。C51 對輸入輸出實行“函數(shù)化”。 7可以用/*/對C51程序中的任何部分作注釋。 一個好的、有使用價值的源程序都應(yīng)當(dāng)加上必要的注 釋

58、,以增加程序的可讀性。 4.5.2 C51程序編譯和連接程序編譯和連接 C51語言源程序是一個ASCII文件,可 采用任何標(biāo)準(zhǔn)的ASCII文本編輯器編寫, 擴展名為.C。源程序需經(jīng)過編譯和連接 轉(zhuǎn)換為機器語言后才能被CPU識別執(zhí)行。 現(xiàn)以文件名為SAMPLE.C源程序為例說 明編譯和連接的過程。 1編譯編譯 使用命令為: C51 源程序文件名(可選編譯控制項) 例如:C51 SAMPLE.C ROM(SMALL),將產(chǎn)生目標(biāo)文 件SAMPLE.OBJ,ROM選項用于決定程序內(nèi)存大小, 它影響轉(zhuǎn)移指令的編碼。SMALL表示以CALL和JMP 指令作為ACALL和AJMP指令的編碼,最大程序空間

59、可達(dá)2K字節(jié),整個用戶程序必須分布在這2K字節(jié)空間 內(nèi)。 2連接連接 編譯得到的目標(biāo)文件.OBJ中指令地址是浮動的,需通過 連接產(chǎn)生最后可執(zhí)行指令文件。使用命令為: L51 輸入列表TO 輸出文件控制列表 輸入列表:是一個由逗號分開的文件名表,該表中的文件是 可重定位的程序模塊,對于每個文件欲包含的模塊可被指定在括 號內(nèi)。一般格式為: 文件名(模塊名),文件名, 文件名必須指出擴展名,目標(biāo)文件使用擴展名“.OBJ”,庫 文件使用擴展名“.LIB”。模塊名輸入只有當(dāng)使用庫文件時才是有 用的。模塊名必須在文件名后括號內(nèi)指定,并且必須用逗號分開。 例:L51 SAMPLE.OBJ ,PROG1.OBJ,UTILITY.LIB(FPMUL,FPDIV) 輸出文件:是將產(chǎn)生的絕對程序模塊的名字,如果不給出名 字,則使用輸入文件表中第一個文件名(不帶擴展名)。必須注 意輸出文件名同時也用作映象文件(擴展名.M51)的基本名。 例:L51 SAMPLE.C TO SAMPLE.ABS 控制列表:包含命令行的命令和參數(shù),可能的參數(shù)按順序顯 示??刂泼羁稍谳敵鑫募笾付?,各控制命令以空格分開。如 果同一

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論