实验内容
- 程序开始时
LED
灯D7-D0
全亮。 - 按下单脉冲开关
KK1
,响应IR6
中断请求,使绿灯(D3-D0
)亮,红灯(D7-D4
)灭。 - 按下单脉冲开关
KK2
,响应IR7
中断请求,使红灯(D7-D4
)亮,绿灯(D3-D0
)灭。
实验接线
LED
连接 8255
的 B
口,KK1+
连接 MIR6
,KK2+
连接 MIR7
。如下图所示:
代码
CODE SEGMENT ASSUME CS:CODE START: MOV AX, 0 MOV DS, AX ;; INIT 8255 MOV DX, 0646H MOV AL, 90H ;; 10010000B, INPUT FROM A & OUTPUT TO B OUT DX, AL ;; MIR6 MOV AX, OFFSET MIR6 ;; PUT CS:IP TO INTERRUPT VECTOR ADDRESS ;; 6: 38H - 3BH ;; IP -> 38H ;; CS -> 3AH MOV SI, 38H MOV [SI], AX MOV AX, CS MOV SI, 3AH MOV [SI], AX ;; MIR7 MOV AX, OFFSET MIR7 ;; 7: 3CH - 3FH ;; IP -> 3CH ;; CS -> 3AH MOV SI, 3CH MOV [SI], AX MOV AX, CS MOV SI, 3EH MOV [SI], AX ;; -------------------------------------------------- ;; INIT 8259 CLI ;; DISABLE INTERRUPT MOV AL, 11H ;; ICW1 00010001B ;; ----A-BC ;; A: 1=HIGH, 0=UPPER EDGE ;; B: 1=SINGLE, 0=MULTIPLE ;; C: NEED ICW4 OUT 20H, AL MOV AL, 08H ;; ICW2 00001000B ;; OUT 21H, AL MOV AL, 04H ;; ICW3 00000100B ;; -----AB- ;; A: 1 = INNER SUB 8259 CONNECTED TO IR2 ;; 0 = NOT USED ;; B: ANY 8259 CONNECTED TO MAIN IR1 OUT 21H, AL MOV AL, 07H ;; ICW4 00000111B ;; ----ABC- ;; A: 1 = BUFFERED ;; 0 = NOT BUFFERED ;; B: 1 = MAIN ;; 0 = SUB ;; C: 1 = AUTO INTERRUPT STOP ;; 0 = NOT AUTO OUT 21H, AL MOV AL, 2FH ;; OCW1 00101111B ;; M7 - M0 ;; 0 = ALLOWED ;; 1 = DISABLED ;; IR4 IS USED TO COMMUNICATE WITH PC OUT 21H, AL STI ;; ALLOW INTERRUPT ;; -------------------------------------------------- AA1: ;; MAIN MOV DX, 0642H MOV AL, 0FFH OUT DX, AL JMP AA1 MIR6: MOV DX, 0642H MOV AL, 0FH ;; GREEN LIGHT OUT DX, AL CALL DELAY IRET MIR7: MOV DX, 0642H MOV AL, 0F0H OUT DX, AL ;; RED LIGHT CALL DELAY IRET DELAY PROC NEAR MOV CX, 0FFFFH LOOP $ MOV CX, 0FFFFH LOOP $ MOV CX, 0FFFFH LOOP $ MOV CX, 0FFFFH LOOP $ RET DELAY ENDP CODE ENDS END START
选做实验 1
描述
使用单脉冲开关控制 LED
的移动方向,初始状态仅点亮 D7
。
当 KK1
按下时,LED
灯向右移动;当 KK2
按下时,LED
灯向左移动;当 LED
灯移动到单侧边界时,停止移动。
分析
需要保存当前移动的状态,使得中断嵌套执行完后原中断不继续执行。
代码
CODE SEGMENT ASSUME CS:CODE START: ;; BH: MODIFIED ;; BL: STATUS MOV BX, 0080H ;; INIT 8255 MOV DX, 0646H MOV AL, 90H ;; 10010000B, INPUT FROM A & OUTPUT TO B OUT DX, AL ;; MIR6 MOV AX, OFFSET MIR6 ;; PUT CS:IP TO INTERRUPT VECTOR ADDRESS ;; 6: 38H - 3BH ;; IP -> 38H ;; CS -> 3AH MOV SI, 38H MOV [SI], AX MOV AX, CS MOV SI, 3AH MOV [SI], AX ;; MIR7 MOV AX, OFFSET MIR7 ;; 7: 3CH - 3FH ;; IP -> 3CH ;; CS -> 3AH MOV SI, 3CH MOV [SI], AX MOV AX, CS MOV SI, 3EH MOV [SI], AX ;; -------------------------------------------------- ;; INIT 8259 CLI ;; DISABLE INTERRUPT MOV AL, 11H ;; ICW1 00010001B ;; ----A-BC ;; A: 1=HIGH, 0=UPPER EDGE ;; B: 1=SINGLE, 0=MULTIPLE ;; C: NEED ICW4 OUT 20H, AL MOV AL, 08H ;; ICW2 00001000B ;; OUT 21H, AL MOV AL, 04H ;; ICW3 00000100B ;; -----AB- ;; A: 1 = INNER SUB 8259 CONNECTED TO IR2 ;; 0 = NOT USED ;; B: ANY 8259 CONNECTED TO MAIN IR1 OUT 21H, AL MOV AL, 07H ;; ICW4 00000111B ;; ----ABC- ;; A: 1 = BUFFERED ;; 0 = NOT BUFFERED ;; B: 1 = MAIN ;; 0 = SUB ;; C: 1 = AUTO INTERRUPT STOP ;; 0 = NOT AUTO OUT 21H, AL MOV AL, 2FH ;; OCW1 00101111B ;; M7 - M0 ;; 0 = ALLOWED ;; 1 = DISABLED ;; IR4 IS USED TO COMMUNICATE WITH PC OUT 21H, AL STI ;; ALLOW INTERRUPT ;; -------------------------------------------------- AA1: ;; MAIN MOV DX, 0642H MOV AL, BL OUT DX, AL JMP AA1 MIR6: STI MOV BH, 1 MOV DX, 0642H IR6_RIGHT: CMP BL, 1 ;; MOST RIGHT JE IR6_STOP SHR BL, 1 MOV AL, BL OUT DX, AL CALL DELAY CMP BH, 1 ;; CHECK WHETHER NESTED INTERRUPT HAPPENED JNE IR6_STOP JMP IR6_RIGHT IR6_STOP: MOV BH, 0 IRET MIR7: STI MOV BH, 1 MOV DX, 0642H IR7_LEFT: CMP BL, 80H ;; MOST LEFT JE IR7_STOP SHL BL, 1 MOV AL, BL OUT DX, AL CALL DELAY CMP BH, 1 ;; CHECK WHETHER NESTED INTERRUPT HAPPENED JNE IR7_STOP JMP IR7_LEFT IR7_STOP: MOV BH, 0 IRET DELAY PROC NEAR MOV CX, 0FFFFH LOOP $ MOV CX, 0FFFFH LOOP $ MOV CX, 0FFFFH LOOP $ MOV CX, 0FFFFH LOOP $ RET DELAY ENDP CODE ENDS END START
选做实验 2
描述
在选做实验 1 的基础上,增加:
- 在向左移动过程中,如果要求其向右移动,则立即改变方向,向右移动。到最右侧后,向左移动到最左侧。
- 在向右移动中,如果要求其向左移动,不立即改变方向,等到移动到最右侧后再开始向左移动。
分析
在当前移动状态的基础上,增加是否需要向左移动的标志。在向右移动中断处理程序(MIR6
)的最后,当需要向左移动时,则调用向左移动中断处理程序(MIR7
)。
代码
CODE SEGMENT ASSUME CS:CODE START: ;; BH: MODIFIED ;; 00 = IDLE ;; 01 = GOING_LEFT ;; 10 = GOING_RIGHT ;; 11 = GOING_RIGHT(DEFER GO RIGHT) ;; BL: STATUS MOV BX, 0080H ;; INIT 8255 MOV DX, 0646H MOV AL, 90H ;; 10010000B, INPUT FROM A & OUTPUT TO B OUT DX, AL ;; MIR6 MOV AX, OFFSET MIR6 ;; PUT CS:IP TO INTERRUPT VECTOR ADDRESS ;; 6: 38H - 3BH ;; IP -> 38H ;; CS -> 3AH MOV SI, 38H MOV [SI], AX MOV AX, CS MOV SI, 3AH MOV [SI], AX ;; MIR7 MOV AX, OFFSET MIR7 ;; 7: 3CH - 3FH ;; IP -> 3CH ;; CS -> 3AH MOV SI, 3CH MOV [SI], AX MOV AX, CS MOV SI, 3EH MOV [SI], AX ;; -------------------------------------------------- ;; INIT 8259 CLI ;; DISABLE INTERRUPT MOV AL, 11H ;; ICW1 00010001B ;; ----A-BC ;; A: 1=HIGH, 0=UPPER EDGE ;; B: 1=SINGLE, 0=MULTIPLE ;; C: NEED ICW4 OUT 20H, AL MOV AL, 08H ;; ICW2 00001000B ;; OUT 21H, AL MOV AL, 04H ;; ICW3 00000100B ;; -----AB- ;; A: 1 = INNER SUB 8259 CONNECTED TO IR2 ;; 0 = NOT USED ;; B: ANY 8259 CONNECTED TO MAIN IR1 OUT 21H, AL MOV AL, 07H ;; ICW4 00000111B ;; ----ABC- ;; A: 1 = BUFFERED ;; 0 = NOT BUFFERED ;; B: 1 = MAIN ;; 0 = SUB ;; C: 1 = AUTO INTERRUPT STOP ;; 0 = NOT AUTO OUT 21H, AL MOV AL, 2FH ;; OCW1 00101111B ;; M7 - M0 ;; 0 = ALLOWED ;; 1 = DISABLED ;; IR4 IS USED TO COMMUNICATE WITH PC OUT 21H, AL STI ;; ALLOW INTERRUPT ;; -------------------------------------------------- AA1: ;; MAIN MOV DX, 0642H MOV AL, BL OUT DX, AL JMP AA1 ;; -------------------------------------------------- MIR6: ;; INTEND TO GO RIGHT STI MOV DX, 0642H ;; PRESS KK1 WHEN GOING RIGHT TEST BH, 10B JNZ IR6_EXIT_IRET ;; BH MUST BE 0 OR 1 ;; BH = 0 ==> MOV BH, 10B ;; BH = 1 ==> MOV BH, 11B OR BH, 10B IR6_RIGHT: CMP BL, 1 ;; MOST RIGHT JE IR6_LEFT SHR BL, 1 MOV AL, BL OUT DX, AL CALL DELAY JMP IR6_RIGHT IR6_LEFT: TEST BH, 1 ;; NEED TO GO LEFT JZ IR6_EXIT MOV BH, 1 ;; SET MODE TO GOING_LEFT JMP MIR7 IR6_EXIT: ;; NORMAL EXIT MOV BH, 0 IR6_EXIT_IRET: IRET ;; -------------------------------------------------- MIR7: ;; INTEND TO GO LEFT STI TEST BH, 10B ;; GOING TO RIGHT NOW JNZ IR7_IRET ;; EXIT MOV BH, 1 MOV DX, 0642H IR7_LEFT: CMP BL, 80H ;; MOST LEFT JE IR7_STOP SHL BL, 1 MOV AL, BL OUT DX, AL CALL DELAY CMP BH, 1 ;; WHETHER TO CONTINUE GOING LEFT JNE IR7_STOP JMP IR7_LEFT IR7_STOP: MOV BH, 0 ;; BACK TO IDLE IRET IR7_IRET: OR BH, 01B ;; GO TO LEFT AFTER RIGHT FINISHED IRET DELAY PROC NEAR MOV CX, 0FFFFH LOOP $ MOV CX, 0FFFFH LOOP $ MOV CX, 0FFFFH LOOP $ MOV CX, 0FFFFH LOOP $ RET DELAY ENDP CODE ENDS END START