📄 final1.asm
字号:
STACK SEGMENT STACK
DW 64 DUP(?)
STACK ENDS
DATA SEGMENT
IP1 EQU 20H ;8259_PORT
IP2 EQU 21H ;8259_PORT
PA EQU 60H ;8255A_A
PB EQU 61H ;8255A_B
PC EQU 62H ;8255A_C
PCONTROL EQU 63H ;8255A_CONTROL
CCONTROL EQU 43H ;8253_CONTROL
COUNTPORT EQU 42H ;计数器2-42 1-41 0-40
TIME DW 59659 ;50MS * 1.19318*10^3 = 59659==0e9h,0bh;
TIME1 DW 100;2100(140);100 ;(5S);1200 ;车行道通行1分钟,中断次数计数器初值,每50ms中断一次,1200次为1分。
TIME2 DW 5 ;黄灯闪烁5次。0.5*2*5=5S
TIME3 DW 2100 ;(5S);500 ;人行道通行。中断次数计数器初值,每50ms中断一次,500次为25秒。
;交通灯 SW-LED
; 7 6 5 4 3 2 1 0
; | | | | | | | |
;车行道黄灯 、绿灯 、红灯 NULL 人行道 红灯 绿灯 红灯 绿灯
LIGHT1 EQU 10111010B ;行车
LIGHT2 EQU 01111010B ;黄灯亮
LIGHT3 EQU 11111010B ;黄灯灭
LIGHT4 EQU 11010101B ;行人
MSG1 DB 'CARS GO',0
MSG2 DB 'WAITING',0
MSG3 DB 'MEN GO',0
FLAG DB 00H
LED DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,67H ;STAND FOR LED CODE 0 - 9
NOWTIME DB 0
DATA ENDS
CODE SEGMENT
ASSUME CS:CODE,DS:DATA,SS:STACK
START:
MOV AX,DATA
MOV DS,AX
mov cx,3 ;initial
CLI
;8255A初始化:端口A工作方式0,输出(P156)
MOV AL,10000000B
OUT PCONTROL,AL
;8253初始化:8253计数器2,先低后高,模式2,二进制计数(P218)
MOV AL,10110100B ;-----------------------------------
OUT CCONTROL,AL
MOV AX,TIME
OUT COUNTPORT,AL ;写计数值低字节;--------------------------------
MOV AL,AH
OUT COUNTPORT,AL ;,AL ;写计数值高字节;---------------------------------
;8259中断初始化
PUSH DS
MOV AX,0
MOV DS,AX ;DS指到0段
MOV AX,OFFSET IRQ7 ;IRQ7为中断服务程序入口标号
ADD AX,2000H
MOV SI,0fH*4 ;-----------------------------------------------
MOV [SI],AX ;中断类型号为0FH,设置中断向量低字
MOV AX,0
MOV [SI+2],AX ;设置中断向量高字
POP DS
IN AL,IP2 ;允许7#中断
AND AL,7FH ;0feh;7FH ;-----------------------------------
OUT IP2,AL
STI
MAIN:
MOV [FLAG],0FFH
;车行道通行
MOV CX,TIME1
MOV AL,LIGHT1
OUT PA,AL
CALL CLRSCR
MOV AH,06H
MOV BX,OFFSET MSG1
INT 10H
STI
S1: CMP CX,0
JNZ S1
MOV [FLAG],00H
;黄灯闪烁
MOV BX,TIME2
PUSH BX
CALL CLRSCR
MOV AH,06H
MOV BX,OFFSET MSG2
INT 10H
POP BX
S2: MOV AL,LIGHT2
OUT PA,AL
MOV CX,10 ;0.5秒。
S3: CMP CX,0
JNZ S3
MOV AL,LIGHT3
OUT PA,AL
MOV CX,10
S4: CMP CX,0
JNZ S4
DEC BX
JNZ S2
MOV [FLAG],0FFH
;人行道通行
S5: MOV CX,TIME3
MOV AL,LIGHT4
OUT PA,AL
CALL CLRSCR
MOV AH,06H
MOV BX,OFFSET MSG3
INT 10H
S6: CMP CX,0
JNZ S6
JMP MAIN
;中断服务子程序
IRQ7: DEC CX
push ax
PUSH BX
PUSH CX
PUSH DX
CALL SHOWTIME
;如果CX%20==0,每一秒显示当前记数
MOV BL,20 ;除数
MOV AX,CX ;被除数
DIV BL ;商AL 余数aH
MOV dX,AX ;保存商 余数->cx
MOV NOWTIME,AL
TEST AH,0FFH ;是否为秒边缘
JNZ GO
TEST [FLAG],0FFH ;黄灯不显示倒数
JZ GO
MOV Ax,0001H ;清屏
INT 10H
MOV AX,dX ;当前秒计数
MOV BL,10 ;被除数
XOR CX,CX ;秒数字位个数 计数器清零
LOOP1:DIV BL ;AX/10->AL(商),AH(余数)
INC CX
PUSH AX ;保存结果 Ah有意义
TEST AL,0FFH
JZ SHOW
MOV AH,0
JMP LOOP1
SHOW:
POP AX
PUSH AX
ADD AH,30H
MOV AL,AH
MOV AH,01H
INT 10H
MOV AL,BL ;选通值
;OUT PC,AL
POP AX
MOV AL,AH
MOV AH,0
MOV DI,AX ;NUMBER (D)
MOV AL,LED[DI] ;CHANGE NUMBER TO LED CODE
;OUT PB,AL
LOOP SHOW
GO:
MOV AL,20H
OUT 20H,AL ;中断结束,置OCW2
POP Dx
POP CX
POP BX
POP AX
IRET ;中断返回
CLRSCR PROC;清屏(TDN显示为换行)
PUSH AX
MOV AX,0001H
INT 10H
POP AX
RET
SHOWTIME PROC
push ax
PUSH BX
PUSH CX
PUSH DX
mov cx,11111101b
mov al,cl
out pc,al
MOV AH,0
MOV AL,NOWTIME ;当前秒计数
MOV BL,10 ;被除数
LOOPT:DIV BL ;AX/10->AL(商),AH(余数)
puah ax
mov al,ah
MOV AH,0
MOV DI,AX ;NUMBER (D)
MOV AL,LED[DI] ;CHANGE NUMBER TO LED CODE
OUT PB,AL
sal cx,1
mov al,cl
out pc,al
pop ax
TEST AL,0FFH
JZ exit
JMP LOOPT
exit:
POP Dx
POP CX
POP BX
POP AX
RET
CODE ENDS
END START
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -