|
|
| <!--插入廣告JS代碼--> |
程序編寫做到:
占用存儲空間少;
運(yùn)行時間短;
程序的編制、調(diào)試及排錯所需時間短;
結(jié)構(gòu)清晰,易讀、易于移植。
按結(jié)構(gòu)化程序設(shè)計思想,任何復(fù)雜程序都可由順序結(jié)構(gòu)、分支結(jié)構(gòu)、循環(huán)結(jié)構(gòu)等構(gòu)成。
如圖1所示。


一、順序程序舉例
例1、設(shè)在外RAM的60H單元存有1個字節(jié)代碼,要求將其分解成兩個4位字段,高4位存入原單元的低4位,其低4位存入61H單元的低4位,且要求這兩個單元的高4位均為0,試編制完整程序。
解: 字節(jié)分解:

核心指令
MODE: | ANL ORL 1000H MODE:MOV R0,#60H MOVX A,@R0 MOV B,A ANL A,#0F0H SWAP A MOVX @R0,A ANL B,#0FH MOV A,B INC R0 MOVX @R0,A END
|
二、分支結(jié)構(gòu)與分支程序設(shè)計
結(jié)構(gòu):根據(jù)不同的條件,進(jìn)行相應(yīng)的處理。
通常用條件轉(zhuǎn)移指令形成簡單分支結(jié)構(gòu)。
如: 判(A) = Z 或 NZ ,轉(zhuǎn)移
判(CY)= 1 或 0 ,轉(zhuǎn)移
判(bit)=1 或 0 ,轉(zhuǎn)移
CJNE 比較不相等轉(zhuǎn)移
例3、設(shè)a存放在累加器A中,b存放在寄存器B中,要求按下式計算Y值,并將結(jié)果Y存于累加器A 中,試編寫程序。

解:本題關(guān)鍵是判a是正數(shù),還是負(fù)數(shù);由ACC7便知。
BR:
MINUS: DONE:
| ORG 1000H JB ACC7,MINUS CLR C SUBB A,B SJMP DONE ADD A,B SJMP $ END
|
例4、設(shè)有兩個16位無符號數(shù)NA,NB分別存放在8031單片機(jī)內(nèi)部RAM的40H、41H及50H、51H單元中,當(dāng)NA > NB時,將內(nèi)部RAM的42H單元清0;否則,將該單元置成全1,試編程。
解法I:因為無16位數(shù)的比較指令,所以,只能用8位數(shù)的比較指令。
(畫出流程框圖)
CMP:
CMP1:
HIGHE: DONE:
| ORG 2000H MOV A,50H CJNE A,40H,CMP1 MOV A,51H CJNE A,41H,CMP1 SJMP NHIGHE JC HIGHE NHIGHE:MOV 42H,#0FFH SJMP DONE MOV 42H,#00H SJMP $ END |
上述程序中多次用到SJMP語句,該語句為無條件轉(zhuǎn)移語句。無條件語句應(yīng)盡量少用,這樣可使程序結(jié)構(gòu)緊湊而易讀,易理解。
解法II:先假設(shè)NA > NB,再來判斷是否NA ≤ NB
CMP2:
CMP3: NHIGHE: HIGHE: | ORG 3000H MOV R0,#00H MOV A,50H CJNE A,40H,CMP3 MOV A,51H CJNE A,41H,CMP3 SJMP NHIGHE JC HIGHE MOV R0,#0FFH ;不大于標(biāo)志 MOV 42H,R0 SJMP $ END |
循環(huán)結(jié)構(gòu)不但使程序簡練,而且大大節(jié)省存儲空間。
循環(huán)程序包含四部分:
初始化部分
循環(huán)處理部分(主體)
循環(huán)控制部分(修改地址指針、修改變量、檢測循環(huán)結(jié)束條件)
循環(huán)結(jié)束部分(對結(jié)果分析、處理,存放結(jié)果)
循環(huán)有:單循環(huán)、多重循環(huán)。
循環(huán)次數(shù)已知,可用計數(shù)器控制循環(huán)次數(shù);
循環(huán)次數(shù)未知,按問題條件控制循環(huán)是否結(jié)束。
一、單循環(huán)程序
1、循環(huán)次數(shù)是已知的程序
例1、已知片外RAM的10H單元存放8位二進(jìn)制數(shù),要求將其轉(zhuǎn)移成相應(yīng)的ASCII碼,并以高位在前,低位在后的順序,依次存放到片外RAM以11H為首地址的連續(xù)單元中,試編程。

