实验一
DATA SEGMENT
OUTPORT1 EQU 290H
OUTPORT2 EQU 2A0H
DATA ENDS
CODE SEGMENT
ASSUME CS:CODE,DS:DATA
START: MOV AX,DATA
MOV DS,AX
CNG: MOV DX,OUTPORT1
OUT DX,AL
CALL DELAY ;调延时子程序
MOV DX,OUTPORT2
OUT DX,AL
CALL DELAY ;调延时子程序
MOV AH,1
INT 16H
JE CNG
MOV AX,4C00H
INT 21H
DELAY PROC NEAR ;延时子程序
MOV BX,200
LLL: MOV CX,0
LL: LOOP LL
DEC BX
JNE LLL
RET
DELAY ENDP
CODE ENDS
END START
实验二
DATA SEGMENT
PORTA EQU 288H ; A口地址(LED控制)
PORTC EQU 28AH ; C口地址(按键检测)
CTRL_PORT EQU 28BH ; 控制端口(基地址+3,确认硬件基地址正确)
DATA ENDS
CODE SEGMENT
ASSUME CS:CODE, DS:DATA
START:
MOV AX, DATA
MOV DS, AX
; 初始化8255:A口输出,C口低三位输入
MOV DX, CTRL_PORT
MOV AL, 8BH ; 控制字:10001011(A口输出,C口低三位输入)
OUT DX, AL
MAIN_LOOP:
; 检测按键状态(使用AH保存,避免覆盖AL)
MOV DX, PORTC
IN AL, DX
AND AL, 07H ; 取PC0-PC2(K5-K7)
CALL DEBOUNCE_DELAY ; 去抖动
; 优先级判断
TEST AL, 01H ; K5按下?
JNZ MODE1
TEST AL, 02H ; K6按下?
JNZ MODE2
TEST AL, 04H ; K7按下?
JNZ MODE3
; 无按键:全灭
MOV DX, PORTA
MOV AL, 00H
OUT DX, AL
JMP MAIN_LOOP
; 模式1:左→右跑马灯(修复寄存器冲突)
MODE1:
MOV BL, 01H ; BL保存LED状态(LED0亮)
MODE1_LOOP:
MOV DX, PORTA
MOV AL, BL
OUT DX, AL ; 输出当前LED状态
CALL DELAY ; 延时0.5秒
ROL BL, 1 ; 循环左移(操作BL寄存器)
; 检测按键是否仍为K5按下(使用AH避免覆盖)
MOV DX, PORTC
IN AL, DX
AND AL, 07H
TEST AL, 01H
JNZ MODE1_LOOP ; 保持按下则继续循环
JMP MAIN_LOOP ; 否则退出
; 模式2:右→左跑马灯(同理修复)
MODE2:
MOV BL, 80H ; BL保存LED状态(LED7亮)
MODE2_LOOP:
MOV DX, PORTA
MOV AL, BL
OUT DX, AL
CALL DELAY
ROR BL, 1 ; 循环右移(操作BL寄存器)
; 检测按键
MOV DX, PORTC
IN AL, DX
AND AL, 07H
TEST AL, 01H
JNZ MODE1
TEST AL, 02H
JNZ MODE2_LOOP
JMP MAIN_LOOP
; 模式3:奇偶交替闪烁(修复LED状态覆盖)
MODE3:
MOV BH, 55H ; 奇位亮(BH保存状态)
MOV BL, 0AAH ; 偶位亮(BL保存状态)
MODE3_LOOP:
; 输出奇位
MOV DX, PORTA
MOV AL, BH
OUT DX, AL
CALL DELAY
; 输出偶位
MOV AL, BL
OUT DX, AL
CALL DELAY
; 检测是否仍为K7按下
MOV DX, PORTC
IN AL, DX
AND AL, 07H
CMP AL, 04H
JE MODE3_LOOP
JMP MAIN_LOOP
;---------------- 子程序 ------------------
; 去抖动延时(约10ms)
DEBOUNCE_DELAY PROC
PUSH CX
MOV CX, 6000 ; 根据CPU频率调整
DEBOUNCE_LOOP:
NOP
LOOP DEBOUNCE_LOOP
POP CX
RET
DEBOUNCE_DELAY ENDP
; 主延时(约0.5秒)
DELAY PROC
PUSH CX
PUSH DX
MOV CX, 4000 ; 外层循环
DELAY_OUTER:
MOV DX, 3000 ; 内层循环
DELAY_INNER:
NOP
DEC DX
JNZ DELAY_INNER
LOOP DELAY_OUTER
POP DX
POP CX
RET
DELAY ENDP
CODE ENDS
END START
实验三
DATA SEGMENT
IO8255_A EQU 288H
IO8255_B EQU 289H
IO8255_C EQU 28AH
IO8255_K EQU 28BH
TAB DB 01H,02,04H,08H,10H,20H,40H,80H
DATA ENDS
CODE SEGMENT
ASSUME CS:CODE,DS:DATA
START: MOV AX,DATA ;设数据寄存器的值
MOV DS,AX
MOV DX,IO8255_K ;设8255方式1,A口输出B口输入
MOV AL,0AEH
OUT DX,AL
MOV AL,04H ;设置(PC2)/STBB=0
OUT DX,AL
LL: MOV DX,IO8255_C ;读8255C口
SS1: IN AL,DX
TEST AL,00000010B ;PC1=1?
JZ SS1 ;N0
MOV DX,IO8255_B ;读8255B口
IN AL,DX
AND AL,07 ;屏蔽高5位
MOV BX,OFFSET TAB
XLAT TAB ;查表
MOV DX,IO8255_A ;表项输出A口
OUT DX,AL
JMP LL ;无条件转移LL处
CODE ENDS
END START
实验四
DATA SEGMENT
IO8254_0 EQU 280H
IO8254_K EQU 283H
DATA ENDS
CODE SEGMENT
ASSUME CS:CODE,DS:DATA
START: MOV AX,DATA
MOV DS,AX
MOV AL,14H ;设置8253通道0为工作方式2,二进制计数
MOV DX,IO8254_K
OUT DX,AL
MOV DX,IO8254_0 ;送计数初值为0FH
MOV AL,0FH
OUT DX,AL
LLL: IN AL,DX ;读计数初值
CALL DISP ;调显示子程序
PUSH DX
MOV AH,06H
MOV DL,0FFH
INT 21H
POP DX
JZ LLL
MOV AX,4C00H ;退出
INT 21H
DISP PROC NEAR ;显示子程序
PUSH DX
AND AL,0FH ;首先取低四位
MOV DL,AL
CMP DL,9 ;判断是否<=9
JLE NUM ;若是则为'0'-'9',ASCII码加30H
ADD DL,7 ;否则为'A'-'F',ASCII码加37H
NUM: ADD DL,30H
MOV AH,02H ;显示
INT 21H
MOV DL,0DH ;加回车符
INT 21H
MOV DL,0AH ;加换行符
INT 21H
POP DX
RET ;子程序返回
DISP ENDP
CODE ENDS
END START