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

📄 code.asm

📁 十字路口的交通灯管理,红绿灯亮灭的时间安排,还有闪烁时间
💻 ASM
字号:
;路口定义:1路口为东,2路口为南,3路口为西,4路口为北
CODE 		SEGMENT
ASSUME 		CS:CODE
INTPORT1  	EQU 	0020H    ;定义8259的控制口地址,用来写ICW1             
INTPORT2 	EQU 	0021H     ;定义8259的数据口地址,用来写ICW2,3,4          
INTQ3	 	EQU 	INTERUPT3  ;定义3号中断向量对应的处理函数
INTQ7	 	EQU 	INTERUPT7  ;定义7号中断向量对应的处理函数
CONTPORT 	EQU 	00DFH      ;8255的控制口地址
DATAPORT 	EQU 	00DEH	   ;8255的数据口地址
CtrPort EQU 0073H    ;8255的方式选择控制字地址  
APort	EQU 0070H    ;8255的A口地址,A口在本实验中未使用
BPort	EQU 0071H    ;8255的B口地址,PB4-PB7控制四个路口直行灯的亮灭(本例为PB0-PB3)
CPort	EQU 0072H    ;8255的C口地址,PC0-PC3控制四个路口左转灯,PC4-PC7控制右转灯,0为亮,1为灭??	

DATA1	 	EQU 	0500H  ;电平错误显示区首地址,INTQ7显示错误时使用
DATA2	 	EQU 	0508H   ;在CONVERS1中使用到 ,为显示字符区首地址
DATA4	 	EQU 	0520H   ;显示缓冲区的首地址              
DATA5	 	EQU 	0528H   ;LEDDISP中使用,保存显示到第几位
DATA6	 	EQU 	0529H   ; INTERUPT3 中使用,用于保存8259收到8253时钟脉冲的次数
DATA7	 	EQU 	052AH    ;保存当前四个路口的灯处于哪个状态(共4个)
DATA8	 	EQU 	052BH    ;保存剩余的秒数,在FORMAT函数的最后进行初始定义             
DATA9	 	EQU 	052CH    ;保存剩余的秒数,在FORMAT函数的最后进行初始定义
DATA10	 	EQU 	052EH    ;在CONVERS2中使用,作为指针,指向显示缓冲区的某一位 

                ORG     1800H      ;存储地址的偏移量
START:
;------------------------ 初始化存储空间和各个芯片--------------------------------
                CALL    FORMAT
                CLD
                ;初始化8253
		MOV     DX,004BH      
                MOV     AL,0B6H                              
                OUT     DX,AL                                
                MOV     DX,004AH
                MOV     AL,50H
                OUT     DX,AL
                MOV     AL,0C3H
                OUT     DX,AL    
		; 定义8255的工作方式,三个端口均工作于方式0,均为输出口
	        MOV AL,80H
	        MOV DX,CtrPort 
		OUT DX,AL                            

                ;写中断向量
		MOV     AX,0H
                MOV     DS,AX
                CALL    writeINT        

                MOV     AL,13H            ;初始化8259
                MOV     DX,INTPORT1
                OUT     DX,AL
                MOV     AL,08H
                MOV     DX,INTPORT2
                OUT     DX,AL
                MOV     AL,0BH
                OUT     DX,AL
                MOV     AL,0F7H
                OUT     DX,AL
;--------------------------------------------------------------------------------
;---------------------等待模块,用来调用中断服务程序和交通灯状态程序------------------
WATING:     STI   ;开中断
            CMP  BYTE PTR DS:[DATA7],01H     ;判断是否为状态一
            JA   WATING1            ;如果不是则转WATING1
            CMP  BYTE PTR DS:[DATA8],03H  ;如果是状态一,看当前时间剩余值是否大于3
            JNA  ZT1F   ;如果小于等于3秒,则调用状态一闪烁程序
            CALL  ZT1    ;如果大于3秒,则调用状态一程序
            JMP  WATING
