first commit
BIN
Lab/Lab_final/material/Picture1.png
Executable file
|
After Width: | Height: | Size: 125 KiB |
BIN
Lab/Lab_final/material/Picture2.jpg
Executable file
|
After Width: | Height: | Size: 7.8 MiB |
339
Lab/Lab_final/material/code.asm
Executable file
@@ -0,0 +1,339 @@
|
||||
DATA SEGMENT
|
||||
A8255A EQU 280H
|
||||
A8255B EQU 281H
|
||||
A8255C EQU 282H
|
||||
A8255COM EQU 283H
|
||||
|
||||
A8254A EQU 288H
|
||||
A8254B EQU 289H
|
||||
A8254COM EQU 28BH
|
||||
|
||||
OLD_OFF DW 0
|
||||
OLD_SEG DW 0
|
||||
|
||||
TMP1 DB 0
|
||||
TMP2 DB 0
|
||||
LED DB 3FH, 06H, 5BH, 4FH, 66H, 6DH, 7DH, 07H, 7FH, 6FH, 77H, 7CH, 39H, 5EH, 79H, 71H
|
||||
WAITING DB 40H ; 等待状态的字节码
|
||||
FAULT DB 71H ; 违规状态的字节码
|
||||
SUCCESS DB 6DH ; 抢答成功状态的字节码
|
||||
ZERO DB 3FH ; 数码管显示0的字节码
|
||||
DATA ENDS
|
||||
|
||||
CODE SEGMENT
|
||||
ASSUME DS:DATA, CS:CODE
|
||||
|
||||
; 1. 程序逻辑
|
||||
; 1.1. 当K7为0时,K0-6都必须为0,否则为1的违规,数码管显示违规选手 && 扬声器鸣叫
|
||||
; 1.2. 当K7为1时,当K0-6中有一个为1时,停止检测,为1的按键对应的选手抢答成功,数码管显示抢答成功选手
|
||||
; 2. 程序设计
|
||||
; 2.1. 2个PROC
|
||||
; 2.1.1. PROC1扫描到 K7为0 && K0-6中存在1的按键时进入,K0-6全为0时退出
|
||||
; 进入PROC1后蜂鸣器响起,不断扫描K0-7,数码管显示违规选手。
|
||||
; 当全为0时蜂鸣器关闭,退出PROC1
|
||||
; 2.1.2. PROC2扫描到K7为1时进入,K7为0时退出
|
||||
; 进入PROC2后循环扫描K0-7,K0-6存在1后数码管显示抢答成功选手
|
||||
; 继续循环扫描,但只看K7,K7为0时退出
|
||||
; 进入PROC2后进行计时,4秒后若无变化,触发中断,退出PROC
|
||||
; 2.2. 主程序 循环扫描K0-7
|
||||
; 2.2.1. K7为0 && K0-6按键全0时不变,继续循环
|
||||
; 2.2.2. K7为0 && K0-6中存在1的按键时进入PROC1
|
||||
; 2.2.2. K7为1时进入PROC2
|
||||
|
||||
START:
|
||||
MOV AX, DATA
|
||||
MOV DS, AX
|
||||
|
||||
CLI ; 关中断,防止中断干扰
|
||||
; 保存旧的中断向量
|
||||
MOV AX, 350BH
|
||||
INT 21H
|
||||
MOV OLD_OFF, BX
|
||||
MOV BX, ES
|
||||
MOV OLD_SEG, BX
|
||||
|
||||
; 设置新的中断向量
|
||||
MOV AX, 250BH
|
||||
MOV DX, SEG TIMEOUT
|
||||
MOV DS, DX
|
||||
MOV DX, OFFSET TIMEOUT
|
||||
INT 21H
|
||||
STI
|
||||
|
||||
; 恢复数据段
|
||||
MOV AX, DATA
|
||||
MOV DS, AX
|
||||
|
||||
; 初始化8255
|
||||
MOV AX, 10001001B ; A口输出段码,B口输出位码,C口输入拨动开关
|
||||
MOV DX, A8255COM
|
||||
OUT DX, AL
|
||||
|
||||
; 使用8254 A口将1MHz降频为1kHz,为8254 B口提供时钟源
|
||||
MOV DX, A8254COM
|
||||
MOV AL, 00110110B
|
||||
OUT DX, AL
|
||||
MOV DX, A8254A
|
||||
MOV AL, 11101000B
|
||||
OUT DX, AL
|
||||
MOV AL, 00000011B
|
||||
OUT DX, AL
|
||||
|
||||
; 主程序
|
||||
MAIN:
|
||||
MOV DX, A8255C
|
||||
IN AL, DX
|
||||
|
||||
MOV SI, 0 ; 中断标志位
|
||||
|
||||
; K7为0 && K0-6按键全0时不变,继续循环
|
||||
CMP AL, 0 ; 比较AL寄存器的值与0
|
||||
JE MAIN ; 如果相等,则跳转到MAIN
|
||||
|
||||
; K7为0 && K0-6中存在1的按键时进入PROC1
|
||||
AND AL, 10000000B ; 将AL寄存器的值与10000000B进行按位与操作
|
||||
CMP AL, 0 ; 比较AL寄存器的值与0,即判断第7位是否为0
|
||||
JNE P2 ; 如果不相等,则跳转到P2
|
||||
CALL PROC1 ; 调用PROC1子程序
|
||||
|
||||
; K7为1时进入PROC2
|
||||
P2:
|
||||
CALL PROC2 ; 调用PROC2子程序
|
||||
JMP MAIN ; 无条件跳转到MAIN
|
||||
|
||||
FINISH:
|
||||
CLI ; 关中断,防止中断干扰
|
||||
MOV AX, 250BH ; 恢复原来的中断向量
|
||||
MOV DX, OLD_OFF
|
||||
MOV DS, DX
|
||||
MOV DS, OLD_SEG
|
||||
INT 21H
|
||||
|
||||
MOV AX, 4C00H
|
||||
INT 21H
|
||||
|
||||
PROC1 PROC NEAR
|
||||
|
||||
; K7为0 && K0-6中存在1的按键时进入,K0-6全为0时退出
|
||||
; 进入PROC1后蜂鸣器响起,不断扫描K0-7,数码管显示违规选手。
|
||||
; 当全为0时,蜂鸣器关闭,退出PROC1
|
||||
|
||||
PUSH DX
|
||||
PUSH CX
|
||||
|
||||
LOOP1:
|
||||
MOV DX, A8255C
|
||||
IN AL, DX
|
||||
MOV TMP1, AL
|
||||
|
||||
CMP AL, 0
|
||||
JE RETURN1
|
||||
|
||||
MOV CX, 8
|
||||
MOV TMP2, 10000000B ; 位码
|
||||
LOOP2:
|
||||
ROR TMP2, 1
|
||||
JMP OUTPUT1
|
||||
BACK1:
|
||||
LOOP LOOP2
|
||||
JMP LOOP1
|
||||
|
||||
; 在数码管上输出
|
||||
OUTPUT1:
|
||||
CALL CLEAR
|
||||
MOV AL, TMP1
|
||||
AND AL, TMP2
|
||||
CMP AL, TMP2
|
||||
JE FAULT1
|
||||
MOV AL, WAITING
|
||||
JMP DISPLAY1
|
||||
FAULT1:
|
||||
MOV AL, FAULT
|
||||
DISPLAY1:
|
||||
MOV DX, A8255A
|
||||
OUT DX, AL
|
||||
MOV DX, A8255B
|
||||
MOV AL, TMP2
|
||||
OUT DX, AL
|
||||
CALL DELAY
|
||||
JMP BACK1
|
||||
|
||||
RETURN1:
|
||||
CALL CLEAR
|
||||
POP CX
|
||||
POP DX
|
||||
RET
|
||||
PROC1 ENDP
|
||||
|
||||
PROC2 PROC NEAR
|
||||
|
||||
; 进入PROC2后循环扫描K0-7,K0-6存在1后数码管显示抢答成功选手
|
||||
; 继续循环扫描,但只看K7,K7为0时退出PROC2
|
||||
|
||||
PUSH DX
|
||||
PUSH CX
|
||||
|
||||
MOV SI, 0 ; 时间到退出抢答标志
|
||||
|
||||
; 开始计时,1000Hz * 4000 = 4s后输出低电平,取反后用于触发中断
|
||||
MOV DX, A8254COM
|
||||
MOV AL, 10111000B
|
||||
OUT DX, AL
|
||||
MOV DX, A8254B
|
||||
MOV AL, 10100000B
|
||||
OUT DX, AL
|
||||
MOV AL, 00001111B
|
||||
OUT DX, AL
|
||||
|
||||
; 设置中断屏蔽
|
||||
CLI
|
||||
IN AL, 21H
|
||||
AND AL, 11110111B
|
||||
OUT 21H, AL
|
||||
STI
|
||||
|
||||
LOOP3:
|
||||
CMP SI, 1
|
||||
JE RETURN2
|
||||
|
||||
MOV DX, A8255C
|
||||
IN AL, DX
|
||||
MOV TMP1, AL
|
||||
AND AL, 10000000B ; 位码
|
||||
CMP AL, 0
|
||||
JE RETURN2
|
||||
|
||||
MOV AL, TMP1
|
||||
AND AL, 01111111B
|
||||
MOV TMP1, AL
|
||||
CMP AL, 0
|
||||
JE LOOP3
|
||||
|
||||
; 检测到有变化,恢复中断屏蔽,取消中断
|
||||
CLI
|
||||
IN AL, 21H
|
||||
OR AL, 00001000B
|
||||
OUT 21H, AL
|
||||
STI
|
||||
|
||||
LOOP4:
|
||||
MOV DX, A8255C
|
||||
IN AL, DX
|
||||
AND AL, 10000000B
|
||||
CMP AL, 0
|
||||
JE RETURN2
|
||||
|
||||
MOV CX, 7
|
||||
MOV TMP2, 10000000B ; 位码
|
||||
LOOP5:
|
||||
ROR TMP2, 1
|
||||
JMP OUTPUT2
|
||||
BACK2:
|
||||
LOOP LOOP5
|
||||
JMP LOOP4
|
||||
|
||||
OUTPUT2:
|
||||
CALL CLEAR
|
||||
MOV AL, TMP1
|
||||
AND AL, TMP2
|
||||
CMP AL, TMP2
|
||||
JE SUCCESS2
|
||||
MOV AL, WAITING
|
||||
JMP DISPLAY2
|
||||
SUCCESS2:
|
||||
MOV AL, SUCCESS
|
||||
DISPLAY2:
|
||||
MOV DX, A8255A
|
||||
OUT DX, AL
|
||||
MOV DX, A8255B
|
||||
MOV AL, TMP2
|
||||
OUT DX, AL
|
||||
CALL DELAY
|
||||
JMP BACK2
|
||||
|
||||
RETURN2:
|
||||
CALL CLEAR
|
||||
; 恢复中断屏蔽
|
||||
CLI
|
||||
IN AL, 21H
|
||||
OR AL, 00001000B
|
||||
OUT 21H, AL
|
||||
STI
|
||||
POP CX
|
||||
POP DX
|
||||
RET
|
||||
PROC2 ENDP
|
||||
|
||||
TIMEOUT PROC FAR
|
||||
CLI
|
||||
PUSH CX
|
||||
PUSH BX
|
||||
MOV SI, 1
|
||||
|
||||
CALL CLEAR
|
||||
MOV BX, 0FH
|
||||
LOOP6:
|
||||
MOV CX, 8
|
||||
MOV TMP1, 00000001B ; 位码
|
||||
LOOP7:
|
||||
ROR TMP1, 1
|
||||
JMP OUTPUT3
|
||||
BACK3:
|
||||
LOOP LOOP7
|
||||
DEC BX
|
||||
JZ RETURN3
|
||||
JMP LOOP6
|
||||
|
||||
OUTPUT3:
|
||||
MOV AL, ZERO
|
||||
MOV DX, A8255A
|
||||
OUT DX, AL
|
||||
MOV DX, A8255B
|
||||
MOV AL, TMP1
|
||||
OUT DX, AL
|
||||
CALL DELAY
|
||||
JMP BACK3
|
||||
|
||||
RETURN3:
|
||||
MOV AL, 20H ; 发送EOI指令
|
||||
OUT 20H, AL
|
||||
POP BX
|
||||
POP CX
|
||||
STI
|
||||
IRET
|
||||
TIMEOUT ENDP
|
||||
|
||||
CLEAR PROC NEAR
|
||||
PUSH DX
|
||||
PUSH AX
|
||||
|
||||
MOV DX, A8255A
|
||||
MOV AL, 00000000B
|
||||
OUT DX, AL
|
||||
MOV DX, A8255B
|
||||
MOV AL, 0
|
||||
OUT DX, AL
|
||||
|
||||
POP AX
|
||||
POP DX
|
||||
RET
|
||||
CLEAR ENDP
|
||||
|
||||
DELAY PROC NEAR
|
||||
PUSH CX
|
||||
PUSH BX
|
||||
MOV CX, 0FFFFH
|
||||
LOOP8:
|
||||
MOV BX, 2
|
||||
LOOP9:
|
||||
DEC BX
|
||||
JNZ LOOP9
|
||||
DEC CX
|
||||
JNZ LOOP8
|
||||
POP BX
|
||||
POP CX
|
||||
RET
|
||||
DELAY ENDP
|
||||
|
||||
END START
|
||||
CODE ENDS
|
||||
BIN
Lab/Lab_final/material/connections.png
Executable file
|
After Width: | Height: | Size: 15 KiB |
BIN
Lab/Lab_final/material/cover.png
Executable file
|
After Width: | Height: | Size: 46 KiB |
BIN
Lab/Lab_final/material/fault.png
Executable file
|
After Width: | Height: | Size: 1.3 MiB |
BIN
Lab/Lab_final/material/success.png
Executable file
|
After Width: | Height: | Size: 1.1 MiB |
BIN
Lab/Lab_final/material/timeout.png
Executable file
|
After Width: | Height: | Size: 1.3 MiB |
BIN
Lab/Lab_final/material/接线.xlsx
Executable file
516
Lab/Lab_final/material/研究性实验_竞赛抢答器设计.md
Executable file
@@ -0,0 +1,516 @@
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||

