1、題目
當開關合上,16個LED燈從上而下依次循環發光,每次只能點亮一個LED燈;
當開關打開,保持當前LED燈的點亮狀態不變,下次開關合上時,從當前的LED燈開始點亮。
2、電路圖
2.1總圖
2.2分圖
3、編程
;當開關合上,16個LED燈從上而下依次循環發光,每次只能點亮一個LED燈(燈亮 -> 延時 -> 燈滅(下一個亮) ->延時...)
;當開關打開,保持當前LED燈的點亮狀態不變,下次開關合上時,從當前的LED燈開始點亮。
;輸入端口爲IO5(0000 0010 1110 0**0B)
;定義符號常量
IOCON EQU 02D6H ;控制口(0000 0010 1110 0110B),輸出
IOA EQU 02D0H ;端口A (0000 0010 1110 0000B),輸入
IOB EQU 02D2H ;端口B (0000 0010 1110 0010B),輸入
IOC EQU 02D4H ;端口C (0000 0010 1110 0010B),輸入
CODE SEGMENT
ASSUME CS:CODE
;初始化8255A(往控制口寫控制字,即對CPU而言就是輸出)
START: MOV AL,10001001B ;從左到右:1表示工作方式控制字 00表示工作方式選擇 0端口A輸出 1端口C輸入 0端口B工作方式選擇 0端口B輸出 1端口C輸入。CPU控制字經AL輸出
MOV DX,IOCON ;口地址爲16位,寫入控制口輸出,將控制口地址送給DX
OUT DX,AL ;把工作方式控制字寫入控制口
MOV BX,0001H ;BX的值控制哪個燈亮即爲1,;初始狀態PA0=1(無論開始開關斷開還是閉合,總是第一個亮着的)
;從上往下A端口、B端口各決定8個燈(BX = BH + BL)
NEXT: MOV AL,BL ;將BL(初始是01H送給AL,即端口A控 制的8個燈)
MOV DX,IOA ;將端口A地址送給DX
OUT DX,AL ;輸出端口A燈亮的情況
MOV AL,BH ;將BH(初始是00H送給AL,即端口B控制的8個燈)
MOV DX,IOB ;將端口B的地址送給DX
OUT DX,AL ;輸出端口B燈亮的情況
MOV DX,IOC ;將端口C的地址送給DX
IN AL,DX ;讀取PC口檢測開關狀態
TEST AL,00000010B;測試PC1是0還是1
JNZ NEXT ;ZF=0,即PC1=1(開關斷開)跳轉到NEXT(ZF零標誌位,結果爲0ZF=1,結果不爲0ZF=0),對當前BX再次輸出(開關一直斷開,一直重複當前燈亮的代碼,就是看起來燈亮暫停了)
ROL BX,1 ;開關閉合,ROL對BX循環左移,控制流水燈效果(如:第一次執行到此處,BX(0001H -> 0002H,將會(繼續執行A1內容到OUT後)由第一個燈亮變成第二個燈亮)
Delayed_jump: CALL DELAY ;調用子函數,延時控制
JMP NEXT ;跳轉到NEXT,NEXT決定下一個動作燈是亮還是滅(燈亮 -> 延時 -> 燈滅(下一個亮) ->延時)
DELAY PROC
MOV CX,0FFFFH ;LOOP 指令循環次數須放在CX 中
Null_loop: NOP ;NOP指令執行時花去一個時鐘週期(多個NOP就花去多個時鐘週期),可把它用在延時程序中作爲循環體,用以估計一個延時時間
LOOP Null_loop ;空循環達到延時目的(這種軟件延時時間上不太精準)
RET
DELAY ENDP
CODE ENDS
END START