程序編寫做到:
占用存儲空間少;
運行時間短;
程序的編制、調試及排錯所需時間短;
結構清晰,易讀、易于移植。
按結構化程序設計思想,任何復雜程序都可由順序結構、分支結構、循環結構等構成。
如圖1所示。


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

核心指令 ANL
ORL 1000H
MODE: 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
二、分支結構與分支程序設計
結構:根據不同的條件,進行相應的處理。
通常用條件轉移指令形成簡單分支結構。
如: 判(A) = Z 或 NZ ,轉移
判(CY)= 1 或 0 ,轉移
判(bit)=1 或 0 ,轉移
CJNE 比較不相等轉移
例3、設a存放在累加器A中,b存放在寄存器B中,要求按下式計算Y值,并將結果Y存于累加器A 中,試編寫程序。

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

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

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

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