|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<h1><center><strong>研究性实验 竞赛抢答器设计</strong></center></h1>
|
||||
|
||||
### 一、实验目的
|
||||
|
||||
利用可编程并行接口接口芯片$8255$、可编程定时器/计数器$8254$,扬声器,$\rm LED$八段数码管,$8$个拨动开关,设计一个七路抢答器,以模拟竞赛中的抢答器功能。
|
||||
|
||||
|
||||
|
||||
### 二、实验内容
|
||||
|
||||
设计一个七路抢答器,以模拟竞赛中的抢答器功能。当主持人按开始键后,选手才可抢答,否则违规。该抢答器具有如下功能:
|
||||
|
||||
1. 该抢答器有一个开始键,由拨动开关控制,由主持人使用;
|
||||
2. 该抢答器可供$7$人同时抢答,由拨动开关控制,选手使用;
|
||||
3. 当选手违规时,扬声器报警,数码管显示最先违规的选手;
|
||||
4. 当选手抢答成功,数码管显示最先抢答到的选手号码;
|
||||
5. 抢答前,所有的波动开关必须拨到下方,新一轮的抢答才可以开始。
|
||||
|
||||
> 在本实验中,我们没有参照原实验指导书使用发光二极管进行抢答成功/违规选手的号码的显示,而是直接在数码管上直接对抢答成功/违规选手的物理位置进行显示,如第四部分中实验效果图所示。
|
||||
>
|
||||
> 我们认为这样更能贴合竞赛抢答的实际情景,也比在数码管上直接显示单个数字更具有挑战性。
|
||||
|
||||
|
||||
|
||||
### 三、流程图
|
||||
|
||||
<img src="Picture1.png" alt="graph" style="zoom: 50%;" />
|
||||
|
||||
|
||||
|
||||
### 四、实验过程与分析
|
||||
|
||||
#### 4.1. 接线
|
||||
|
||||

