⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 实验.asm

📁 十字路口交通信号灯控制系统的设计基本要求:(利用8088、8254、8255及其它器件实现交通信号灯控制)(1)南北与东西方向
💻 ASM
字号:


data segment
ioport equ 0e800h-280h
io8255a equ ioport+288h
io8255b equ ioport+289h
io8255c equ ioport+28ah
io8255ctrl equ ioport+28bh
io8253a equ ioport+280h
io8253b equ ioport+281h
io8253ctrl equ ioport+283h
message1 db 0dh,0ah,'Please input the time to delay $'
message2 db 0dh,0ah,'South-North direction :$'
message3 db 0dh,0ah,'East-West direction :$'
message4 db 0dh,0ah,'Please turn off the console switch !!'
	  db 0dh,0ah,'After you turn off it,the system will work ... $'

led db 3fh,06h,5bh,4fh,66h,6dh,7dh,07h,7fh,6fh
time1 db 30
time2 db 30
count db ?
light db ?
data ends
				;-------------------------------------------------------
				;              本实验的一些简化假设
				;   紧急控制可以打断正常行车、夜间行车、路灯全灭3种状态,
				;但是在调节时间状态下不能有其他的打断;在紧急控制、
				;夜间行车和路灯全灭时才能设置两方向的显示时间;
				;-------------------------------------------------------

;-----------------------------------------------------------
;C口用于输出交通灯和数码管的选通脚S1、S0
;PC7~PC5对应南北路口红黄绿灯,PC2~PC0对应东西路口的红黄绿灯
;PC4接S1
;PC3接S0
;A口用于输出LED数码管显示
;B口用于输入
;PB0用于判断是否有紧急控制信号
;PB1用于判断是否有夜间行车的信号
;PB2用于判断是否有设置两个方向的亮时时间
;PB3用于输入8253产生的一秒的时钟信号
;PB4用于控制交通灯全灭
;-----------------------------------------------------------

code   segment 
	assume cs:code
start :mov ax, data
	mov ds, ax 
	call init8253
	mov dx,io8255ctrl
       mov al,82h          ;工作方式0为A,C口输出,B口输入
	out dx,al           ;置方式控制字
;------------------------------------------------------
;十字路口交通灯的控制主程序段
;------------------------------------------------------
repeat: 
	mov al,00100100b    ;初始设南北路口绿灯亮,东西路口红灯亮
	mov dx,io8255c     
	out dx,al
	mov light,al        ;保存当前灯的状态
	mov cl,time1
	call delay          ;延时30秒
	mov al,01000100b    ;置南北路口黄灯亮,东西路口红灯亮
	out dx,al
	mov light,al        ;保存当前灯的状态
	mov cl,5	      
	call delay          ;延时5秒
	mov al,10000001b    ;置南北路红灯亮,东西路绿灯亮
	out dx,al
	mov light,al        ;保存当前灯的状态
	mov cl,time2
	call delay          ;延时30秒
	mov al,10000010b    ;置南北路红灯亮,东西路黄灯亮
	out dx,al
	mov light,al        ;保存当前灯的状态
	mov cl,5
	call delay          ;延时5秒

	mov ah,1            ;读键盘缓冲
	int 16h
	jz repeat           ;无按下键则继续
	mov ah,4ch          ;按下任意键退出
	int 21h

;-----------------------------------------
;延时子模块,CX传递要延时的长度
;-----------------------------------------
delay  proc near
	push ax            ;保护现场
	push dx
	mov count,cl       ;CL的值为要显示的时间长度付给count
lop:   cmp count,0
 	jz exit
 
	call init8253      ;初始化8253
wait1s:		
	mov dx,io8255b     ;读PB口
	in al,dx
	and al,00000001b   ;判断PB0是否为1
	cmp al,0
	jz next            ;为0跳到下一步
	call emergency     ;否则调用紧急控制子程序
next:       
	in al,dx           ;读PB口
	and al,00000010b   ;判断PB1是否为1
	cmp al,0
	jz next1           ;为0跳到下一步
	call nighting      ;否则调用夜间行车子程序
