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

📄 jjztl.asm

📁 IO程序 - 交通灯演示程序,采用中断驱动模式。① 南北路口的绿灯
💻 ASM
📖 第 1 页 / 共 2 页
字号:
Init8255 ENDP
;----------------------------------------------------------
;┏━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
;┃Display LED灯和七段数码管显示子程序                   ┃
;┣━━━━━━━━━━━━━━━━━━━━━━━━━━━┫
;┃参    数 : AH - 显示第几个数码管                      ┃
;┃           AL - 数码管上显示的数字                    ┃
;┗━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
Display PROC NEAR
            PUSHA

            ; 将AL的数字值更换为相应的段码,从8255的PA口输出
            LEA     BX, SegTab
            XLAT
            MOV     DX, E8255_PA
            OUT     DX, AL   
            
            ; 根据当前LED显示模式获得当前PC2-PC7口的输出值
            MOV     AL, [CurMode]
            LEA     BX, LedMode
            XLAT
            
            ; 将PC2-PC7的输出值和数码管的位码相或,并输出到PC口
            OR      AL, AH
            MOV     DX, E8255_PC
            OUT     DX, AL

            POPA
            RET
Display ENDP
;----------------------------------------------------------
;┏━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
;┃Delay 短暂延迟(根据各机状态修改循环次数)              ┃
;┣━━━━━━━━━━━━━━━━━━━━━━━━━━━┫
;┃参    数 : 无                                         ┃
;┃返 回 值 : 无                                         ┃
;┗━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
Delay PROC NEAR
            PUSH    CX
            
            MOV     CX, 02H

  D_LOOP1:  PUSH    CX
            MOV     CX, 0FFFFh
  D_LOOP2:  LOOP    D_LOOP2
            POP     CX
            LOOP    D_LOOP1

            POP     CX
            RET
Delay ENDP
;----------------------------------------------------------
;┏━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
;┃SetIRQ 重新设置7号中断                                ┃
;┣━━━━━━━━━━━━━━━━━━━━━━━━━━━┫
;┃参    数 : 无                                         ┃
;┃返 回 值 : 无                                         ┃
;┗━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
SetIRQ PROC NEAR
            PUSHA

            ; 暂时禁止中断
            CLI

            ; 将ES清零,用ES:[BX]来存取内存底端地址
            XOR     AX, AX
            MOV     ES, AX

            ; 计算IRQ7中断向量的地址: ADDR = IRQ7_NR * 4
            MOV     AL, IRQ7_NR
            MOV     BL, 4H
            MUL     BL
            MOV     BX, AX

            ; 保存旧中断向量偏移地址到OldIrq变量中
            LEA     SI, OldIrq
            MOV     AX, ES:[BX]
            MOV     [SI], AX

            ; 设置新中断向量偏移地址
            LEA     DI, NewIRQ7
            MOV     ES:[BX], DI
            ADD     BX, 2

            ; 保存旧中断向量段地址
            ADD     SI, 2
            MOV     AX, ES:[BX]
            MOV     [SI], AX

            ; 设置新中断向量段地址
            MOV     AX, CS
            MOV     ES:[BX], AX

            ; 读写中断屏蔽寄存器,开放IRQ7中断
            IN      AL, E8259_CTL1
            AND     AL, IRQ7_OPEN_MASK
            OUT     E8259_CTL1, AL

			; 开启中断
            STI             

            POPA
            RET
SetIRQ ENDP
;----------------------------------------------------------
;┏━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
;┃RestoreIRQ 还原旧7号中断                              ┃
;┣━━━━━━━━━━━━━━━━━━━━━━━━━━━┫
;┃参    数 : 无                                         ┃
;┃返 回 值 : 无                                         ┃
;┗━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
RestoreIRQ PROC
            PUSHA

            XOR     AX, AX
            MOV     ES, AX

            ; 计算7号中断向量的地址
            MOV     AL, 0Fh
            MOV     BL, 4H
            MUL     BL
            MOV     BX, AX
            
            CLI

            LEA     SI, OldIrq
            MOV     AX, [Si]
            MOV     ES:[BX], ax

            ADD     SI, 2H
            ADD     BX, 2H

            MOV     AX, [Si]
            MOV     ES:[BX], ax

            ; 读写中断屏蔽寄存器,关闭IR7中断
            IN      AL, E8259_CTL1
            OR      AL, IRQ7_CLOSE_MASK
            OUT     E8259_CTL1, AL 
            
            STI

            POPA
            RET
