基于8086的匯編代碼,用到了8254以及8255芯片
功能實作是一個打地鼠小游戲
原理大概是8255A口作為LED燈輸出,B口作為開關輸入,C口作為數碼管顯示
10個50Hz中斷為一個周期,每個中斷判斷開關是否變化,若變化則與LED對比,一致便得分。
滿十個中斷后進入下一個周期,亮起下一個燈泡。
看不懂的地方:
1. 代碼段SET_NMI_INT。看起來是8259的中斷,但是沒有用到8259芯片,測驗刪掉代碼就不能按原邏輯運行了,
2. 代碼段UPDATE_LED。他這里重繪LED的邏輯是什么?
DATA SEGMENT
I8253_1 EQU 0288H
I8253_2 EQU 028AH
I8253_MODE EQU 028EH
I8255_A EQU 0280H
I8255_B EQU 0282H
I7SEG_1 EQU 0284H
I8255_MODE EQU 0286H
SYMBOL_7SEG DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH
DIGITS DB 0
RANDOM_NUMBER DB ?
LED DB 1
SWITCH DB ?
INT_TIMES DB 1
DATA ENDS
STACKS SEGMENT STACK
DB 1024 DUP (0)
STACKS ENDS
CODE SEGMENT
ASSUME CS:CODE,DS:DATA,SS:STACKS
START:
MOV AX,DATA
MOV DS,AX
MOV AX,STACKS
MOV SS,AX
MOV DX,I8255_MODE ;初始化8255作業方式
MOV AL,82H
OUT DX,AL
MOV DX,I8255_A ;A輸出
MOV AL,0
OUT DX,AL
MOV [RANDOM_NUMBER],47
MOV DX,I8255_B ;B輸入
IN AL,DX
MOV [SWITCH],AL
CALL SET_NMI_INT
CALL PRINT_SCORE
CALL SET_TIMER
@WAIT:
JMP @WAIT
SET_TIMER PROC NEAR
MOV DX,I8253_MODE ;初始化8254作業方式
MOV AL,00100101B
OUT DX,AL
MOV DX,I8253_1
MOV AL,01H
OUT DX,AL
MOV DX,I8253_MODE
MOV AL,01100101B
OUT DX,AL
MOV DX,I8253_2
MOV AL,10H
OUT DX,AL
RET
SET_TIMER ENDP
SET_NMI_INT PROC NEAR
PUSH DS
MOV AX, CS
MOV DS, AX
MOV DX, OFFSET NMI_HANDLER ;采用間接修改法,設定中斷向量
MOV AX, 250BH ;設定對應的中斷向量
INT 21H
IN AL, 21H ;讀中斷屏蔽暫存器,21H是該暫存器的埠號
AND AL, 0F7H ;開放中斷,允許的中斷申請
OUT 21H, AL
STI
POP DS
RET
SET_NMI_INT ENDP
UPDATE_LED PROC NEAR
XOR AX,AX
MOV AL,[RANDOM_NUMBER]
PUSH AX
MOV DL,8
DIV DL
MOV CL,AH
MOV BL,1
SHL BL,CL
MOV [LED],BL
POP AX
MOV DL,23
MUL DL
MOV DL,97
DIV DL
MOV [RANDOM_NUMBER],AH
MOV DX,I8255_A
MOV AL,BL
OUT DX,AL
RET
UPDATE_LED ENDP
ADD_SCORE PROC NEAR ;得分程式
MOV AL,[DIGITS]
INC AL ;如果得分分數+1
CMP AL,10
JNZ @ADD_SCORE_NEXT ;不等于10跳轉,否則數碼管跳回0
MOV AL,0
@ADD_SCORE_NEXT:
MOV [DIGITS],AL ;更新得分后成績
RET
ADD_SCORE ENDP
PRINT_SCORE PROC NEAR ;數碼管分數顯示
MOV DL,[DIGITS]
MOV DH,0
MOV DI,OFFSET SYMBOL_7SEG
ADD DI,DX
MOV DX,I7SEG_1
MOV AL,BYTE PTR [DI]
OUT DX,AL
RET
PRINT_SCORE ENDP
UPDATE PROC NEAR ;更新
DEC [INT_TIMES] ;剩余重繪時間-1
JNZ @UPDATE_ELSE ;不為0跳轉判斷是否得分
MOV [INT_TIMES],10 ;累計是個中端進入下一次亮燈
CALL UPDATE_LED
@UPDATE_ELSE:
MOV DX,I8255_B ;開關輸入
IN AL,DX
MOV CH,[SWITCH] ;燈泡輸出
MOV [SWITCH],AL
XOR AL,CH ;兩次中斷間開關有變化
XOR AL,[LED] ;變化開關與亮起燈泡是否一致
JNZ @UPDATE_NO_SCORE ;開關沒變化或不一致不得分
CALL ADD_SCORE ;否則得分
CALL PRINT_SCORE
@UPDATE_NO_SCORE:
RET
UPDATE ENDP
NMI_HANDLER:
MOV AX,DATA
MOV DS,AX
MOV AX,STACKS
MOV SS,AX
CALL UPDATE
MOV AL, 20H ;發出EOI結束中斷到PC內主片的地址20H
OUT 20H, AL
IRET
CODE ENDS
END START
uj5u.com熱心網友回復:
SET_NMI_INT 應該是呼叫dos修改鍵盤中斷向量UPDATE_LED應該是通過一個亂數計算控制led燈?
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/67410.html
標籤:單片機/工控
下一篇:有使用vx653的大神同學嗎