next1: 

	in al,dx           ;读PB口
	and al,00010000b   ;判断PB4是否为1
	cmp al,0
	jz next3           ;为1就跳到下一步
	call turnoff       ;否则调用路灯全灭子程序
next3:
	call display       ;显示剩余时间
	in al,dx           ;读PB口
	and al,00001000b   ;判断PB3是否为0
	cmp al,0
	jnz wait1s         ;不为0,则表示还没到一秒,等待
	dec count          ;绿灯延时长度减一
	jmp lop
exit:  pop dx             ;恢复现场
	pop ax
	ret
delay  endp

;---------------------------------------------
;显示剩余时间子程序
;---------------------------------------------
display proc near
	
	push ax             ;保护现场
	push bx
	push cx
	push dx

	mov bx, offset led
  
	mov cl, 10
	mov al, count       ;要显示的数为count的值
	mov ah, 0
	div cl              ;除10,求出十位及个位,商(即十位)在AL,余数(即个位)在AH
 
	xlat                ;转换对应的码值	
	mov dx, io8255a    
	out dx, al	      ;把十位送到LED灯显示
	mov dx, io8255ctrl
	mov al, 00000110b   ;PC3置0,即关闭数码管的S0
	out dx,al
	mov dx, io8255ctrl 
	mov al, 00001001b   ;PC4置1,即选通数码管的S1
	out dx, al

	mov cx,30000
lop1:   loop lop1          ;延时
	
	mov dx, io8255a
	mov al, ah          ;个位的值放到AL中
	xlat                ;转换对应的码值
	out dx,al           ;把个位送到LED灯显示
	mov dx, io8255ctrl 
	mov al, 00001000b   ;PC4置0,即关闭数码管的S1
	out dx, al
	mov dx, io8255ctrl
	mov al, 00000111b   ;PC3置1,即选通数码管的S0
	out dx,al
	mov cx,30000
lop2:  loop lop2           ;延时

	pop dx              ;恢复现场
	pop cx
	pop bx
	pop ax
	ret
display endp

;-----------------------------------------
;初始化8253子程序
;-----------------------------------------
init8253 proc near
	push dx              ;保护现场
	push ax
	mov dx, io8253ctrl
	mov al, 36h
	out dx, al
	mov ax, 1000
	mov dx, io8253a
	out dx, al
	xchg ah, al
	out dx, al
	mov dx, io8253ctrl
	mov al, 76h
	out dx, al
	mov ax, 2000
	mov dx, io8253b
	out dx, al
	xchg ah, al
	out dx, al
	pop ax            ;恢复现场
	pop dx
	ret
init8253 endp

;------------------------------------
;路灯全灭子程序
;------------------------------------
turnoff proc near
	push ax          ;保护现场
	push bx
	push cx
	push dx
	mov dx,io8255c
	mov al,0
	out dx,al        ;灯全灭
	mov bl,count
	mov count,0      ;数码管显示0
again:
	call display
	mov dx,io8255b
	in al,dx
	and al,00000001b
	cmp al,0
	jz noemergency
	call emergency
noemergency:
	mov dx,io8255b     ;读PB口
	in al,dx
	and al,00000100b   ;判断PB2是否为1
	cmp al,0
	jz noadjust           ;为0跳到下一步
	call adjust        ;否则调用调节两方向了绿灯的时间
noadjust:
	mov dx,io8255b     ;读PB口
	in al,dx
	and al,00010000b
	cmp al,0
	jnz again
	call init8253
	mov count,bl
	pop dx            ;恢复现场
	pop cx
	pop bx
	pop ax
	ret
turnoff endp


;------------------------------------
;紧急控制子程序OK
;------------------------------------
emergency proc near
	push ax          ;保护现场
	push bx
	push cx
	push dx
	mov al,count     ;保存count
	push ax

	mov count,30     ;使数码管要显示的时间为30
	mov dx,io8255c
	mov al,10000100b ;使两路口红灯亮
	out dx,al
	mov dx,io8255b
