版權說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權,請進行舉報或認領
文檔簡介
1、單 片 機 技 術 及 應 用,第4章 MCS-51程序設計,教學目標掌握匯編語言程序基本結構。掌握程序設計的步驟和方法。學會具體程序的應用。,程序設計的過程大致可以分為以下幾個步驟:(1) 編制說明要解決問題的程序框圖。(2) 確定數(shù)據(jù)結構、算法、工作單元、變量設定。(3) 根據(jù)所用計算機的指令系統(tǒng),按照已編制的程序框圖,用匯編語言編制出源程序。(4) 將編制出的程序在計算機上調(diào)試,直至實現(xiàn)預定的功能。,4.1 三種
2、基本程序結構: (1) 順序程序順序程序是指按順序依次執(zhí)行的程序,也稱為簡單程序或直線程序。順序程序結構雖然比較簡單,但也能完成一定的功能任務,是構成復雜程序的基礎。,【例4-1/3-27】已知16位二進制負數(shù)存放在R1、R0中,試求其補碼,并將結果存放在R3、R2中。分析:負數(shù)的求補:“求反加1”,符號位不變。利用CPL指令實現(xiàn)求反;加1時,則應低8位先加1,高8位再加上低位的進位。注意:不能用INC指令。,步驟:(1)低
3、八位送累加器(CPL操作八位數(shù)字只能在累加器中進行);(2)低八位取反,加1;(3)存低八位處理結果;(4)高八位送累加器;(5)高八位取反,加標志位并將符號位置1;(6)保存高八位處理結果。,程序如下:CONT:MOV A,R0 ;讀低8位 CPL A ;取反 ADD A, #1 ;加1
4、 MOV R2, A ;存低8位 MOV A, R1 ;讀高8位 CPL A ;取反 ADDC A, #80H;加進位及符號位 MOV R3, A ;存高8位 RET ;
5、返回,【例3-28/4-2】將兩個半字節(jié)數(shù)合并成一個1字節(jié)數(shù)。 設內(nèi)部RAM的40H、41H單元中分別存放著8位二進制數(shù)1101 1001B 、10110110B。要求取出兩個單元中的低半字節(jié),合并成一個字節(jié)后,存放在42H單元中。,要求:設內(nèi)部RAM的40H、41H單元中分別存放著8位二進制數(shù)。要求取出兩個單元中的低半字節(jié),合并成一個字節(jié)后,存放在42H單元中。步驟:(1)取40H里面的數(shù)字放入累加
6、器;(2)高四位清零;(3)高低位互換;(4)保存;(5)取41H里面的數(shù)字放入累加器;(6)高四位清零;(7)拼字;(8)保存。,程序如下: ORG 0000HSTART:MOV R1, #40H MOV A, @R1 ANL A, #0FH ;取第一個半字節(jié)
7、 SWAPA INC R1 XCH A, @R1 ;取第二字節(jié) ANLA, #0FH ;取第二個半字節(jié) ORL A, @R1 ;拼字
8、 INC R1 MOV @R1, A ;存放結果 SJMP $ END,【例3-29/4-3】拆字程序。 40H里面一個8位 二進制數(shù)拆成兩個半字節(jié)數(shù)字,分別送入41H 42H中。步驟(1)40H數(shù)字送累加器;(2)備份;
9、 (3)高四位清零;(4)保存低四位; (5)取數(shù)字;(6)低四位清零;(7)高地位互換;(8)保存高四位。,ORG 0000HSTART:MOV R1,#40H MOV A,@R1 MOV B,A ;暫存B中 ANL A,#0FH ;取第一個半字節(jié) INC R1 MOV @R
10、1,A ;存放第一個半字節(jié) MOV A,B SWAPA ANL A,#0FH ;取第二個半字節(jié) INC R1 MOV @R1,A ;存放第二個半字節(jié) SJMP$ END,4.1.2 分支程序分支程序比順序程序的結構復雜得多,其主要特點
11、是程序的流向有兩個或兩個以上的出口,根據(jù)指定的條件進行選擇確定。編程的關鍵是如何確定供判斷或選擇的條件以及選擇合理的分支指令。,【例3-30/4-4】求單字節(jié)有符號二進制數(shù)的補碼。分析:正數(shù)的補碼是其本身,負數(shù)的補碼是其反碼加1。因此,程序首先判斷被轉換數(shù)的符號,負數(shù)進行轉換,正數(shù)即為補碼。步驟:(1)判斷正負,正則跳到正數(shù)對應的子程序,負數(shù)則往下執(zhí)行;(2)假設是負數(shù),取反;(3)加1;(4)符號位置1,負數(shù)處理程序結束;(5
12、)正數(shù)處理子程序。,設二進制數(shù)放在累加器A中,其補碼放回到A中。 程序如下: ORG 0000H CMPT:JNB ACC.7,NCH ;(A)>0,不需轉換 CPL A
13、 ADD A, #1 SETBACC.7 ;保存符號 NCH: SJMP$ END,【例3-31/4-5】兩個無符號數(shù)比較大小。設兩個連續(xù)外部RAM單元ST1和ST2中存放不帶符號的二進制數(shù),找出其中的大數(shù)存入ST3單元中。,設兩個連續(xù)外部RAM單元ST1和ST2中存放不帶符號的
14、二進制數(shù),找出其中的大數(shù)存入ST3單元中。分析:減法運算的操作數(shù)必須在內(nèi)部數(shù)據(jù)存儲器中,所以ST1和ST2中的數(shù)據(jù)首先要存入內(nèi)部數(shù)據(jù)存儲器,再通過減法運算判斷大小步驟(1)取第一個數(shù)并保存;(2)取第二個數(shù)到累加器A;(3)第二個數(shù)減第一個數(shù)(4)如果發(fā)生借位(CY=1),則第一個存入ST3,否則第二個數(shù)…,程序如下: ORG 8000H ST1 EQU 8040H START1:C
15、LRC ;進位位清零 MOV DPTR,#ST1 ;設數(shù)據(jù)指針 MOVXA,@DPTR ;取第一個數(shù) MOV R2,A ;暫存R2 INC DPTR MOVXA,@DTPR ;取第二個數(shù) SUBBA,R2 ;兩數(shù)比較 JN
16、C BIG1 XCH A,R2 ;第一個數(shù)大BIG0: INC DPTR MOVX@DPTR,A ;存大數(shù) SJMP$BIG1: MOVX A,@DPTR;第二個數(shù)大 SJMP BIG0 END,4.1.3 循環(huán)程序只有簡單程序和分支程序是不夠的。因為簡單程序和分支程序的特點是,每一條指令至
17、多執(zhí)行一次。在處理實際事務時,有時會遇到多次重復處理的問題,用循環(huán)程序的方法來解決就比較合適。循環(huán)程序中的某些指令可以反復執(zhí)行多次。采用循環(huán)程序,可使程序縮短,從而節(jié)省存儲單元。重復次數(shù)越多,循環(huán)程序的優(yōu)越性就越明顯。,1. 單循環(huán)程序,【例4-6/3-31】多個單字節(jié)數(shù)據(jù)求和。已知有10個單字節(jié)數(shù)據(jù),依次存放在以內(nèi)部RAM的50H單元開始的連續(xù)單元中。要求把計算結果存入R2、R3中(高位存R2,低位存R3)。思路: R2、R3、C
18、Y首先清零,依次將10個數(shù)據(jù)跟R3中數(shù)據(jù)相加(結果存在R3),每次加法完成后,如果CY=1,則R2加1.,解:程序如下: ORG 8000HSAD: MOV R0,#50H ;設數(shù)據(jù)指針 MOV R5,#0AH ;計數(shù)值0AH→R5SAD1:MOV R2,#0 ;和的高8位清零 MOV R3,#0 ;和的低8位清零LOOP:MOV A,R3
19、 ;取加數(shù) ADD A,@R0 MOV R3,A ;存和的低8位 JNC LOP1 INC R2 ;有進位,和的高8位+1LOP1:INC R0 ;指向下一個數(shù)據(jù)地址 DJNZR5,LOOP SJMP$ END,【例4-7/3-33】內(nèi)部R
20、AM單元清零。要求:將60H為起點的9個單元清“0”。解:程序如下: ORG 0000HCLEAR:CLR A ;A清0 MOV R0,#60H ;確定清0單元起始地址 MOV R6,#09 ;確定要清除的單元個數(shù)LOOP:MOV @R0,A ;清單元 INC R0 ;指向下一個
21、單元 DJNZR6,LOOP ;控制循環(huán) SJMP$ END,【例4-8】外部RAM單元清零。要求:設有40個外部RAM單元要清“0”,即為循環(huán)次數(shù)存放在R2寄存器中,其首地址存放在DPTR中,設為3000H。 解:方法一:程序如下:ORG0000HMOVDPTR,#3000HCLEAR:CLRAMOVR2,#2
22、8H;置計數(shù)值LOOP:MOVX@DPTR,AINCDPTR;修改地址指針DJNZR2,LOOP;控制循環(huán)END,2. 多重循環(huán)程序如果在一個循環(huán)體中又包含了其他的循環(huán)程序,即循環(huán)中還套著循環(huán),這種程序稱為多重循環(huán)程序?!纠?-9】10秒延時程序。延時程序與MCS-51執(zhí)行指令的時間有關,如果使用6MHz晶振,一個機器周期為2μs,計算出執(zhí)行一條指令以至一個循環(huán)所需要的時間,給出相應的循環(huán)次數(shù),便能達到
23、延時的目的。程序如下:DEL:MOVR5,#100DEL0:MOVR6,#100DEL1:MOVR7,#248DEL2:DJNZR7,DEL2;DJNZR6,DEL1;DJNZR5,DEL0;RET,4.2 子程序和參數(shù)傳遞方法在實際程序中,常常會多次進行一些相同的計算和操作,如數(shù)制轉換、函數(shù)式計算等。如果每次都從頭開始編制一段程序,不僅麻煩,而且浪費存儲空間。因此對一些常用的程序段,以
24、子程序的形式,事先存放在存儲器的某一區(qū)域。當主程序運行過程中需要用子程序時,只要執(zhí)行調(diào)用子程序的指令,使程序轉至子程序即可。子程序處理完畢,返回主程序,繼續(xù)進行以后的操作。調(diào)用子程序有以下優(yōu)點:(1)避免對相同程序段的重復編制。(2)簡化程序的邏輯結構,同時也便于子程序調(diào)試。(3)節(jié)省存儲器空間。,4.2.1 工作寄存器或累加器傳遞參數(shù)此方法是把入口參數(shù)或出口參數(shù)放在工作寄存器或累加器中的方法。使用這種方法可使程序最簡
25、單,運算速度也最高。它的缺點是:工作寄存器數(shù)量有限,不能傳遞太多的數(shù)據(jù);主程序必須先把數(shù)據(jù)送到工作寄存器;參數(shù)個數(shù)固定,不能由主程序任意設定。,【例4-10】請編出能把20H單元內(nèi)兩個BCD數(shù)變換成相應ASCII碼放在21H(高位BCD數(shù)的ASCII碼)和22H(低位BCD數(shù)的ASCII碼)單元的程序。解:根據(jù)ASCII字符表,0~9的BCD數(shù)和它們的ASCII碼之間僅相差30H。因此,僅需把20H單元中兩個BCD數(shù)拆開,分別和30H
26、相加即可,程序如下:ORG0000HASC1:MOVR0, #22HMOV@R0, #00HMOVA, 20HXCHDA, @R0ORL22H, #30HSWAPAORLA, #30HMOV21H, ASJMP$END,4.2.2 用指針寄存器來傳遞參數(shù)由于數(shù)據(jù)一般存放在存儲器中,而不是工作寄存器中,故可用指針來指示數(shù)據(jù)的位置,這樣可以大大節(jié)省傳遞數(shù)據(jù)的工作量,并可實現(xiàn)
27、可變長度運算。一般如參數(shù)在內(nèi)部RAM 中,可用R0或R1作指針。進行可變長度運算時,可用一個寄存器來指出數(shù)據(jù)長度,也可在數(shù)據(jù)中指出其長度(如使用結束標記符)。,4.2.3 用堆棧來傳遞參數(shù)堆棧可以用于傳遞參數(shù)。調(diào)用時,主程序可用PUSH指令把參數(shù)壓入堆棧中。之后子程序可按棧指針訪問堆棧中的參數(shù),同時可把結果參數(shù)送回堆棧中。返回主程序后,可用POP指令得到這些結果參數(shù)。這種方法的優(yōu)點是:簡單;能傳遞大量參數(shù);不必為特定的參數(shù)分配存儲單
28、元。使用這種方法時,由于參數(shù)在堆棧中,故大大簡化了中斷響應時的現(xiàn)場保護。實際使用時,不同的調(diào)用程序可使用不同的技術來決定或處理這些參數(shù)。下面以幾個簡單的例子說明用堆棧來傳遞參數(shù)的方法。,【例4-11】一位十六進制數(shù)轉換為ASCII碼子程序。解:程序如下:HASC:MOVR0, SPDECR0DECR0;R0為參數(shù)指針XCHA,@R0;保護ACC,取出參數(shù)ANLA,#0FHADDA,#2;加
29、偏移量MOVCA,@A+PCXCHA,@R0;將查表結果放回堆棧中RETDB'0123456789';十六進制數(shù)的ASCII字符表DB'ABCDEF'END,【例4-12】把內(nèi)部RAM中50H、51H的雙字節(jié)十六進制數(shù)轉換為4位ASCII碼,存放于(R1)指向的4個內(nèi)部RAM單元。解:編寫程序時可以將例4-10當作子程序調(diào)用,子程序名為HASC。HA24:MOVA
30、,50HSWAPAPUSHACCACALLHASCPOPACCMOV@R1,AINCR1PUSH50HACALLHASCPOPACC,MOV@R1,AINCR1MOVA,51HSWAPAPUSHACCACALLHASCPOPACCMOV@R1,AINCR1PUSH51HACALLHASCPOPACCMOV@R1
31、,AEND,【例4-13】一個字節(jié)的兩位十六進制數(shù)轉換為兩個ASCII碼子程序。解:參考程序如下:ORG 0000HHTA2:MOVR0,SP DECR0 DECR0 PUSHACC ;保護累加器內(nèi)容 MOVA, @R0;取出參數(shù) ANLA, #0FH ADDA, #14 ;加偏移量 MOVCA,@A+PC
32、 XCHA,@R0;低位HEX的ASCII碼放入堆棧中,SWAPAANLA,#0FH ADDA,#7;加偏移量MOVCA,@A+PCINCR0XCHA,@R0;高位HEX的ASCII碼放入堆棧中INCR0XCHA,@R0;高位返回地址放入堆棧,并恢復累加器內(nèi)容RETDB'0123456789'DB'ABCDEF'END,4.3
33、 查表程序設計查表程序是一種常用程序,它廣泛應用于LED顯示器控制、打印機打印及數(shù)據(jù)補償、計算、轉換等功能程序中,具有程序簡單、執(zhí)行速度快等優(yōu)點。,1. 用MOVC A,@A+PC查表指令編程【例4-16/3-41】用查表方法編寫彩燈控制程序,編程使彩燈先順次點亮,再逆次點亮,然后連閃3下,反復循環(huán)。,39,,START:MOVR0,#00HLOOP:CLRA MOVA,R0 ADDA,
34、#0CH MOVCA,@A+PCCJNEA,#03H,LOOP1; 3字節(jié)SJMPSTART ; 2字節(jié)LOOP1: MOVP2,A ; 2字節(jié) ACALLDEL ; 2字節(jié) INCR0 ; 1字節(jié) SJMPLOOP ;
35、 2字節(jié)TAB: DB 0FEH,0FDH,0FBH,0F7H, 0EFH,0DFH,0BFH,07FH DB 0BFH, 0DFH, 0EFH, 0F7H, 0FBH, 0FDH, 0FEH DB 00H,0FFH,00H,0FFH,00H,0FFH,03H,DEL:MOVR7,#03HDEL1:MOVR6,#0FFHDEL2:MOVR5,#0FFHDEL3:D
36、JNZR5,DEL3 DJNZR6,DEL2 DJNZR7,DEL1 RET END,2. 用MOVC A,@A+DPTR查表指令編程【例4-17/3-42】START: MOVDPTR,#TABLOOP: CLRA MOVCA, @A+DPTR CJNEA,
37、#03H,LOOP1 JMPSTARTLOOP1:MOVP2,A ACALLDEL INCDPTR JMPLOOPTAB: DB 0FEH,0FDH,0FBH,0F7H, 0EFH,0DFH,0BFH,07FH DB 0BFH, 0DFH, 0EFH, 0F7H, 0FBH, 0FDH, 0FEH
38、 DB 00H,0FFH,00H,0FFH,00H,0FFH,03H,DEL:MOVR7,#03HDEL1:MOVR6,#0FFHDEL2:MOVR5,#0FFHDEL3:DJNZR5,DEL3 DJNZR6,DEL2 DJNZR7,DEL1 RET END,42,,43,44,,45,,ORG
39、 00HSTART:MOVDPTR,#NUM_TABLE; 裝表,DPTR指向數(shù)據(jù)NUM_TABLELOADTABLE:CLRA; 累加器A清0MOVCA,@A+DPTR; 取表操作CJNEA,#88H,DISPLAY; JMPSTART; 循環(huán)DISPLAY:MOVP0,A; 顯示數(shù)據(jù)從P0口輸出CALLDELAY; 調(diào)延時子程
40、序INCDPTR; DPTR自增1JMPLOADTABLE; 繼續(xù)取表顯示,46,,DELAY:MOVR5,#20; 延時200msD2:MOVR6,#20D1:MOVR7,#248DJNZR7,$DJNZR6,D1DJNZR5,D2RETNUM_TABLE:; 七段數(shù)碼管顯示數(shù)據(jù)表DB40H,79H,24H,30H,19H
41、DB12H,02H,78H,00H,10HDB88HEND,4.4 散轉程序設計散轉程序是分支程序的一種,它由輸入條件或運算結果來確定轉入各自的處理程序。,4.4.1 用轉移指令表實現(xiàn)散轉在許多場合中,要根據(jù)某一單元的值0, 1, 2, …, n分別轉向處理程序0,處理程序1, …,處理程序n。這時可以用轉移指令AJMP(或LJMP)組成一個轉移表?!纠?-18】根據(jù)R6的內(nèi)容,轉向各個處理程序。R
42、6=0,轉LOP0R6=1,轉LOP1R6=2,轉LOP2把轉移標志送累加器A,轉移表首地址送DPTR,利用JMP @A+DPTR實現(xiàn)轉移。,解:分析題意可編寫出以下程序: START: MOV DPTR, #TAB1 MOV A, R6 ADD A, R6 JNC PAD
43、 INC DPH PAD:JMP @A+DPTR TAB1: AJMP LOP0 AJMP LOP1 AJMP LOP2 LOP1:….. RETLOP2:….. RET LOP0:….. RET END,4.4.2 用轉移地址表實現(xiàn)散轉當轉向范圍比較大
44、時,可直接使用轉向地址表方法,即把每個處理程序的入口地址直接置于地址表內(nèi)。用查表指令,找到對應的轉向地址,把它裝入DPTR中。將累加器清零后用JMP @A+DPTR直接轉向各個處理程序的入口。,【例4-19】根據(jù)R3的內(nèi)容轉向對應處理程序。處理程序的入口分別是LOP0~LOP2。ORG 0000HPJ3:MOVDPTR,#TAB3 MOVA,R3 ADDA,R3;R3*2
45、 JNCCAD INCDPH;有進位DPTR高位加1CAD:MOVR2,A;暫存R2 MOVCA,@A+DPTR XCHA,R2;程序入口地址高8位暫存R2 INCA MOVCA,@A+DPTR MOVDPL,A;程序入口地址低8位暫存DPL MOVDPH,R2
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經(jīng)權益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 眾賞文庫僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
- 6. 下載文件中如有侵權或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
評論
0/150
提交評論