WATING1:   CMP  BYTE PTR DS:[DATA7],02H
            JA   WATING2
            CMP  BYTE PTR DS:[DATA8],03H
            JNA  ZT2F
            CALL  ZT2
            JMP  WATING
WATING2:   CMP  BYTE PTR DS:[DATA7],03H
            JA   WATING3
            CMP  BYTE PTR DS:[DATA8],03H
            JNA  ZT3F
            CALL  ZT3
            JMP  WATING
WATING3:    JMP WATING4    ;跳转到WATING4,因为JNA指令只能在段内跳转范围为-127b-128b,
;-------------------------------------------------------------------------------------
;-----------------------------交通灯状态子程序-----------------------------------------
;-------------状态1: 2、4路口直行灯点亮------------------
ZT1:    PUSH  AX
        PUSH  DX
        MOV AL,01010000B  ;设置2,4路口直行灯亮
        MOV DX,BPort      ;BPort为8255A的PB口的地址
        OUT DX,AL         ;更改PB口的值,从而改变LED灯显示的状态
        MOV AL,00H      ;设置四个路口左转灯,右转灯全部关闭
        MOV DX,CPort     ;CPort为8255A的PC口的地址
        OUT DX,AL        ;更改PC口的值,从而改变LED灯显示的状态
        POP  DX
        POP AX
        RET
ZT1F:           ;状态一闪烁程序: 2、4路口直行灯闪烁
        PUSH  AX
        PUSH  DX
	MOV CX,12H ;定义闪烁12次
ZT1Flash:MOV AL,00H ;灯灭
	MOV DX,BPort
	OUT DX,AL
	CALL DELAY2 	;短延时
        MOV DX,BPort
        MOV AL,01010000B ;灯亮
	OUT DX,AL
	CALL DELAY2 	;短延时
	LOOP ZT1Flash   ;循环
        POP  DX
        POP AX
        JMP WATING
;-----------------------------------------------------------------
;---------------状态2: 1、3路口左转灯亮,2、4路口右转灯亮---------

;------------------------------------------------------------
;------------------------------交通灯闪烁延时程序------------
DELY2:	CALL DELAY2
	LOOP DELY2
	POP CX
	POP AX
	RET
DELAY2: PUSH CX
	MOV CX,9000H
DELA1:	LOOP DELA1
	POP CX
	RET
;---------------------------------------------------------------------------------------

writeINT:       MOV     AX,0H       ;写中断向量子程序
                MOV     ES,AX
                MOV     DI,002CH
                LEA     AX,INTQ3
                STOSW
                MOV     AX,CS
                STOSW
                MOV     DI,003CH
                LEA     AX,INTQ7
                STOSW
                MOV     AX,CS
                STOSW
                RET

;----------------------------------------------中断处理程序-----------------------------------
INTERUPT3:	
		CLI      ;处理中断时先关中断
                PUSH AX
                PUSH DX
                MOV     AL,DS:[DATA6]  ;DATA6  EQU 0529H 地址中为00D ,用于保存收到的中断次数
                INC     AL
                MOV     DS:[DATA6],AL  ;将00D改为 01D  ,DATA6用于保持收到脉冲的次数,满20时加1
                CMP     AL,20H
                JAE      NEXT      ; 大于等于20时,清零,并转向状态判断程序,中断返回
                JMP      INTRE2     ;小于时中断返回

NEXT:      MOV  BYTE PTR DS:[DATA6],00H    ;将中断计数器清零
	   CALL LEDDISP    ;将显示缓冲区中的数字显示出来
           CALL NEWTIME     ;将时间缓冲区中的数字减一
P1:        CMP  BYTE PTR DS:[DATA7],01H         ;判断是否是第一个状态
           JNZ  P2                              ;如果不是第一个状态,则转P2
           CMP  BYTE  PTR  DS:[DATA8],00H    ;看20S是否已经减到0
     	   JNE  CONV                      ;如果未减到0,则更新显示缓冲区,并中断返回
           MOV  BYTE  PTR  DS:[DATA7],02H   ;如果减到0,则转到第二个状态
           MOV  BYTE  PTR  DS:[DATA9],8H   ;  设定2状态时,路口的显示初始值
           MOV  BYTE  PTR  DS:[DATA8],8H    ;
           JMP  CONV