RestoreIRQ ENDP
;----------------------------------------------------------
;┏━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
;┃NewIRQ7 新中断子程序                                  ┃
;┣━━━━━━━━━━━━━━━━━━━━━━━━━━━┫
;┃参    数 : 无                                         ┃
;┃返 回 值 : 无                                         ┃
;┗━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
NewIRQ7 PROC NEAR
            PUSHA

            MOV     AX, DATA_SEG
            MOV     DS, AX
                                 
            ;--------------------------------------------------
            ; 计秒处理
            LEA     DI, SecTick
            DEC     BYTE PTR [DI]

            ; 是否计数为0,为0代表已经经过一秒
            CMP     BYTE PTR [DI], 0
            JNZ     NI_SEC_END

            ; 更新当前倒计时时间
            CALL    DecTime

            ; 重新置10
            MOV     BYTE PTR [DI], SEC_SETUP

  NI_SEC_END:
            ;--------------------------------------------------
            INC     WORD PTR [ModeTick]
            
            ; 设置 BX 为当前模式号
            MOV     BL, [CurMode]
            
            XOR     BH, BH
            MOV     DX, BX
            ADD     DX, BX    
            
            LEA     SI, ModeInt
            ADD     SI, DX

            ; 比较是否达到当前模式号的时间间隔
            MOV     AX, [SI]
            CMP     [ModeTick], AX
            JZ      NI_ADD_MODE

            ; 没到达间隔
            JMP     NI_END

            ; 递增当前模式
  NI_ADD_MODE:
            INC     BL
            CMP     BL, 14
            JNZ     NI_NO14
            ; 如果模式号超出范围(>=14),置零
            XOR     BL, BL
  NI_NO14:
            MOV     [CurMode], BL
            ; 修改倒计时显示时间
            LEA     SI, TimeInc
            ADD     SI, BX
            ADD     SI, BX
            MOV     AL, [SI]
            ADD     [CurTime], AL
            MOV     AL, [SI+1]
            ADD     [CurTime+1], AL    
                                  
            XOR     AX, AX
            MOV     [ModeTick], AX
  NI_END:    
            ; 发出EOI结束中断
            MOV     AL, E8259_CTL0
            OUT     E8259_CTL0, AL

            POPA
            IRET
NewIRQ7 ENDP
;----------------------------------------------------------
; 
;┏━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
;┃DecTime 减少 CurTime 表示的值                         ┃
;┣━━━━━━━━━━━━━━━━━━━━━━━━━━━┫
;┃参    数 : 无                                         ┃
;┃返 回 值 : 无                                         ┃
;┗━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
DecTime PROC NEAR
            PUSHA

            LEA     DI, CurTime

            ; 判断个位,如果个位不为0,只要递减个位
            ; 否则个位置9,十位递减
            MOV     AL, [DI+1]
            CMP     AL, 0
            JZ      DT_CASE
            DEC     BYTE PTR [DI+1]
            JMP     DT_END

            ; 个位为0,如果十位也是0,直接返回
  DT_CASE:
            CMP     BYTE PTR [DI], 0
            JNZ     DT_NEXT

            POPA
            RET
  DT_NEXT:
            MOV     BYTE PTR [DI+1], 9
            DEC     BYTE PTR [DI]
  DT_END:        
            POPA
            RET
DecTime ENDP   
            
;----------------------------------------------------------  
;┏━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
;┃KeyTest 按键检测子程序                                ┃
;┣━━━━━━━━━━━━━━━━━━━━━━━━━━━┫
;┃参    数 : 无                                         ┃
;┃返 回 值 : AL = 1 主程序结束循环                      ┃
;┗━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
KeyTest PROC NEAR
            PUSH    DX
 
			; 读取键盘端口
            MOV     DX, KEYBOARD_PORT
            IN      AL, DX
            CMP     AL, 1
            JE      KT_P

            MOV     AL, 0
            POP     DX
            RET

  KT_P:     MOV     AL, 1
            POP     DX
            RET
KeyTest ENDP

CODE_SEG ENDS
            END START

⌨️ 快捷键说明

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