透析 8051 之分支跳躍與迴圈控制 - 利用 VB 的程式觀念解說 迴圈的控制方法不失為寫程式最重要的技巧之所在之一, 它搭配邏輯運算的判斷作為迴圈繼續執行的判斷依據, 程式設計師必須考量分析所有可能的情況, 然後給予不同的條件, 當條件成立時執行某段程式, 不符合時執行另一段程式, 然後重複某項任務, 直到使用者中斷程式的執行, 或是條件喪失時才跳出迴圈 也可能一個程式重複著無止盡的迴圈, 直到關閉電源為止, 等 有鑑於此, 以下的控制方法, 是程式設計必須學會的 : 如何控制迴圈? 可以使用那些控制迴圈的指令? 邏輯判斷式的表示? 掌控程式流向的方法? 茲特別整理出來相關的指令及範例, 綜合幾種不同的常用作法, 利用高階語言的語法來對照, 透過 VB 的判斷式迴圈控制語法來說明, 相信能給你更方便的學習 8051 的程式寫作, 也因此進一步對學習市面上任何其它種類的微電腦程式語言, 均可以舉一而反三, 靈活應用於程式寫作 VB 語言有關迴圈 邏輯判斷式 分支跳躍及程式呼叫 等語法, 列表說明 VB 指令語法格式說明 Goto GoSub Return : Goto GoSub MyRoutine MyRoutine: Return 無條件的重複執行 呼叫同一 Sub 中的副程式 MyRoutine 副程式返回後繼續執行 GoSub 之後 的陳述式 副程式 ( 與呼叫程序同 Sub) 結束副程式, 返回呼叫程式 If..Then..Else If < 條件 > Then Else End IF 邏輯判斷式, 控制執行路徑 當 < 條件 > 成立, 執行, 否則, 執行 For...Next For i= 初值 To 終值 Step 增量 Next 明確指定變數 i 的初值 終值 增量 控制執行敘述的次數
While While < 條件 > Do While.. Do Until.. Select Case Do While < 條件 > Do While < 條件 > Do Until < 條件 > Do Until < 條件 > Select Case n Case 1 Case 2 End Select 先測試後執行 : 當 < 條件 > 成立, 則重複執行 先測試後執行 : 當 < 條件 > 成立, 則重複執行 先執行後測試 : 先執行, 再判斷是否繼續執行 當 < 條件 > 成立, 則重複執行 先測試後執行 : 當 < 條件 > 不成立, 則重複執行 先執行後測試 : 先執行, 再判斷是否繼續執行 當 < 條件 > 不成立, 則重複執行 多選一當符合條件 1, 執行當符合條件 2, 執行 8051 有關迴圈 邏輯判斷式 分支跳躍及程式呼叫 等語法, 列表說明 8051 指令語法範例說明 JMP JB bit,rel JNB bit,rel JMP LOOP JB BIT1,LOOP1 JNB BIT1,LOOP1 無條件的重複執行 當 BIT1=1, 則跳至 LOOP1, 否則, 執行 BIT1: 凡符合位元定址之位元均屬 之, 如 20h.1,2fh.3,P0.7,PSW.0 (Jmp to LOOP1 if BIT1=1) 當 BIT1=0( 即不為 1), 則跳至 LOOP1, 否則, 執行 (Jmp to LOOP1 if BIT1<>1)
JBC bit,rel JC rel JNC rel JZ rel JNZ rel CJNE data1,data2,rel DJNZ data1,rel JBC BIT1,LOOP1 JC LOOP1 JNC LOOP1 JZ LOOP1 JNZ LOOP1 CJNE A,#01,LOOP1 DJNZ R0,LOOP 當 BIT1=1, 則跳至 LOOP1, 執行, 並清除此 bit 為 0 否則, 執行 (Jmp to LOOP1 if BIT1=1,Clear BIT1) 運算後, 當進位旗標 C=1, 則跳至 LOOP1 否則, 執行 (Jmp to LOOP1 if C=1) 運算後, 當沒有進位時,C=0( 即不為 1), 則跳至 LOOP1 否則, 執行 (Jmp to LOOP1 if C<>1) 運算後, 當零旗標 Z=1, 則跳至 LOOP1 否則, 執行 (Z=1 表示運算結果使 ACC=0) Z 旗標只對 ACC 判斷 (Jmp to LOOP1 if Z=1) 運算後, 當零旗標 Z=0, 則跳至 LOOP1 否則, 執行 (Z=1 表示運算結果使 ACC=0) (Jmp to LOOP1 if Z<>1) 比較 (Compare) 兩值是否不相等, 當 ACC 的值不等於 1, 則跳至 LOOP1 執行, 否則, 執行 data1: 可以是 A Rn 或 @Ri data2: 可以是 #data,direct (jmp to LOOP1 if ACC<>#01) R0=R0-1, 並判斷是否為 0, 當 R0<>0, 跳回 LOOP 繼續執行 否則, 往下執行 data1: 可以是 Rn direct (R0=R0-1, jmp to LOOP if R0<>0)
8051 與 VB 之相似對照範例 項目 8051 VB 說明 1 2 P0=A INC A MOV A,R0 SUBB A,#10 JC MyRoutine Next: P0=A JMP Other MyRoutine: INC A JMP Next Other: 3 JB BIT1,S1 JMP S2 S1: ACALL SUB1 JMP Next S2: ACALL SUB2 Next: Sub1() Print A GOTO LOOP If N<10 Then GoSub MyRoutine Print N Exit Sub MyRoutine: N = N+1 Return End Sub IF BIT1=1 THEN CALL SUB1 ELSE CALL SUB2 ENDIF 無條件跳躍 無盡迴圈 當 A-10 產生借位 (C=1) 則表示變數值小於 10 狀況一 : 當 N<10, 則執 行副程式 N+1 後返回並 輸出 狀況二 : 若 N>=10, 則 直接輸出 當 BIT=1, 跳 S1 否則, 跳 S2 副程式呼叫 SUB1 返回後跳 Next 繼續向下 執行 副程式呼叫 SUB2 4 SUBB A,#1 JZ S1 JMP S2 S1: ACALL SUB1 JMP Next S2: ACALL SUB2 Next: ACC=ACC-1 IF ACC=0 THEN CALL SUB1 ELSE CALL SUB2 ENDIF JZ 指令 : 判斷 ACC 是否為 0 是, 則零旗標 Z=1, 跳 S1, 呼叫副程式 1 否則, 跳 S2, 呼叫副程式 1 5 MOV R0,#10 INC A DJNZ R0,L1 FOR I=1 TO 10 NEXT R0 訂定迴圈次數 =10 次 以 DJNZ 遞減 1 後判斷是 否為 0
6 MOV R0,#0 MOV A,#0 ADD A,R0 INC R0 INC R0 CJNE R0,#22,L1 MOV P0,A 7 MOV R0,#20 MOV A,#0 ADD A,R0 DEC R0 DJNZ R0,L1 MOV P0,A 8 CLR C JC L2 ADD A,#1 L2: MOV P0,A 9 CLR C JNC L2 JMP L3 L2: ADD A,#1 L3: MOV P0,A 10 MOV R1,#2 CJNE R1,#1,L2 MOV P0,#1 L2: CJNE R1,#2,L3 MOV P0,#2 L3: CJNE R1,#3,L4 MOV P0,#3 L4: 11 BIT1 EQU 20H.0 CLR BIT1 CPL BIT1 N=0 Sum=0 While N<=20 Sum=Sum+N N=N+2 Print Sum N=0 Sum=0 Do While N<=20 Sum=Sum+N N=N+2 Print Sum C=0 DO While C=0 IF A>255 THEN C=1 LOOP Print A C=0 Do Until C=1 IF A>255 THEN C=1 Print A Select Case n Case 1 Print 1 Case 2 Print 2 Case 3 Print 3 End Select Dim BIT1 As Boolean BIT1=False While (1) BIT1=Not BIT1 變數 N=0 總和 =0 計算 Sum=2+4+6+ 20 用 CJNE 判斷已執行迴圈數 注意 :( 先加 2 後判斷 ) 與 ( 先判斷後加 2) 之區別與上一項目同功能, 唯作法不同 用 DJNZ 判斷已執行迴圈數 VB: 以 Do While 完成相同的功能 8051 為 8 位元, 當 ACC 超過 255=256 時, 使進位旗標 C=1, 並使 ACC=0 以 JC 是否進位判斷迴圈之執行 功能同上 以 JNC 判斷, 直到產生進位為止 VB: 以 Do Until 完成相同的功能多選一判斷式 : 當 R1=1, 輸出 1 當 R1=2, 輸出 2 當 R1=3, 輸出 3 定義布林數 ( 位元定址 ) 初值設定無盡迴圈反相
L2: JNB BIT1,L2 MOV P0,#0H Call Delay MOV P0,#0FFH Call Delay1s IF BIT1 THEN ACC= 00h Else ACC= FFh End If Label1=ACC Call Delay1s 當 BIT1=True 輸出 00 當 BIT1=False 輸出 FF 輸出, 並延時 1 秒 12 MOV A,#0 JB ACC.0,L1 MOV P0,#00H JMP L2 MOV P0,#0FFH L2: INC A CALL Delay JMP LOOP A=0 While (1) IF A MOD 2=0 THEN ACC= 00h Else ACC= FFh End if Label1=ACC Call Delay1s 初值設定無盡迴圈當 A= 偶數, 輸出 00 當 A= 奇數, 輸出 FF ( 偶數 : 最低位元 LSB=0) ( 奇數 : 最低位元 LSB=1) 輸出, 並延時 1 秒