CONV:      CALL    CONVERS  ;把时间缓冲区中的时间转换到显示缓冲区中
INTRE2:         CALL LEDDISP
                MOV     AL,20H      ;写8259控制口 ,并中断返回
                MOV     DX,INTPORT1
                OUT     DX,AL
                POP DX
                POP AX
                STI     ;开中断
                IRET    ;中断返回
;------------------------------------------------------------------------------------------------

INTERUPT7: 	CLI            ;电平不符合要求时,自动显示ERR
                MOV     SI,DATA1
                CALL    LEDDISP
                MOV     AL,14H
                MOV     DX,INTPORT1
                OUT     DX,AL
                IRET
;-----------------------------转换子程序,将时间数值转换为显示字符,存入显示缓冲区-----------------
CONVERS:        MOV     AL,BYTE PTR DS:[DATA9]   ;转换2,4路口(对应于实验仪上右边显示屏)的秒
                CALL    CONVERS2
                ADD     WORD PTR DS:[DATA10],03H   ;转换1,3路口(对应于实验仪上左边显示屏)的秒
                MOV     AL,BYTE PTR DS:[DATA8]
                CALL    CONVERS2
                MOV     WORD PTR DS:[DATA10],DATA4   ;恢复[DATA10]的指向显示缓冲区首地址
      		RET
CONVERS2:       PUSH    AX
                CALL    CONVERS1           ;转换低位
                MOV     BX,WORD PTR DS:[DATA10]
                MOV     DS:[BX],AL  		;更新低位所对应的显示缓冲区
                ADD     WORD PTR DS:[DATA10],01H   ;[DATA10]指向高位
                POP     AX
                
                PUSH    CX
                MOV     CL,4H
                SHR     AL,CL    ;AL右移CL(4)位, 丢弃低4位,如AL为12H,则转换为01H
                POP     CX
                CALL    CONVERS1      ;转换高位
                MOV     BX,WORD PTR DS:[DATA10]    ;更新高位所对应的显示缓冲区
                MOV     DS:[BX],AL
      		RET
CONVERS1:       MOV     BH,0H
                AND     AL,0FH      ;取AL的低位 ,如AL为12H,则取02H
                MOV     BL,AL    ; 将数值存入BL中,作为基址
                MOV     AL,CS:[BX+DATA2]   ;将相应的显示字符存入AL,如将2对应的字符存入AL.
      		RET
;-------------------------------------------------------------------------------------------

;--------------------------------更新时间缓冲区子程序---------------------------------------
NEWTIME:
                MOV     AL,BYTE PTR DS:[DATA9]     ;[DATA789]全部加1D
                SUB     AL,01D
                DAS                              ;减法的十进制调整,如12D改为12H
                MOV     BYTE PTR DS:[DATA9],AL

                MOV     AL,BYTE PTR DS:[DATA8]
                SUB     AL,01D
                DAS
                MOV     BYTE PTR DS:[DATA8],AL
                RET         ;返回
;----------------------------------------------------------------------------------------------

;-------------------------------------显示子程序,调用时显示时间缓冲区中的字符--------------------------
LEDDISP:
                 PUSH  AX                          ;显示子程序
                 PUSH  BX
                 PUSH  CX
                 PUSH  DX
                 MOV   SI,DATA4    ;DATA4 EQU 0520H    从0520h开始显示
                MOV     AL,90H         ;初始显示时 DATA3 EQU  0518H
                MOV     DX,CONTPORT     ;写8255控制口
                OUT     DX,AL
                
                MOV     BYTE PTR DS:[DATA5],00H  ;DATA5	EQU 0528H
