版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、4.1 概述 4.2 簡(jiǎn)單程序設(shè)計(jì) 4.3 分支程序設(shè)計(jì) 4.4 循環(huán)程序設(shè)計(jì) 4.5 查表程序 4.6 子程序設(shè)計(jì)與堆棧技術(shù) 4.7 實(shí)用匯編子程序舉例,第四章 程序設(shè)計(jì),4.1 概 述,單片機(jī)程序設(shè)計(jì)語(yǔ)言主要有三類(lèi):機(jī)器語(yǔ)言、匯編語(yǔ)言和高級(jí)語(yǔ)言。 機(jī)器語(yǔ)言(Machine Language)是指直接用機(jī)器碼編寫(xiě)程序、能夠?yàn)橛?jì)算機(jī)直接執(zhí)
2、行的機(jī)器級(jí)語(yǔ)言。機(jī)器碼是一串由二進(jìn)制代碼“0”和“1”組成的二進(jìn)制數(shù)據(jù),其執(zhí)行速度快,但是可讀性極差。機(jī)器語(yǔ)言一般只在簡(jiǎn)單的開(kāi)發(fā)裝置中使用,程序的設(shè)計(jì)、輸入、修改和調(diào)試都很麻煩,在實(shí)訓(xùn)1和實(shí)訓(xùn)3中直接固化或輸入的程序都是機(jī)器語(yǔ)言程序。,匯編語(yǔ)言(Assembly Language)是指用指令助記符代替機(jī)器碼的編程語(yǔ)言。匯編語(yǔ)言程序結(jié)構(gòu)簡(jiǎn)單,執(zhí)行速度快,程序易優(yōu)化,編譯后占用存儲(chǔ)空間小,是單片機(jī)應(yīng)用系統(tǒng)開(kāi)發(fā)中最常用的程序設(shè)計(jì)語(yǔ)言。匯編語(yǔ)言
3、的缺點(diǎn)是可讀性比較差,只有熟悉單片機(jī)的指令系統(tǒng),并具有一定的程序設(shè)計(jì)經(jīng)驗(yàn),才能研制出功能復(fù)雜的應(yīng)用程序,實(shí)訓(xùn)4中的3個(gè)程序都是用匯編語(yǔ)言設(shè)計(jì)的。 高級(jí)語(yǔ)言(High-Level Language)是在匯編語(yǔ)言的基礎(chǔ)上用自然語(yǔ)言的語(yǔ)句來(lái)編寫(xiě)程序,例如PL/M-51、Franklin C51、MBASIC 51等,程序可讀性強(qiáng),通用性好,適用于不熟悉單片機(jī)指令系統(tǒng)的的用戶。,高級(jí)語(yǔ)言編寫(xiě)程序的缺點(diǎn)是實(shí)時(shí)性不高,結(jié)構(gòu)不緊湊
4、,編譯后占用存儲(chǔ)空間比較大,這一點(diǎn)在存儲(chǔ)器有限的單片機(jī)應(yīng)用系統(tǒng)中沒(méi)有優(yōu)勢(shì)。 目前,大多數(shù)用戶仍然使用匯編語(yǔ)言進(jìn)行單片機(jī)應(yīng)用系統(tǒng)的軟件設(shè)計(jì),本章將介紹MCS-51單片機(jī)匯編語(yǔ)言的程序設(shè)計(jì)方法。 單片機(jī)匯編語(yǔ)言程序設(shè)計(jì)的基本步驟如下: (1) 題意分析。熟悉并了解匯編語(yǔ)言指令的基本格式和主要特點(diǎn),明確被控對(duì)象對(duì)軟件的要求,設(shè)計(jì)出算法等。 (2) 畫(huà)出程序流程圖。編寫(xiě)較復(fù)雜的程序
5、,畫(huà)出程序流程圖是十分必要的。程序流程圖也稱為程序框圖,是根據(jù)控制流程設(shè)計(jì)的,它可以使程序清晰,結(jié)構(gòu)合理,便于調(diào)試。,(3) 分配內(nèi)存工作區(qū)及有關(guān)端口地址。分配內(nèi)存工作區(qū),要根據(jù)程序區(qū)、數(shù)據(jù)區(qū)、暫存區(qū)、堆棧區(qū)等預(yù)計(jì)所占空間大小,對(duì)片內(nèi)外存儲(chǔ)區(qū)進(jìn)行合理分配并確定每個(gè)區(qū)域的首地址,便于編程使用。 (4) 編制匯編源程序。 (5) 仿真、調(diào)試程序。 (6) 固化程序。,4.2 簡(jiǎn)單程序設(shè)計(jì),簡(jiǎn)單程序
6、也就是順序程序,實(shí)訓(xùn)4中的程序1就是順序程序結(jié)構(gòu),它是最簡(jiǎn)單、最基本的程序結(jié)構(gòu),其特點(diǎn)是按指令的排列順序一條條地執(zhí)行,直到全部指令執(zhí)行完畢為止。不管多么復(fù)雜的程序,總是由若干順序程序段所組成的。本節(jié)通過(guò)實(shí)例介紹簡(jiǎn)單程序的設(shè)計(jì)方法。 例4.1 4字節(jié)(雙字)加法。將內(nèi)部RAM 30H開(kāi)始的4個(gè)單元中存放的4字節(jié)十六進(jìn)制數(shù)和內(nèi)部RAM 40H單元開(kāi)始的4個(gè)單元中存放的4字節(jié)十六進(jìn)制數(shù)相加,結(jié)果存放到40H開(kāi)始的單元中。,
7、例4.1題意分析示意圖,(1) 題意分析。 題目的要求如圖所示。,ORG0000HMOVA,30HADD A,40HMOV40H,A;最低字節(jié)加法并送結(jié)果MOVA,31HADDCA,41HMOV41H,A;第二字節(jié)加法并送結(jié)果,(2) 匯編語(yǔ)言源程序。按照雙字節(jié)加法的思路,實(shí)現(xiàn)4字節(jié)加法的源程序如下:,MOVA,32HADDC A,42HMOV42H,A
8、;第三字節(jié)加法并送結(jié)果MOVA,33HADDCA,43HMOV43H,A;第四字節(jié)加法并送結(jié)果,進(jìn)位 位在CY中END,顯然,上面程序中,每一步加法的步驟很相似,因此我們可以采用循環(huán)的方法來(lái)編程,使得源程序更加簡(jiǎn)潔,結(jié)構(gòu)更加緊湊。用循環(huán)方法編制的源程序見(jiàn)習(xí)題4.3題。 例4.2 數(shù)據(jù)拼拆程序
9、。將內(nèi)部RAM 30H單元中存放的BCD碼十進(jìn)制數(shù)拆開(kāi)并變成相應(yīng)的ASCII碼,分別存放到31H和32H單元中。 (1) 題意分析。 題目要求如圖所示。,例4.2題意分析示意圖,本題中,首先必須將兩個(gè)數(shù)拆開(kāi),然后再拼裝成兩個(gè)ASCII碼。數(shù)字與ASCII碼之間的關(guān)系是:高4位為0011H,低4位即為該數(shù)字的8421碼。 (2) 匯編語(yǔ)言源程序。源程序如下: ORG 0000
10、H MOV R0,#30H MOV A,#30H XCHD A,@R0;A的低4位與30H單元的低4位 交換 MOV 32H,A ;A中的數(shù)值為低位的ASCII碼,MOV A,@R0 SWAPA;將高位數(shù)據(jù)換到低位 ORL A,#30H ;與30H拼裝成ASCII碼 MOV 31H,A EN
11、D,4.3 分支程序設(shè)計(jì),4.3.1 分支程序?qū)嵗?1.兩分支程序設(shè)計(jì) 例4.3 兩個(gè)無(wú)符號(hào)數(shù)比較(兩分支)。內(nèi)部RAM的20H單元和30H單元各存放了一個(gè)8位無(wú)符號(hào)數(shù),請(qǐng)比較這兩個(gè)數(shù)的大小,比較結(jié)果顯示在實(shí)訓(xùn)的實(shí)驗(yàn)板上: 若(20H)≥(30H),則P1.0管腳連接的LED發(fā)光; 若(20H)<(30H),則P1.1管腳連接的LED發(fā)光。,(1) 題意分析。
12、 本例是典型的分支程序,根據(jù)兩個(gè)無(wú)符號(hào)數(shù)的比較結(jié)果(判斷條件),程序可以選擇兩個(gè)流向之中的某一個(gè),分別點(diǎn)亮相應(yīng)的LED。 比較兩個(gè)無(wú)符號(hào)數(shù)常用的方法是將兩個(gè)數(shù)相減,然后判斷有否借位CY。若CY=0,無(wú)借位,則X≥Y;若CY=1,有借位,則X<Y。程序的流程圖如圖所示。,兩數(shù)比較流程圖,(2) 匯編語(yǔ)言源程序。 源程序如下: X DATA 20H ;數(shù)據(jù)地址賦值偽指令DATA
13、 Y DATA 30H ORG0000H MOV A, X ;(X) →A CLRC ;CY=0 SUBBA,Y ;帶借位減法,A- (Y)-CY→A,JCL1 ;CY=1,轉(zhuǎn)移到 L1CLRP1.0 ;CY=0,(20H)≥(30H),點(diǎn)亮P1.0連接的LED SJMPFINISH
14、 ;直接跳轉(zhuǎn)到結(jié)束等待 L1:CLRP1.1 ;(20H)<(30H),點(diǎn)亮P1.1連接的LED FINISH:SJMP$END (3) 執(zhí)行結(jié)果。 執(zhí)行該程序之前,利用單片機(jī)開(kāi)發(fā)系統(tǒng)先往內(nèi)部RAM的20H和30H單元存放兩個(gè)無(wú)符號(hào)數(shù)(可以任意設(shè)定),執(zhí)行后觀察點(diǎn)亮的LED是否和存放的數(shù)據(jù)大小相一致。,2. 三分支程序設(shè)計(jì)
15、 例4.4 兩個(gè)有符號(hào)數(shù)比較(三分支程序)。內(nèi)部RAM的20H單元和30H單元各存放了一個(gè)8位有符號(hào)數(shù),請(qǐng)比較這兩個(gè)數(shù)的大小,比較結(jié)果顯示在實(shí)訓(xùn)實(shí)驗(yàn)板上: 若(20H)=(30H),則P1.0管腳連接的LED發(fā)光; 若(20H)>(30H),則P1.1管腳連接的LED發(fā)光; 若(20H)<(30H),則P1.2管腳連接的LED發(fā)光。,(1) 題意分析。
16、 有符號(hào)數(shù)在計(jì)算機(jī)中的表示方式與無(wú)符號(hào)數(shù)是不相同的:正數(shù)以原碼形式表示,負(fù)數(shù)以補(bǔ)碼形式表示,8位二進(jìn)制數(shù)的補(bǔ)碼所能表示的數(shù)值范圍為+127~-128。 計(jì)算機(jī)本身無(wú)法區(qū)分一串二進(jìn)制碼組成的數(shù)字是有符號(hào)數(shù)或無(wú)符號(hào)數(shù),也無(wú)法區(qū)分它是程序指令還是一個(gè)數(shù)據(jù)。編程員必須對(duì)程序中出現(xiàn)的每一個(gè)數(shù)據(jù)的含義非常清楚,并按此選擇相應(yīng)的操作。例如,數(shù)據(jù)FEH看作無(wú)符號(hào)數(shù)其值為254,看作有符號(hào)數(shù)為-2。,比較兩個(gè)有符號(hào)數(shù)X和Y大小要比無(wú)
17、符號(hào)數(shù)麻煩得多。這里提供一種比較思路:先判別兩個(gè)有符號(hào)數(shù)X和Y的符號(hào),如果X、Y兩數(shù)符號(hào)相反,則非負(fù)數(shù)大;如果X、Y兩數(shù)符號(hào)相同,將兩數(shù)相減,然后根據(jù)借位標(biāo)志CY進(jìn)行判斷。這一比較過(guò)程如圖所示。,,比較兩個(gè)有符號(hào)數(shù)X、Y的流程圖,(2) 匯編語(yǔ)言源程序。 源程序如下: XDATA 20H YDATA 30H ORG 0000H MOV A,X XRLA,Y;(X)與(Y)進(jìn)行
18、異或操作 JBACC.7,NEXT1;累加器A的第7位為1, 兩數(shù)符號(hào)不同,轉(zhuǎn)移到NEXT1 MOV A,X CJNEA,Y,NEQUAL;(X)≠(Y),轉(zhuǎn)移到 NEQUAL,CL
19、R P1.0 ;(X)=(Y),點(diǎn)亮P1.0連接的LED SJMP FINISH NEQUAL:JC XXY ;(X)(Y),轉(zhuǎn)移到XDY NEXT1:MOVA,X JNBACC.7,XDY ;判斷(X)的最高位D7,以確定其 正負(fù),XXY:CLRP1
20、.2 ;(X)(Y),點(diǎn)亮P1.1連接的LED FINISH:SJMP$ END (3) 程序說(shuō)明。 ① 判斷兩個(gè)有符號(hào)數(shù)符號(hào)異同的方法。 本例中使用邏輯異或指令,將(X)與(Y)進(jìn)行異或操作,那么,(X)的符號(hào)位(X)7與(Y)的符號(hào)位(Y)7異或的結(jié)果如下:,若(X)7與(Y)7相同,則(X)7?(Y)7=0;若(X)7與(Y)7不相同,則(
21、X)7?(Y)7=1。 本例中,(X)與(Y)的異或結(jié)果存放在累加器A中,因此判斷ACC.7是否為零即可知道兩個(gè)數(shù)的符號(hào)相同與否。 ② 比較兩個(gè)有符號(hào)數(shù)的其它方法。 除了本例中使用的比較兩個(gè)有符號(hào)數(shù)的方法之外,我們還可以利用溢出標(biāo)志OV的狀態(tài)來(lái)判斷兩個(gè)有符號(hào)數(shù)的大小。具體算法如下: 若X-Y為正數(shù),則 OV=0 時(shí) X>Y;OV=1 時(shí)XY。 采用這種比較
22、方式的匯編語(yǔ)言源程序自己編寫(xiě)。,3. 散轉(zhuǎn)程序 散轉(zhuǎn)程序是指經(jīng)過(guò)某個(gè)條件判斷之后,程序有多個(gè)流向(三個(gè)以上)。在后面的鍵盤(pán)接口程序設(shè)計(jì)中經(jīng)常會(huì)用到散轉(zhuǎn)功能——根據(jù)不同的鍵碼跳轉(zhuǎn)到相應(yīng)的程序段。 例4.5在實(shí)訓(xùn)4程序2的基礎(chǔ)之上,先設(shè)計(jì)兩個(gè)開(kāi)關(guān),使CPU可以察知兩個(gè)開(kāi)關(guān)組合出的4種不同狀態(tài)。然后對(duì)應(yīng)每種狀態(tài),使8個(gè)LED顯示出不同的亮滅模式。 (1) 硬件設(shè)計(jì)。 在實(shí)訓(xùn)1
23、的電路中,我們使用單片機(jī)的并行口P1的輸出功能來(lái)控制8個(gè)LED的顯示?,F(xiàn)在我們使用其P3口的輸入功能來(lái)設(shè)計(jì)兩個(gè)輸入開(kāi)關(guān),硬件原理圖如圖所示。,例4.5硬件原理圖,如圖4.9所示,當(dāng)開(kāi)關(guān)S0接通2時(shí),P3.4管腳接地,P3.4=0;當(dāng)S0接通1時(shí),P3.4接+5 V,P3.4=1。同樣,當(dāng)開(kāi)關(guān)S1接通2時(shí),P3.5管腳接地,P3.5=0;當(dāng)S1接通1時(shí),P3.5接+5 V,P3.5=1。 假設(shè)要求P3口的開(kāi)關(guān)狀態(tài)對(duì)應(yīng)的P1
24、口的8個(gè)LED的顯示方式如下: P3.5 P3.4顯示方式 0 0全亮 0 1 交叉亮 1 0低4位連接的燈亮,高4位滅 1 1低4位連接的燈滅,高4位亮,(2) 軟件設(shè)計(jì)。 ① 程序設(shè)計(jì)思想。散轉(zhuǎn)程序
25、的特點(diǎn)是利用散轉(zhuǎn)指令實(shí)現(xiàn)向各分支程序的轉(zhuǎn)移,程序流程圖如圖4.10所示。,散轉(zhuǎn)程序流程圖,② 匯編語(yǔ)言源程序。ORG0000HMOVP3,#00110000B;使P3口鎖存器相應(yīng)位置位MOVA,P3 ;讀P3口相應(yīng)引腳線信號(hào) ANLA,#00110000B ;“邏輯與”操作,屏蔽掉無(wú)
26、 關(guān)位 SWAPA ;將相應(yīng)位移位到低位RLA ;循環(huán)左移一位,A*2→AMOVDPTR,#TABLE;轉(zhuǎn)移指令表的基地址送數(shù) 據(jù)指針DPT
27、RJMP@A+DPTR ;散轉(zhuǎn)指令,ONE: MOVP1,#00H;第一種顯示方式,S0接地,S1 接地 SJMP $ TWO: MOV P1,#55H;第二種顯示方式,S0接+5 V, S1接地 SJMP $ THREE:MOV P1,#0FH ;第三種顯示方式,S0接地,S1接+5 V
28、 SJMP $ FOUR: MOV P1,#0F0H;第四種顯示方式,S0接+5 V,S1接地 SJMP $,TABLE:AJMPONE;轉(zhuǎn)移指令表 AJMPTWO AJMPTHREE A JMPFOUR END (3) 程序說(shuō)明。
29、 ① 讀P3口的管腳狀態(tài)。MCS-51的4個(gè)I/O端口共有三種操作方式:輸出數(shù)據(jù)方式,讀端口數(shù)據(jù)方式和讀端口引腳方式。,輸出數(shù)據(jù)方式舉例: MOV P1,#00H ;輸出數(shù)據(jù)00H→P1端口鎖存器→P1引腳 讀端口數(shù)據(jù)方式舉例: MOV A,P3 ;A←P3端口鎖存器 讀端口引腳方式舉例: MOV P3,#0FFH ;P3口端口鎖存器各位置1 MOV A,P3 ;
30、A←P3端口引腳狀態(tài) 注意:讀引腳方式必須連續(xù)使用兩條指令,首先必須使欲讀的端口引腳所對(duì)應(yīng)的鎖存器置位,然后再讀引腳狀態(tài)。,② 散轉(zhuǎn)指令JMP @A+DPTR。 散轉(zhuǎn)指令是單片機(jī)指令系統(tǒng)中專(zhuān)為散轉(zhuǎn)操作提供的無(wú)條件轉(zhuǎn)移指令,指令格式如下: JMP @A+DPTR;PC←DPTR+A 一般情況下,數(shù)據(jù)指針DPTR固定,根據(jù)累加器A的內(nèi)容,程序轉(zhuǎn)入相應(yīng)的分支程序中去。本例采用
31、最常用的轉(zhuǎn)移指令表法,就是先用無(wú)條件轉(zhuǎn)移指令按一定的順序組成一個(gè)轉(zhuǎn)移表,再將轉(zhuǎn)移表首地址裝入數(shù)據(jù)指針DPTR中,然后將控制轉(zhuǎn)移方向的數(shù)值裝入累加器A中作變址,最后執(zhí)行散轉(zhuǎn)指令,實(shí)現(xiàn)散轉(zhuǎn)。指令轉(zhuǎn)移表的存儲(chǔ)格式如圖4.11所示。,指令轉(zhuǎn)移表的存儲(chǔ)格式,由于無(wú)條件轉(zhuǎn)移指令A(yù)JMP是兩字節(jié)指令,因此控制轉(zhuǎn)移方向的A中的數(shù)值為A=0 轉(zhuǎn)向AJMPONEA=2 轉(zhuǎn)向AJMPTWO A=4
32、轉(zhuǎn)向AJMPTHREE A=6 轉(zhuǎn)向AJMPFOUR 程序中,從P3口讀入的數(shù)據(jù)分別為0、1、2、3,因此必須乘以2來(lái)修正A的值。如果A=2,散轉(zhuǎn)過(guò)程如下: JMP@A+DPTR → PC=TABLE+2 → AJMP TWO,③ 三種無(wú)條件轉(zhuǎn)移指令LJMP、AJMP和SJMP 的比較。 三種無(wú)條件轉(zhuǎn)移指令在應(yīng)用上的區(qū)別有以下三點(diǎn):
33、 一是轉(zhuǎn)移距離不同,LJMP可在64 KB范圍內(nèi)轉(zhuǎn)移,AJMP指令可以在本指令取出后的2 KB范圍內(nèi)轉(zhuǎn)移,SJMP的轉(zhuǎn)移范圍是以本指令為核心的-126~+129 B范圍內(nèi)轉(zhuǎn)移; 二是匯編后機(jī)器碼的字節(jié)數(shù)不同,LJMP是三字節(jié)指令,AJMP和SJMP都是兩字節(jié)指令。,三是LJMP和AJMP都是絕對(duì)轉(zhuǎn)移指令,可以計(jì)算得到轉(zhuǎn)移目的地址,而SJMP是相對(duì)轉(zhuǎn)移指令,只能通過(guò)轉(zhuǎn)移偏移量來(lái)進(jìn)行計(jì)算。 選擇無(wú)
34、條件轉(zhuǎn)移指令的原則是根據(jù)跳轉(zhuǎn)的遠(yuǎn)近,盡可能選擇占用字節(jié)數(shù)少的指令。例如,動(dòng)態(tài)暫停指令一般都選用SJMP $,而不用LJMP $。,4.3.2 分支程序結(jié)構(gòu) 分支程序比順序程序的結(jié)構(gòu)復(fù)雜得多,其主要特點(diǎn)是程序的流向有兩個(gè)或兩個(gè)以上的出口,根據(jù)指定的條件進(jìn)行選擇確定。編程的關(guān)鍵是如何確定供判斷或選擇的條件以及選擇合理的分支指令。 通常,根據(jù)分支程序中出口的個(gè)數(shù)分為單分支結(jié)構(gòu)程序(兩個(gè)出口)和多分支結(jié)構(gòu)程
35、序(三個(gè)或三個(gè)以上出口)。 1. 單分支結(jié)構(gòu)程序的形式 單分支結(jié)構(gòu)在程序設(shè)計(jì)中應(yīng)用最廣,擁有的指令也最多。單分支結(jié)構(gòu)一般為:一個(gè)入口,兩個(gè)出口。如圖4.12所示,單分支結(jié)構(gòu)程序有以下兩種典型形式:,圖4.12(a)表示當(dāng)條件滿足時(shí)執(zhí)行分支程序1,否則執(zhí)行分支程序2,例4.3就是這樣的一種結(jié)構(gòu)。 圖4.12(b)表示當(dāng)條件滿足時(shí)跳過(guò)程序段2,從程序段3往下執(zhí)行,否則順序執(zhí)行程序段2和3。
36、,圖4.12 單分支結(jié)構(gòu)程序的典型形式,另外,分支結(jié)構(gòu)程序允許嵌套,即一個(gè)分支接一個(gè)分支,形成樹(shù)形多級(jí)分支結(jié)構(gòu)程序,例4.4就是這樣的結(jié)構(gòu)。 2. 散轉(zhuǎn)程序 在實(shí)際應(yīng)用中,常常需要從兩個(gè)以上的出口中選一個(gè),稱為多分支程序或散轉(zhuǎn)程序。MCS-51單片機(jī)指令系統(tǒng)中專(zhuān)門(mén)提供了散轉(zhuǎn)指令,使得散轉(zhuǎn)程序的編制更加簡(jiǎn)潔。 例4.5中采用轉(zhuǎn)移地址表法實(shí)現(xiàn)散轉(zhuǎn)程序,轉(zhuǎn)移表是由雙字節(jié)短轉(zhuǎn)移指令“AJMP”組成的,各轉(zhuǎn)
37、移指令地址依次相差兩個(gè)字節(jié),所以累加器A中變址值必須作乘2修正。若轉(zhuǎn)移表是由三字節(jié)長(zhǎng)轉(zhuǎn)移指令“LJMP”組成,則累加器A中變址值必須乘3。當(dāng)修正值有進(jìn)位時(shí),則應(yīng)將進(jìn)位先加在數(shù)據(jù)指針高位字節(jié)DPH上。,此外,轉(zhuǎn)移表中使用“AJMP”指令,這就限制了轉(zhuǎn)移的入口地址ONE、TWO、THREE、FOUR必須和散轉(zhuǎn)表首地址TABLE位于同一個(gè)2 KB范圍內(nèi)。為了克服上述局限性,除了可以使用“LJMP”指令組成跳轉(zhuǎn)表外,還可采用雙字節(jié)的寄存器存放散
38、轉(zhuǎn)值,并利用對(duì)DPTR進(jìn)行加法運(yùn)算的方法,直接修改DPTR,然后再用散轉(zhuǎn)指令實(shí)現(xiàn)散轉(zhuǎn)。 散轉(zhuǎn)程序除了轉(zhuǎn)移指令表法之外,還可以采用地址偏移量表法、轉(zhuǎn)向地址表法及利用“RET”指令(子程序返回指令)實(shí)現(xiàn)散轉(zhuǎn)程序等。,3. 轉(zhuǎn)移條件的形成 分支程序中的轉(zhuǎn)移條件一般都是程序狀態(tài)字(PSW)中標(biāo)志位的狀態(tài),因此,保證分支程序正確流向的關(guān)鍵如下: (1) 在判斷之前,應(yīng)執(zhí)行對(duì)有關(guān)標(biāo)志位有影響的指令
39、該標(biāo)志位能夠適應(yīng)問(wèn)題的要求,這就要求編程員要十分了Vcv 解指令對(duì)標(biāo)志位的影響情況。 (2) 當(dāng)某一標(biāo)志位處于某一狀態(tài)時(shí),在未執(zhí)行下一條影響此標(biāo)志位的指令前,它一直保持原狀態(tài)不變。 (3) 正確理解PSW中各標(biāo)志位的含義及變化情況,才能正確地判斷轉(zhuǎn)移。,4.4 循環(huán)程序設(shè)計(jì),4.4.1 循環(huán)程序?qū)嵗?1. 單重循環(huán)程序設(shè)計(jì) 例4.6 實(shí)訓(xùn)4的程序3設(shè)計(jì)
40、。用P1口連接的8個(gè)LED模擬霓虹燈的顯示方式。編程實(shí)現(xiàn)P1口連接的8個(gè)LED顯示方式如下: 按照從P1.0到P1.7的順序,依次點(diǎn)亮其連接的LED。 (1) 題意分析。這種顯示方式是一種動(dòng)態(tài)顯示方式,逐一點(diǎn)亮一個(gè)燈,使人們感覺(jué)到點(diǎn)亮燈的位置在移動(dòng)。根據(jù)點(diǎn)亮燈的位置,我們要向P1口依次送入如下的立即數(shù):,FEH——點(diǎn)亮P1.0連接的LEDMOVP1,#0FEH FDH——點(diǎn)亮P1
41、.1連接的LEDMOVP1,#0FDH FBH——點(diǎn)亮P1.2連接的LEDMOVP1,#0FBH 7FH——點(diǎn)亮P1.7連接的LEDMOVP1,#7FH 以上完全重復(fù)地執(zhí)行往P1口傳送立即數(shù)的操作,會(huì)使程序結(jié)構(gòu)松散。我們看到,控制LED點(diǎn)亮的顯示模式字立即數(shù)0FEH、0FDH、0FBH…7FH之間存在著每次左移一位的規(guī)律,因此我們可以試用循環(huán)程序來(lái)實(shí)現(xiàn)。初步設(shè)想的程序流程圖如圖
42、所示。,例4.6初步設(shè)想的程序流程圖,用匯編語(yǔ)言實(shí)現(xiàn)的程序如下: ORG 0000HSTART:MOVR2,#08H ;設(shè)置循環(huán)次數(shù) MOVA,#0FEH;從P1.0→P1.7使LED逐 ;個(gè)亮過(guò)去NEXT: MOVP1,A ;點(diǎn)亮LED R
43、L A ;左移一位 DJNZR2,NEXT;次數(shù)減1,不為;零,繼續(xù)點(diǎn)亮下一個(gè)LED SJMPSTART;反復(fù)點(diǎn)亮 END,執(zhí)行上面程序后,結(jié)果是8個(gè)燈全部被點(diǎn)亮,跟預(yù)想的結(jié)果不符,為什么呢?這是因?yàn)槌绦驁?zhí)行得很快,逐一點(diǎn)亮LED的間隔太短,在我們看來(lái)就是同時(shí)點(diǎn)亮了,因此,必須在點(diǎn)亮一個(gè)LED后加一段延時(shí)程序
44、,使該顯示狀態(tài)稍事停頓,人眼才能區(qū)別開(kāi)來(lái)。,(2) 匯編語(yǔ)言源程序。 由于程序設(shè)計(jì)中經(jīng)常會(huì)出現(xiàn)如圖所示的次數(shù)控制循環(huán)程序結(jié)構(gòu),為了編程方便,單片機(jī)指令系統(tǒng)中專(zhuān)門(mén)提供了循環(huán)指令DJNZ,以適用于上述結(jié)構(gòu)的編程。 DJNZR2,NEXT;R2中存放控制次數(shù), ;R2-1→R2,R2≠0,轉(zhuǎn)移到NEXT繼續(xù)循環(huán),
45、 ;否則執(zhí)行下面指令,常見(jiàn)循環(huán)程序結(jié)構(gòu),2.雙重循環(huán)程序設(shè)計(jì)——延時(shí)程序設(shè)計(jì) 在上例中使用了延時(shí)程序段之后,我們才能看到正確的顯示結(jié)果。延時(shí)程序在單片機(jī)匯編語(yǔ)言程序設(shè)計(jì)中使用非常廣泛,例如,鍵盤(pán)接口程序設(shè)計(jì)中的軟件消除抖動(dòng)、動(dòng)態(tài)LED顯示程序設(shè)計(jì)、LCD接口程序設(shè)計(jì)、串行通信接口程序設(shè)計(jì)等。所謂延時(shí),就是讓CPU做一些與主程序功能無(wú)關(guān)的操作(例如將一個(gè)數(shù)字逐次減1直到為0)來(lái)消耗掉CPU的時(shí)間。由于
46、我們知道CPU執(zhí)行每條指令的準(zhǔn)確時(shí)間,因此執(zhí)行整個(gè)延時(shí)程序的時(shí)間也可以精確計(jì)算出來(lái)。也就是說(shuō),我們可以寫(xiě)出延時(shí)長(zhǎng)度任意而且精度相當(dāng)高的延時(shí)程序。,例4.7 設(shè)計(jì)一個(gè)延時(shí)1 s的程序,設(shè)單片機(jī)時(shí)鐘晶振頻率為fosc=6 MHz。 (1) 題意分析。 設(shè)計(jì)延時(shí)程序的關(guān)鍵是計(jì)算延時(shí)時(shí)間。延時(shí)程序一般采用循環(huán)程序結(jié)構(gòu)編程,通過(guò)確定循環(huán)程序中的循環(huán)次數(shù)和循環(huán)程序段兩個(gè)因素來(lái)確定延時(shí)時(shí)間。對(duì)于循環(huán)程序段來(lái)講
47、,必須知道每一條指令的執(zhí)行時(shí)間,這里涉及到幾個(gè)非常重要的概念——時(shí)鐘周期、機(jī)器周期和指令周期。 時(shí)鐘周期T時(shí)鐘是計(jì)算機(jī)基本時(shí)間單位,同單片機(jī)使用的晶振頻率有關(guān)。題目給定fosc=6 MHz,那么T時(shí)鐘=1/fosc=1/6 M=166.7 ns。,機(jī)器周期T機(jī)器是指CPU完成一個(gè)基本操作所需要的時(shí)間,如取指操作、讀數(shù)據(jù)操作等,機(jī)器周期的計(jì)算方法:T機(jī)器=12T時(shí)鐘=166.7 ns×12=2 µs
48、。 指令周期是指執(zhí)行一條指令所需要的時(shí)間。由于指令匯編后有單字節(jié)指令、雙字節(jié)指令和三字節(jié)指令,因此指令周期沒(méi)有確定值,一般為1~4個(gè)T機(jī)器。在附錄2的指令表中給出了每條指令所需的機(jī)器周期數(shù),可以計(jì)算每一條指令的指令周期。 現(xiàn)在,我們可以來(lái)計(jì)算一下實(shí)訓(xùn)4程序3中延時(shí)程序段的延時(shí)時(shí)間。延時(shí)程序段如下:,DELAY1:MOV R3,#0FFH DEL2: MOV R4,#0FFHDEL1: NO
49、P DJNZ R4,DEL1 DJNZ R3,DEL2 經(jīng)查指令表得到:指令MOV R4,#0FFH、NOP、DJNZ的執(zhí)行時(shí)間分別為2 µs、2 µs和4 µs。NOP為空操作指令,其功能是取指、譯碼,然后不進(jìn)行任何操作進(jìn)入下一條指令,經(jīng)常用于產(chǎn)生一個(gè)機(jī)器的延遲。,延時(shí)程序段為雙重循環(huán),下面分別計(jì)算內(nèi)循環(huán)和外循環(huán)的延時(shí)時(shí)間。 內(nèi)循環(huán):內(nèi)
50、循環(huán)的循環(huán)次數(shù)為255(0FFH)次,循環(huán)為以下兩條指令: NOP;2 µs DJNZ R4,DEL1;4 µs 內(nèi)循環(huán)延時(shí)時(shí)間為 :255×(2+4)=1530 µs。 外循環(huán):外循環(huán)的循環(huán)次數(shù)為255(0FFH)次,循環(huán)內(nèi)容如下: MOVR4,#0FFH;2 µs
51、 1530 us內(nèi)循環(huán) ;1530 µs DJNZ R3,DEL2 ;4 µs,外循環(huán)一次時(shí)間為1530 µs+2 µs+4 µs=1536 µs,循環(huán)255次,另外加上第一條指令 MOVR3,#0FFH;2 µs的循環(huán)時(shí)間2 µs,因此總的循環(huán)時(shí)間為 2?
52、1;s+(1530?µs+2?µs+4?µs)×255=391682?µs≈392 ms 以上是比較精確的計(jì)算方法,一般情況下,在外循環(huán)的計(jì)算中,經(jīng)常忽略比較小的時(shí)間段,例如將上面的外循環(huán)計(jì)算公式簡(jiǎn)化為 1530 µs×255 = 390 150 µs ≈ 390 ms,了解了延時(shí)時(shí)間的計(jì)算方法,本例我們使用三重循環(huán)結(jié)構(gòu)。
53、程序流程圖如圖4.15所示。 內(nèi)循環(huán)選擇為1 ms,第二層循環(huán)達(dá)到延時(shí)10 ms(循環(huán)次數(shù)為10),第三層循環(huán)延時(shí)到1 s(循環(huán)次數(shù)為100)。 (2) 匯編語(yǔ)言源程序段。 一般情況下,延時(shí)程序均是作為一個(gè)子程序段使用,不會(huì)獨(dú)立運(yùn)行它,否則單純的延時(shí)沒(méi)有實(shí)際意義。,延時(shí)1 s的程序流程圖,DELAY:MOVR0,#100;延時(shí)1 s的循環(huán)次數(shù)DEL2:
54、MOVR1,#10 ;延時(shí)10 ms的循環(huán)次數(shù)DEL1: MOVR2,#7DH ;延時(shí)1 ms的循環(huán)次數(shù)DEL0: NOPNOPDJNZR2,DEL0DJNZR1,DEL1DJNZR0,DEL2,(3) 程序說(shuō)明。 本例中,第二層循環(huán)和外循環(huán)都采用了簡(jiǎn)化計(jì)算方法,編程關(guān)鍵是延時(shí)1ms的內(nèi)循環(huán)程序如何編
55、制。首先確定循環(huán)程序段的內(nèi)容如下: NOP ;2 µs NOP ;2 µs DJNZ R2,DEL0 ;4 µs 內(nèi)循環(huán)次數(shù)設(shè)為count,計(jì)算
56、方法如下式: (一次循環(huán)時(shí)間)×count = 1 ms從而得到 count = 1 ms/(2 µs+2 µs+4 µs) = 125 = 7DH,本例提供了一種延時(shí)程序的基本編制方法,若需要延時(shí)更長(zhǎng)或更短時(shí)間,只要用同樣的方法采用更多重或更少重的循環(huán)即可。 值得注意的是,延時(shí)程序的目的是白白占用CPU一段時(shí)間,此時(shí)不能做任何其
57、它工作,就像機(jī)器在不停地空轉(zhuǎn)一樣,這是程序延時(shí)的缺點(diǎn)。若在延時(shí)過(guò)程中需要CPU做指定的其它工作,就要采用單片機(jī)內(nèi)部的硬件定時(shí)器或片外的定時(shí)芯片(如8253等)。,3. 數(shù)據(jù)傳送程序 例4.8 不同存儲(chǔ)區(qū)域之間的數(shù)據(jù)傳輸。將內(nèi)部RAM 30H單元開(kāi)始的內(nèi)容依次傳送到外部RAM 0100H單元開(kāi)始的區(qū)域,直到遇到傳送的內(nèi)容是0為止。 (1) 題意分析。 本例要解決的關(guān)鍵問(wèn)題是:數(shù)據(jù)塊的傳
58、送和不同存儲(chǔ)區(qū)域之間的數(shù)據(jù)傳送。前者采用循環(huán)程序結(jié)構(gòu),以條件控制結(jié)束;后者采用間接尋址方式,以累加器A作為中間變量實(shí)現(xiàn)數(shù)據(jù)傳輸。程序流程圖如圖所示。,例4.8程序流程圖,(2) 匯編語(yǔ)言源程序。 ORG0000H MOVR0,#30H;R0指向內(nèi)部RAM數(shù)據(jù)區(qū)首地址 MOVDPTR,#0100H;DPTR指向外部RAM數(shù)據(jù)區(qū)首地址 TRANS:
59、 MOVA,@R0;A←(R0) MOVX@DPTR,A;(DPTR)←A CJNE A,#00H,NEXT SJMP FINISH;A=0,傳送完成,NEXT:INCR0 ;修改地址指針I(yè)NCDPTR AJMPTRANS;繼續(xù)傳送 FINISH:SJMP$ END (3) 程序說(shuō)明
60、。 ① 間接尋址指令。在單片機(jī)指令系統(tǒng)中,對(duì)內(nèi)部RAM讀/寫(xiě)數(shù)據(jù)有兩種方式:直接尋址方式和間接尋址方式。例如:,直接方式:MOVA,30H;內(nèi)部RAM(30H)→累加器A 間接方式:MOV R0,#30H;30H→R0 MOV A,@R0; 內(nèi)部RAM(R0)→累加器A 對(duì)外部RAM的讀/寫(xiě)數(shù)據(jù)只有間接尋址方式,間接尋址寄存器有R0、R1(尋址范圍是00
61、H~FFH)和DPTR(尋址范圍0000H~FFFFH,整個(gè)外部RAM區(qū))。,② 不同存儲(chǔ)空間之間的數(shù)據(jù)傳輸。MCS-51系列單片機(jī)存儲(chǔ)器結(jié)構(gòu)的特點(diǎn)之一是存在著4種物理存儲(chǔ)空間,即片內(nèi)RAM、片外RAM、片內(nèi)ROM和片外ROM。不同的物理存儲(chǔ)空間之間的數(shù)據(jù)傳送一般以累加器A作為數(shù)據(jù)傳輸?shù)闹行?,如圖所示。 不同的存儲(chǔ)空間是獨(dú)立編址的,在傳送指令中的區(qū)別在于不同的指令助記符,例如:MOVR0,#30HMOVA,
62、@R0;內(nèi)部RAM(30H)→A MOVX A,@R0 ;外部RAM(30H)→A,以累加器A為中心的不同存儲(chǔ)空間的數(shù)據(jù)傳送示意圖,4.4.2 循環(huán)程序結(jié)構(gòu) 1. 循環(huán)程序組成 從以上循環(huán)程序?qū)嵗?,我們看到循環(huán)程序的特點(diǎn)是程序中含有可以重復(fù)執(zhí)行的程序段。循環(huán)程序由以下4部分組成: (1) 初始化部分。程序在進(jìn)入循環(huán)處理之前必須先設(shè)立初值,例如
63、循環(huán)次數(shù)計(jì)數(shù)器、工作寄存器以及其它變量的初始值等,為進(jìn)入循環(huán)做準(zhǔn)備。 (2) 循環(huán)體。循環(huán)體也稱為循環(huán)處理部分,是循環(huán)程序的核心。循環(huán)體用于處理實(shí)際的數(shù)據(jù),是重復(fù)執(zhí)行部分。,(3) 循環(huán)控制。在重復(fù)執(zhí)行循環(huán)體的過(guò)程中,不斷修改和判別循環(huán)變量,直到符合循環(huán)結(jié)束條件。一般情況下,循環(huán)控制有以下幾種方式: ① 計(jì)數(shù)循環(huán)——如果循環(huán)次數(shù)已知,用計(jì)數(shù)器計(jì)數(shù)來(lái)控制循環(huán)次數(shù),這種控制方式用得比較多。循環(huán)次數(shù)要在初始化部
64、分預(yù)置,在控制部分修改,每循環(huán)一次,計(jì)數(shù)器內(nèi)容減1。例4.6、例4.7都屬于計(jì)數(shù)循環(huán)控制方式。 ② 條件控制循環(huán)——在循環(huán)次數(shù)未知的情況下,一般通過(guò)設(shè)立結(jié)束條件來(lái)控制循環(huán)的結(jié)束,例4.8就是用條件A=0來(lái)控制循環(huán)結(jié)束的。,③ 開(kāi)關(guān)量與邏輯尺控制循環(huán)——這種方法經(jīng)常用在過(guò)程控制程序設(shè)計(jì)中,這里不再詳述。 (4) 循環(huán)結(jié)束處理。這部分程序用于存放執(zhí)行循環(huán)程序所得結(jié)果以及恢復(fù)各工作單元的初值等。
65、 2. 循環(huán)程序的基本結(jié)構(gòu) 循環(huán)程序通常有兩種編制方法:一種是先處理再判斷,另一種是先判斷后處理,如圖所示。,循環(huán)程序的兩種基本結(jié)構(gòu)(a)先執(zhí)行后判斷;(b)先判斷后執(zhí)行,3. 多重循環(huán)結(jié)構(gòu)程序 有些復(fù)雜問(wèn)題,必須采用多重循環(huán)的程序結(jié)構(gòu),即循環(huán)程序中包含循環(huán)程序或一個(gè)大循環(huán)中包含多個(gè)小循環(huán)程序,稱為多重循環(huán)程序結(jié)構(gòu),又稱循環(huán)嵌套。 多重循環(huán)程序必須注意的是各重循環(huán)不能交叉,不能從外循環(huán)跳
66、入內(nèi)循環(huán)。例4.7的延時(shí)程序就是一個(gè)典型的三重循環(huán)結(jié)構(gòu)。 4. 循環(huán)程序與分支程序的比較 循環(huán)程序本質(zhì)上是分支程序的一種特殊形式,凡是分支程序可以使用的轉(zhuǎn)移指令,循環(huán)程序一般都可以使用,并且由于循環(huán)程序在程序設(shè)計(jì)中的重要性,單片機(jī)指令系統(tǒng)還專(zhuān)門(mén)提供了循環(huán)控制指令,如DJNZ等。,4.5 查 表 程 序,在單片機(jī)匯編語(yǔ)言程序設(shè)計(jì)中,查表程序的應(yīng)用非常廣泛,在LED顯示程序和鍵盤(pán)接口程序設(shè)計(jì)中都用到了查表程
67、序段。 例4.9 在程序中定義一個(gè)0~9的平方表,利用查表指令找出累加器A=05H的平方值。 (1) 題意分析。 所謂表格是指在程序中定義的一串有序的常數(shù),如平方表、字型碼表、鍵碼表等。因?yàn)槌绦蛞话愣际枪袒诔绦虼鎯?chǔ)器(通常是只讀存儲(chǔ)器ROM類(lèi)型)中,因此可以說(shuō)表格是預(yù)先定義在程序的數(shù)據(jù)區(qū)中,然后和程序一起固化在ROM中的一串常數(shù)。,查表程序的關(guān)鍵是表格的定義和如何實(shí)現(xiàn)查表。
68、 (2) 匯編語(yǔ)言源程序。 ORG0000H MOVDPTR,#TABLE ;表首地址→DPTR(數(shù)據(jù)指針) MOVA,#05 ;05→A MOVCA,@A+DPTR;查表指令,25→A,A=19H SJMP$;程序暫停 TABLE:DB0,1,4,9,16,25,36,49,
69、64,81;定義0~9平方表 END,(3) 程序說(shuō)明。 從程序存儲(chǔ)器中讀數(shù)據(jù)時(shí),只能先讀到累加器A中,然后再送到題目要求的地方。單片機(jī)提供了兩條專(zhuān)門(mén)用于查表操作的查表指令: MOVCA,@A+DPTR;(A+DPTR)→A MOVCA,@A+PC;PC+1→PC,(A+PC)→ADPTR為數(shù)據(jù)指針,一般用于存放表首地址。 用指令MOVC A,@A+PC實(shí)現(xiàn)查找
70、平方表的源程序如下:,ORG 0000H MOV A,#05;05→A ADD A,#02;修正累加器A的值,修正值為查表指令距離表格首地址 ;的字節(jié)數(shù)減去1
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 眾賞文庫(kù)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
評(píng)論
0/150
提交評(píng)論