|
||||
|
||||
<center>表4-1 硬件连接表</center>
|
||||
|
||||
<img src="Picture2.jpg" alt="4-1" style="zoom: 10%;" />
|
||||
|
||||
<center>图4-1 硬件连接图</center>
|
||||
|
||||
#### 4.2. 程序设计
|
||||
|
||||
##### 4.2.1. 需求分析和程序逻辑
|
||||
|
||||
1. 判断主持人和选手的行为可以使用$8255$芯片读取逻辑电平开关状态实现
|
||||
1. 当主持人对应的$\rm K7$为$0$时还没开始抢答,这时选手对应的$\rm K0\sim 6$中的$1$说明对应选手违规,存在违规选手时不能进入抢答程序
|
||||
2. 当主持人对应的$\rm K7$为$1$时开始抢答,这时选手对应的$\rm K0\sim 6$中有$1$说明选手抢答成功,此时应停止其他选手的抢答
|
||||
2. 显示违规和抢答成功信息使用数码管显示,需要利用人眼延时特性循环刷新数码管显示
|
||||
3. 违规选手的告警用蜂鸣器和$8255$芯片控制。
|
||||
1. 利用违规时数码管的位码第$7$位为$0$、抢答时数码管的位码第$7$位为$1$的程序特性,将控制位码的$8255B$口的第$7$位用单根线连接至扬声器,这样违规时扬声器鸣叫,正常抢答时扬声器不鸣叫。
|
||||
|
||||
##### 4.2.2. 新器件的控制方法
|
||||
|
||||
新器件是扬声器,控制口为高电平时鸣叫,为低电平时不鸣叫。
|
||||
|
||||
##### 4.2.3. 代码实现
|
||||
|
||||
**主程序**
|
||||
|
||||
首先初始化所有要用到的芯片。
|
||||
|
||||
然后进行无限循环,不断从$\rm 8255C$口获取逻辑电平开关状态,判断:
|
||||
|
||||
1. 当$\rm K0\sim 7$全为$0$时不作任何变化,继续循环;
|
||||
1. 当$\rm K7$为$0$且$\rm K0\sim 6$中存在$1$时,进入$\rm PROC1$;
|
||||
1. 当$\rm K7$为$1$时,进入$\rm PROC2$。
|
||||
|
||||
**PROC1程序**(抢答开始前有选手违规)
|
||||
|
||||
主程序扫描到 $\rm K7$为$0$且$\rm K0\sim 6$中存在$1$时进入,扬声器鸣叫。
|
||||
|
||||
进入无限循环,不断从$\rm 8255C$口读入$\rm K0\sim 7$,数码管显示违规选手。
|
||||
|
||||
$\rm K0\sim 6$全为$0$时,跳出循环,扬声器关闭,退出$\rm PROC1$。
|
||||
|
||||
<img src="fault.png" alt="fault" style="zoom: 50%;" />
|
||||
|
||||
<center>图4-2 判定违规选手效果图</center>
|
||||
|
||||
**PROC2程序**(选手成功抢答)
|
||||
|
||||
主程序扫描到 $\rm K7$为$1$时进入,开启$\rm 8254$芯片开始计时,取消屏蔽$\rm MIRQ3$的中断。
|
||||
|
||||
进入第一个无限循环,不断从$\rm 8255C$口读入$\rm K0\sim 7$。
|
||||
|
||||
$\rm K0\sim 6$存在$1$后,退出循环,开启屏蔽$\rm MIRQ3$的中断。
|
||||
|
||||
进入第二个无限循环,数码管显示抢答成功选手,当 $\rm K7$为$0$时退出无限循环,退出$\rm PROC2$。
|
||||
|
||||
若在第一个无限循环中,$4$秒内$\rm K0\sim 6$都为$0$没有变化,$8254$芯片会用$4$方式输出低电平,经非门取反后触发$\rm MIRQ3$中断。
|
||||
|
||||
<img src="success.png" alt="success" style="zoom:60%;" />
|
||||
|
||||
<center>图4-3 判定抢答成功选手效果图</center>
|
||||
|
||||
**TIMEOUT中断服务程序**(抢答超时)
|
||||
|
||||
$\rm PROC2$进入$4$秒后由$8254$芯片用$4$方式输出低电平,经非门取反后触发$\rm MIRQ3$进入。
|
||||
|
||||
数码管显示全$0$,延时约$1$秒后退出$\rm TIMEOUT$中断服务程序。
|
||||
|
||||
<img src="timeout.png" alt="timeout" style="zoom:60%;" />
|
||||
|
||||
<center>图4-4 判定抢答超时效果图</center>
|
||||
|
||||
|
||||
|
||||
### 五、实验总结
|
||||
|
||||
在实验过程中我们发现了抢答器出现的问题:
|
||||
|
||||
1. 数字开头命名变量导致代码编译错误;
|
||||
2. 接错线,且没有与蜂鸣器联动;
|
||||
3. 我们只有$\rm PROC2$中可以触发中断但是在进行$\rm PROC1$时也会触发中断
|
||||
|
||||
经讨论得到的解决方案或结论:
|
||||
|
||||
1. 在变量前增加字母,使得程序顺利运行。
|
||||
2. 重新搭线,由于$\rm K7$的位码在有选手违规时以及抢答时都会亮起,利用这点将$\rm PB7$口作为蜂鸣器的输入,使得条件$1$时蜂鸣器报警。
|
||||
3. 硬件问题,实验箱短路造成中断的误触发,无法避免。
|
||||
|
||||
|
||||
|
||||
### 六、小组分工 & 心得体会
|
||||
|
||||
**皇甫昱慧** *(组长)*
|
||||
|
||||
组织组员协同完成实验;编写$8255$芯片的逻辑电平开关输入和对发光二极管输出控制代码;绘制程序逻辑流程图。
|
||||
|
||||
> 在本次实验中,我学会了使用$8255$来实现抢答器的功能,同时我们设计了使用$8254$进行计时并使用$8259$进行中断。在实验过程中,一开始我写了非常冗长且不方便的代码,非常感谢我的组员给予的帮助,同时我通过画流程图对后面精简过的代码也有了更好的认识。
|
||||
|
||||
**庄子君** *(组员)*
|
||||
|
||||
为实验箱接线;参与实验程序的调试;记录实验流程和现象以及在实验中遇到的问题;实验报告和实验总结的撰写。
|
||||
|
||||
> 加深了对可编程接口芯片$8254$、$8255$的理解,顺利实现$8254$、$8255$的配合使用,遇到问题组内也及时沟通并积极讨论,最后顺利解决了试验过程中出现的问题。
|
||||
|
||||
**柯劲帆** *(组员)*
|
||||
|
||||
编写$8255$芯片控制数码管显示、$8254$芯片和$8259$芯片控制代码,整合程序代码;接线并调试代码;修改实验报告。
|
||||
|
||||
> 通过本次实验我学会使用$8255$芯片、$8254$芯片、$8259$芯片、数码管以及蜂鸣器进行联动,我对接口的理解更为深刻,同时汇编代码编写能力、逻辑实现能力、工程架构设计能力和$\rm DEBUG$能力都得到了非常大的提升。非常感谢老师的指导。
|
||||
|
||||
|
||||
|
||||
### 源代码附录
|
||||
|
||||
```assembly
|
||||
DATA SEGMENT
|
||||
A8255A EQU 280H
|
||||
A8255B EQU 281H
|
||||
A8255C EQU 282H
|
||||
A8255COM EQU 283H
|
||||
|
||||
A8254A EQU 288H
|
||||
A8254B EQU 289H
|
||||
A8254COM EQU 28BH
|
||||
|
||||
OLD_OFF DW 0
|
||||
OLD_SEG DW 0
|
||||
|
||||
TMP1 DB 0
|
||||
TMP2 DB 0
|
||||
LED DB 3FH, 06H, 5BH, 4FH, 66H, 6DH, 7DH, 07H, 7FH, 6FH, 77H, 7CH, 39H, 5EH, 79H, 71H
|
||||
WAITING DB 40H ; 等待状态的字节码
|
||||
FAULT DB 71H ; 违规状态的字节码
|
||||
SUCCESS DB 6DH ; 抢答成功状态的字节码
|
||||
ZERO DB 3FH ; 数码管显示0的字节码
|
||||
DATA ENDS
|
||||
|
||||
CODE SEGMENT
|
||||
ASSUME DS:DATA, CS:CODE
|
||||
|
||||
; 1. 程序逻辑
|
||||
; 1.1. 当K7为0时,K0-6都必须为0,否则为1的违规,数码管显示违规选手 && 扬声器鸣叫
|
||||
; 1.2. 当K7为1时,当K0-6中有一个为1时,停止检测,为1的按键对应的选手抢答成功,数码管显示抢答成功选手
|
||||
; 2. 程序设计
|
||||
; 2.1. 2个PROC
|
||||
; 2.1.1. PROC1扫描到 K7为0 && K0-6中存在1的按键时进入,K0-6全为0时退出
|
||||
; 进入PROC1后蜂鸣器响起,不断扫描K0-7,数码管显示违规选手。
|
||||
; 当全为0时蜂鸣器关闭,退出PROC1
|
||||
; 2.1.2. PROC2扫描到K7为1时进入,K7为0时退出
|
||||
; 进入PROC2后循环扫描K0-7,K0-6存在1后数码管显示抢答成功选手
|
||||
; 继续循环扫描,但只看K7,K7为0时退出
|
||||
; 进入PROC2后进行计时,4秒后若无变化,触发中断,退出PROC
|
||||
; 2.2. 主程序 循环扫描K0-7
|
||||
; 2.2.1. K7为0 && K0-6按键全0时不变,继续循环
|
||||
; 2.2.2. K7为0 && K0-6中存在1的按键时进入PROC1
|
||||
; 2.2.2. K7为1时进入PROC2
|
||||
|
||||
START:
|
||||
MOV AX, DATA
|
||||
MOV DS, AX
|
||||
|
||||
CLI ; 关中断,防止中断干扰
|
||||
; 保存旧的中断向量
|
||||
MOV AX, 350BH
|
||||
INT 21H
|
||||
MOV OLD_OFF, BX
|
||||
MOV BX, ES
|
||||
MOV OLD_SEG, BX
|
||||
|
||||
; 设置新的中断向量
|
||||
MOV AX, 250BH
|
||||
MOV DX, SEG TIMEOUT
|
||||
MOV DS, DX
|
||||
MOV DX, OFFSET TIMEOUT
|
||||
INT 21H
|
||||
STI
|
||||
|
||||
; 恢复数据段
|
||||
MOV AX, DATA
|
||||
MOV DS, AX
|
||||
|
||||
; 初始化8255
|
||||
MOV AX, 10001001B ; A口输出段码,B口输出位码,C口输入拨动开关
|
||||
MOV DX, A8255COM
|
||||
OUT DX, AL
|
||||
|
||||
; 使用8254 A口将1MHz降频为1kHz,为8254 B口提供时钟源
|
||||
MOV DX, A8254COM
|
||||
MOV AL, 00110110B
|
||||
OUT DX, AL
|
||||
MOV DX, A8254A
|
||||
MOV AL, 11101000B
|
||||
OUT DX, AL
|
||||
MOV AL, 00000011B
|
||||
OUT DX, AL
|
||||
|
||||
; 主程序
|
||||
MAIN:
|
||||
MOV DX, A8255C
|
||||
IN AL, DX
|
||||
|
||||
MOV SI, 0 ; 中断标志位
|
||||
|
||||
; K7为0 && K0-6按键全0时不变,继续循环
|
||||
CMP AL, 0 ; 比较AL寄存器的值与0
|
||||
JE MAIN ; 如果相等,则跳转到MAIN
|
||||
|
||||
; K7为0 && K0-6中存在1的按键时进入PROC1
|
||||
AND AL, 10000000B ; 将AL寄存器的值与10000000B进行按位与操作
|
||||
CMP AL, 0 ; 比较AL寄存器的值与0,即判断第7位是否为0
|
||||
JNE P2 ; 如果不相等,则跳转到P2
|
||||
CALL PROC1 ; 调用PROC1子程序
|
||||
|
||||
; K7为1时进入PROC2
|
||||
P2:
|
||||
CALL PROC2 ; 调用PROC2子程序
|
||||
JMP MAIN ; 无条件跳转到MAIN
|
||||
|
||||
FINISH:
|
||||
CLI ; 关中断,防止中断干扰
|
||||
MOV AX, 250BH ; 恢复原来的中断向量
|
||||
MOV DX, OLD_OFF
|
||||
MOV DS, DX
|
||||
MOV DS, OLD_SEG
|
||||
INT 21H
|
||||
|
||||
MOV AX, 4C00H
|
||||
INT 21H
|
||||
|
||||
PROC1 PROC NEAR
|
||||
|
||||
; K7为0 && K0-6中存在1的按键时进入,K0-6全为0时退出
|
||||
; 进入PROC1后蜂鸣器响起,不断扫描K0-7,数码管显示违规选手。
|
||||
; 当全为0时,蜂鸣器关闭,退出PROC1
|
||||
|
||||
PUSH DX
|
||||
PUSH CX
|
||||
|
||||
LOOP1:
|
||||
MOV DX, A8255C
|
||||
IN AL, DX
|
||||
MOV TMP1, AL
|
||||
|
||||
CMP AL, 0
|
||||
JE RETURN1
|
||||
|
||||
MOV CX, 8
|
||||
MOV TMP2, 10000000B ; 位码
|
||||
LOOP2:
|
||||
ROR TMP2, 1
|
||||
JMP OUTPUT1
|
||||
BACK1:
|
||||
LOOP LOOP2
|
||||
JMP LOOP1
|
||||
|
||||
; 在数码管上输出
|
||||
OUTPUT1:
|
||||
CALL CLEAR
|
||||
MOV AL, TMP1
|
||||
AND AL, TMP2
|
||||
CMP AL, TMP2
|
||||
JE FAULT1
|
||||
MOV AL, WAITING
|
||||
JMP DISPLAY1
|
||||
FAULT1:
|
||||
MOV AL, FAULT
|
||||
DISPLAY1:
|
||||
MOV DX, A8255A
|
||||
OUT DX, AL
|
||||
MOV DX, A8255B
|
||||
MOV AL, TMP2
|
||||
OUT DX, AL
|
||||
CALL DELAY
|
||||
JMP BACK1
|
||||
|
||||
RETURN1:
|
||||
CALL CLEAR
|
||||
POP CX
|
||||
POP DX
|
||||
RET
|
||||
PROC1 ENDP
|
||||
|
||||
PROC2 PROC NEAR
|
||||
|
||||
; 进入PROC2后循环扫描K0-7,K0-6存在1后数码管显示抢答成功选手
|
||||
; 继续循环扫描,但只看K7,K7为0时退出PROC2
|
||||
|
||||
PUSH DX
|
||||
PUSH CX
|
||||
|
||||
MOV SI, 0 ; 时间到退出抢答标志
|
||||
|
||||
; 开始计时,1000Hz * 4000 = 4s后输出低电平,取反后用于触发中断
|
||||
MOV DX, A8254COM
|
||||
MOV AL, 10111000B
|
||||
OUT DX, AL
|
||||
MOV DX, A8254B
|
||||
MOV AL, 10100000B
|
||||
OUT DX, AL
|
||||
MOV AL, 00001111B
|
||||
OUT DX, AL
|
||||
|
||||
; 设置中断屏蔽
|
||||
CLI
|
||||
IN AL, 21H
|
||||
AND AL, 11110111B
|
||||
OUT 21H, AL
|
||||
STI
|
||||
|
||||
LOOP3:
|
||||
CMP SI, 1
|
||||
JE RETURN2
|
||||
|
||||
MOV DX, A8255C
|
||||
IN AL, DX
|
||||
MOV TMP1, AL
|
||||
AND AL, 10000000B ; 位码
|
||||
CMP AL, 0
|
||||
JE RETURN2
|
||||
|
||||
MOV AL, TMP1
|
||||
AND AL, 01111111B
|
||||
MOV TMP1, AL
|
||||
CMP AL, 0
|
||||
JE LOOP3
|
||||
|
||||
; 检测到有变化,恢复中断屏蔽,取消中断
|
||||
CLI
|
||||
IN AL, 21H
|
||||
OR AL, 00001000B
|
||||
OUT 21H, AL
|
||||
STI
|
||||
|
||||
LOOP4:
|
||||
MOV DX, A8255C
|
||||
IN AL, DX
|
||||
AND AL, 10000000B
|
||||
CMP AL, 0
|
||||
JE RETURN2
|
||||
|
||||
MOV CX, 7
|
||||
MOV TMP2, 10000000B ; 位码
|
||||
LOOP5:
|
||||
ROR TMP2, 1
|
||||
JMP OUTPUT2
|
||||
BACK2:
|
||||
LOOP LOOP5
|
||||
JMP LOOP4
|
||||
|
||||
OUTPUT2:
|
||||
CALL CLEAR
|
||||
MOV AL, TMP1
|
||||
AND AL, TMP2
|
||||
CMP AL, TMP2
|
||||
JE SUCCESS2
|
||||
MOV AL, WAITING
|
||||
JMP DISPLAY2
|
||||
SUCCESS2:
|
||||
MOV AL, SUCCESS
|
||||
DISPLAY2:
|
||||
MOV DX, A8255A
|
||||
OUT DX, AL
|
||||
MOV DX, A8255B
|
||||
MOV AL, TMP2
|
||||
OUT DX, AL
|
||||
CALL DELAY
|
||||
JMP BACK2
|
||||
|
||||
RETURN2:
|
||||
CALL CLEAR
|
||||
; 恢复中断屏蔽
|
||||
CLI
|
||||
IN AL, 21H
|
||||
OR AL, 00001000B
|
||||
OUT 21H, AL
|
||||
STI
|
||||
POP CX
|
||||
POP DX
|
||||
RET
|
||||
PROC2 ENDP
|
||||
|
||||
TIMEOUT PROC FAR
|
||||
CLI
|
||||
PUSH CX
|
||||
PUSH BX
|
||||
MOV SI, 1
|
||||
|
||||
CALL CLEAR
|
||||
MOV BX, 0FH
|
||||
LOOP6:
|
||||
MOV CX, 8
|
||||
MOV TMP1, 00000001B ; 位码
|
||||
LOOP7:
|
||||
ROR TMP1, 1
|
||||
JMP OUTPUT3
|
||||
BACK3:
|
||||
LOOP LOOP7
|
||||
DEC BX
|
||||
JZ RETURN3
|
||||
JMP LOOP6
|
||||
|
||||
OUTPUT3:
|
||||
MOV AL, ZERO
|
||||
MOV DX, A8255A
|
||||
OUT DX, AL
|
||||
MOV DX, A8255B
|
||||
MOV AL, TMP1
|
||||
OUT DX, AL
|
||||
CALL DELAY
|
||||
JMP BACK3
|
||||
|
||||
RETURN3:
|
||||
MOV AL, 20H ; 发送EOI指令
|
||||
OUT 20H, AL
|
||||
POP BX
|
||||
POP CX
|
||||
STI
|
||||
IRET
|
||||
TIMEOUT ENDP
|
||||
|
||||
CLEAR PROC NEAR
|
||||
PUSH DX
|
||||
PUSH AX
|
||||
|
||||
MOV DX, A8255A
|
||||
MOV AL, 00000000B
|
||||
OUT DX, AL
|
||||
MOV DX, A8255B
|
||||
MOV AL, 0
|
||||
OUT DX, AL
|
||||
|
||||
POP AX
|
||||
POP DX
|
||||
RET
|
||||
CLEAR ENDP
|
||||
|
||||
DELAY PROC NEAR
|
||||
PUSH CX
|
||||
PUSH BX
|
||||
MOV CX, 0FFFFH
|
||||
LOOP8:
|
||||
MOV BX, 2
|
||||
LOOP9:
|
||||
DEC BX
|
||||
JNZ LOOP9
|
||||
DEC CX
|
||||
JNZ LOOP8
|
||||
POP BX
|
||||
POP CX
|
||||
RET
|
||||
DELAY ENDP
|
||||
|
||||
END START
|
||||
CODE ENDS
|
||||
```
|
||||