LED1:           CMP     BYTE PTR DS:[DATA5],05H
                JA      LED2        ;如果显示完8位后,返回
                MOV     BL,DS:[DATA5]                         
                MOV     BH,0H
                MOV     AL,CS:[BX+SI]     ; 初始时,SI等于DATA3 0518H ,
                                          ;INTQ3时等于DATA4 0520H ,从0520h显示到0527H
                MOV     DX,DATAPORT     ;写8255数据口,以此改变显示值
                OUT     DX,AL
                
                ADD     BYTE PTR DS:[DATA5],01H     ;显示下一位
                JNZ     LED1
LED2:
                POP  DX
                POP  CX
                POP  BX
                POP  AX
                RET
;---------------------------------------------------------------------------------------------------------

FORMAT:         MOV     BX,0                              ;DATA1	 EQU 0500H
                MOV     WORD PTR DS:[BX+DATA1],5050H     ; 1 0  INTQ7中使用,显示ERR
                ADD     BX,2
                MOV     WORD PTR DS:[BX+DATA1],0079H      ;3 2
                ADD     BX,2
                MOV     WORD PTR DS:[BX+DATA1],0000H      ;5 4
                ADD     BX,2
                MOV     WORD PTR DS:[BX+DATA1],0000H      ;7 6
                ADD     BX,2

                MOV     WORD PTR DS:[BX+DATA1],063FH       ;9  8    显示字符 1 0
                ADD     BX,2
                MOV     WORD PTR DS:[BX+DATA1],4F5BH       ;0B 0A            3 2
                ADD     BX,2
                MOV     WORD PTR DS:[BX+DATA1],6D66H      ;0D 0C
                ADD     BX,2
                MOV     WORD PTR DS:[BX+DATA1],077DH       ;0F 0E
                ADD     BX,2
                MOV     WORD PTR DS:[BX+DATA1],6F7FH       ;11  10
                ADD     BX,2
                MOV     WORD PTR DS:[BX+DATA1],7C77H       ;13 12
                ADD     BX,2
                MOV     WORD PTR DS:[BX+DATA1],5E39H       ;15 14
                ADD     BX,2
                MOV     WORD PTR DS:[BX+DATA1],7179H       ;17 16

;----------------------------------------- 初始化时显示 ------------------------
                ADD     BX,2
                MOV     WORD PTR DS:[BX+DATA1],663FH       ;19 18      40
                ADD     BX,2
                MOV     WORD PTR DS:[BX+DATA1],3F3fH      ;1B 1A       0-
                ADD     BX,2
                MOV     WORD PTR DS:[BX+DATA1],3F3FH      ;1D  1C      00
                ADD     BX,2
                MOV     WORD PTR DS:[BX+DATA1],3F3FH      ;1F 1E       00
                ADD     BX,2
;-------------------------------------------------------------------------------

;-------------显示缓冲区,保存着当前时间对应的显示字符,INTQ3中进行调用和修改-----------
                MOV     WORD PTR DS:[BX+DATA1],065bH        ;21 20    初次显示12
                ADD     BX,2
                MOV     WORD PTR DS:[BX+DATA1],0000H        ; 23 22    0-
                ADD     BX,2
                MOV     WORD PTR DS:[BX+DATA1],065bH        ;25  24    初次显示12
                ADD     BX,2
                MOV     WORD PTR DS:[BX+DATA1],0000H        ; 27 26     00
;---------------------------------------------------------------------------------------
                MOV     BYTE PTR DS:[DATA6],00H  ;保存8259A当前收到时钟脉冲的次数
                MOV     BYTE PTR DS:[DATA7],01H      ;设置初始状态
                MOV     BYTE PTR DS:[DATA8],12H     ;设置刚开始正常工作后1,3路口显示的秒数
                MOV     BYTE PTR DS:[DATA9],12H     ;设置刚开始正常工作后2,4路口显示的秒数
                MOV     WORD PTR DS:[DATA10],DATA4
                RET
;--------------------------------------------------------------------------------------------

CODE 		ENDS
END  		START


⌨️ 快捷键说明

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