解:先將中間單元置成30H,然后判欲轉(zhuǎn)換位是否為1,
若是,則將中間單元內(nèi)容加1;否則,中間單元內(nèi)容保持不變。
通過左移指令實現(xiàn)由高到低的順序進(jìn)行轉(zhuǎn)換。
| | ORG 1000H | |
| START: | MOV R2,#08H | ;循環(huán)計數(shù)初值(循環(huán)次數(shù)已知) |
| MOV R0,#10H | ;地址指針初值 |
| MOVX A,@R0 | ;取數(shù) |
| MOV B,A | ;暫存B中 |
| LOOP: | MOV A,#30H | ;將中間單元(A)置成30H |
| JNB B.7,NA | ;判斷轉(zhuǎn)換的二進(jìn)制位為0否? |
| | ;若是轉(zhuǎn)NA |
| INC A | ;1的ASCII碼“31H” |
| NA: | INC R0 | ;修改地址指針 |
| | MOVX @R0,A | ;存放轉(zhuǎn)換的結(jié)果 |
| | MOV A,B | |
| | RL A,B | ;作好準(zhǔn)備,判斷下一位 |
| | MOV B,A | ;暫存 |
| | DJNZ R2,LOOP | ;判斷轉(zhuǎn)換結(jié)束否?未完繼續(xù) |
| | SJMP $ | |
| | END | |
2)循環(huán)次數(shù)未知的程序
例2、設(shè)用戶用鍵盤輸入長度不超過100字節(jié)的字符串放在8031單片機(jī)外部RAM以20H為首地址的連續(xù)單元,該字符串用回車符CR(‘CR’= 0DH)作為結(jié)束標(biāo)志,要求統(tǒng)計此字符串的長度并存入內(nèi)部RAM的1FH單元中。
解:從首單元開始取數(shù),每取一數(shù)判斷其是否為‘CR’,是則結(jié)束。
STADA SLANG
CMCR2:
CRLOP: | ORG 1000H DATA 20H DATA 1FH MOV R0,#STADA-1 MOV B,#0FFH INC R0 INC B MOVX A,@R0 CJNE A,#0DH,CRLOP MOV SLANG,B SJMP $ END |
2、多重循環(huán)設(shè)計
循環(huán)體中還包含著一個或多個循環(huán)結(jié)構(gòu),即雙重或多重循環(huán)。
例3、設(shè)8031使用12MHz晶振,試設(shè)計延遲100ms的延時程序。
解:延時程序的延遲時間就是該程序的執(zhí)行時間,通常采用MOV和DJNZ二指令。
T = 12 / fosc = 12 / (12×106)= 1us

內(nèi)循環(huán)延時:
(1 + 2 × CTR)T = 500us(假設(shè))
則CTR = 250
實際延時:[1 + 2 × 250] × 1us = 501us
外循環(huán)延時:T +(501 + 2T)× CTS = 100ms = 100 000us
所以 , CTS = 198.8 取 199
實際延時:[1 + (501 + 2)×199] = 1000.98ms
例4、設(shè)在8031內(nèi)部RAM中存一無符號數(shù)的數(shù)組,其長度為100,起始地址是30H,要求將它們從大到小排序,排序后仍存放在原區(qū)域中,試編者按程。

這就是所畏的“冒泡法”。
實際上大多情況,用不到99次循環(huán),排序就結(jié)束。為了提高排序速度,程序中可設(shè)一交換標(biāo)志位,如10H位,
每次循環(huán)中:若有交換則 SETB 10H
若無交換則 CLR 10H
每次循環(huán)結(jié)束時,測10H位,判斷排序是否結(jié)束。
BUBBLE:
LOOP:
BUEU:
BUNEXT:
| ORG 1000H MOV R0,#30H MOV B,#64H CLR 10H DEC B MOV A,@R0 MOV 20H,A INC R0 MOV 21H,@R0 CJNE A,21H,BUEU JNC BUNEXT MOV A,@R0 MOV @R0,20H DEC R0 MOV @R0,A INC R0 SETB 10H DJNZ B,LOOP JB 10H,BUBBLE END
|
;長度計數(shù) ;暫存,為交換作準(zhǔn)備
;若(20H)≠(21H)轉(zhuǎn)移 ;(20H)≥(21H)轉(zhuǎn)移 ;若(20H)< (21H)則交換
;使R0退格指向小地址
;恢復(fù)R0指向大地址 ;置交換標(biāo)志
;判斷標(biāo)志位為1否?若為1,則繼續(xù) |