lop3:   
	call display
	in al,dx
	and al,00000100b   ;判断PB2是否为1
	cmp al,0
	jz noadjust1        ;为0跳到下一步
	call adjust        ;否则调用调节两方向了绿灯的时间
noadjust1:
	
	in al,dx
	and al,00000001b
	cmp al,0
	jnz lop3            ;PB0的信号仍为1,即交通在紧急状态下,继续等待
	
	mov al,light      ;否则恢复当前交通秩序 
	mov dx,io8255c
	out dx,al
	call init8253

	pop ax
	mov count,al      ;恢复count
	pop dx            ;恢复现场
	pop cx
	pop bx
	pop ax
	ret
emergency endp

;-------------------------------------
;夜间行车子程序
;-------------------------------------
nighting proc near
	push ax            ;保护现场
	push bx
	push cx
	push dx
	mov al,count       ;保存count
	push ax
	mov count,0        ;数码管显示0
	mov al,01000010b   ;两路口的黄灯亮
	mov bx,ax          ;把ax的值即黄灯的状态保存到bx
lop4:	mov ax,bx
	mov dx,io8255c     ;两黄灯的状态由8255C口输出
	out dx,al
	mov dx,io8255b
wait1:
	call display       ;显示剩余时间

	in al,dx           ;读8255B口
	and al,00000001b   ;判断PB0是否为1
	cmp al,0
	jz skip            ;不为1跳到下一步
	call emergency     ;为1则执行紧急控制
skip:
	in al,dx           ;读PB口
	and al,00000100b   ;判断PB2是否为1
	cmp al,0
	jz noadjust2
	call adjust
noadjust2:
	
	in al,dx
	and al,00001000b   ;判断PB3是否为0,为0时到了一秒
	cmp al,0
	jnz wait1          ;为1,则表示还没到一秒,循环等待,制造黄灯亮一秒
	mov ax,bx
	xor al,11111111b   
	and al,01000010b   ;两路口的黄灯与前一秒的状态相反,使达到闪烁的效果
	mov bx,ax          ;把ax的值即两黄灯的状态保存到bx

	in al,dx           ;读PB口
	and al,00000010b
	cmp al,0           ;测试PB1是否为1
	jnz lop4           ;若为1则表示夜间行车信号仍存在,继续等待

	mov al,light       ;否则恢复当前交通秩序 
	mov dx,io8255c
	out dx,al
	call init8253
	pop ax
	mov count,al       ;恢复count
	pop dx             ;恢复现场
	pop cx
	pop bx
	pop ax

	ret
nighting endp

;-------------------------------
;调节两方向的延时时间OK
;-------------------------------
adjust proc near
	push ax               ;保护现场
	push bx
	push cx
	push dx
	
	mov dx,offset message1
	mov ah,9
	int 21h
	mov dx,offset message2
	mov ah,9
	int 21h
	call read
	mov time1,dl          ;设置南北路口延时参数
	mov dx,offset message3
	mov ah,9
	int 21h
	call read
	mov time2,dl          ;设置东西路口延时参数
		
	mov dx,offset message4
	mov ah,9
	int 21h
	mov dx,io8255b
lop5:  in al,dx
	and al,00000100b
	cmp al,0	
	jnz lop5              ;调节控制开关没有关上

	pop dx                ;恢复现场
	pop cx
	pop bx
	pop ax
	ret
adjust endp
;----------------------------------------
;从键盘读数
;结果放在DX中
;----------------------------------------
read proc near
	push ax               ;保护现场
	push bx
	push cx
	
	mov dx,0
dec1:  mov ah,1
	int 21h
	sub al,30h
	jl dec2
	cmp al,9
	jg dec2
	cbw
	push ax
	mov ax,dx
	mov cx,10
	mul cx
	mov dx,ax
	pop ax
	add dx,ax
	jmp dec1
dec2:         
	pop cx          ;恢复现场
	pop bx
	pop ax
	ret
read endp
code ends
	end start

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -