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

📄 程序.txt

📁 一个交通灯模拟程序
💻 TXT
字号:
.model small
.stack
.data
led    db 3fh,06h,5bh,4fh,66h,6dh,7dh,07h,7fh,6fh ;段码
buf    db 3,0
        ;存放要显示的十位和个位
intseg    dw ?       ;存放段地址
intoff    dw ?       ;存放偏移地址
intimr    db ?       

.code
.startup
 
start:
    mov dx,28bh         ;将8255设为A和C口输出
    mov al,80h
    out dx,al
    
    mov al,0            ;关数码管显示
    mov dx,28ah         ;设置C口为0
    out dx,al
    
    mov ax,350bh        ;原中断向量保存
    int 21h
    mov intseg,es
    mov intoff,bx

    cli                 ;关中断
    
    push ds             
    mov dx,offset new0bh  ;修改0bh号中断的服务程序为newobh
    mov ax,seg new0bh
    mov ds,ax
    mov ax,250bh
    int 21h
    pop ds

    in al,21h            ;读出IMR
    mov intimr,al         ;保存原IMR内容
    and al,0f7h          ;允许IRQ3中断请求
    out 21h,al           ;设置新IMR内容

    mov dx,283h      ;向8253控制端口写控制字
    mov al,36h       ;使计数器0为工作方式3
    out dx,al
    mov ax,1000      ;写入循环计数初值1000
    mov dx,280h
    out dx,al        ;先写低字节
    mov al,ah
    out dx,al        ;后写高字节
    ;
    mov dx,283h
    mov al,76h       ;使计数器1工作方式3
    out dx,al
    mov ax,1000      ;写入循环计数初值1000
    mov dx,281h
    out dx,al        ;写低字节
    mov al,ah
    out dx,al        ;写高字节
    ;
    mov  dx,28ah     ;dx中存C口地址
    sti              ;开中断
    
again:
    mov ah,3         ;赋数码管初值为30秒
    mov buf,ah
    mov ah,0
    mov buf+1,ah

    in   al,dx
    and  al,3
    or   al,00110000b   ;初始化南北绿灯亮,东西红灯亮
    out  dx,al
    
again1:
    call displayy       ;数码管显示 
    
    mov  ah,buf
    mov  al,buf+1
    cmp  ax,0           ;判断数码管显示是否为零
    jne  again1         ;不是零继续显示
  
    in   al,dx  
    and  al,11011111b    ;使南北绿灯灭 
    out dx,al
  
    mov ah,0             ;赋数码管初值为5秒
    mov buf,ah
    mov ah,5
    mov buf+1,ah
    
yellow:                   ;黄灯闪烁程序
    mov cx,30             ;设置循环次数
    
cx0:
    cmp cx,0
    jne cxNot0            ;cx不是0继续显示
    in   al,dx  
    xor   al,01000000b    ;改变黄灯状态
    out dx,al
    jmp Time0
    
cxNot0:
    call displayy         ;数码管显示
    dec cx                ;cx减1
    call delayMs          ;延时
    jmp  cx0  
    
Time0:  
    mov  ah,buf           ;判断黄灯闪烁时间是否结束
    mov  al,buf+1
    cmp  ax,0
    jne yellow            ;时间不是0继续闪烁
    
    jmp again12
  
AGAIN11: 
    jmp again             ;跳转中继,跳到again,即程序再一次循环执行
    
again12:
    sti
    mov  ah,3             ;赋数码管初值为30秒
    mov  buf,ah
    mov  ah,0
    mov  buf+1,ah
    
again2: 
    in   al,dx  
    and  al,3
    or   al,10000100b; 使南北红灯亮,东西绿灯亮
    out  dx,al

    call displayy     ;数码管显示
    
    mov  ah,buf       ;判断数码管显示是否为零
    mov  al,buf+1
    cmp  ax,0
    jne  again2       ;不是零继续显示
    
    in   al,dx  
    and  al,11111011b ;使东西绿灯灭
    out dx,al
    
    mov  ah,0         ;赋数码管初值为5秒
    mov  buf,ah
    mov  ah,5
    mov  buf+1,ah

yellow1:
    mov cx,30             ;设置循环次数
cx01:
    cmp cx,0              
    jne cxNot01           ;cx不是0继续显示

    in   al,dx  
    xor   al,00001000b    ;改变黄灯状态
    out dx,al
    jmp Time01
    
cxNot01:
    call displayy         ;数码管显示
    dec cx                ;cx减1
    call delayMs          ;延时
    jmp  cx01 
    
Time01:
    mov  ah,buf           ;判断黄灯闪烁时间是否结束
    mov  al,buf+1
    cmp  ax,0
    jne yellow1           ;时间不是0继续闪烁

    mov  ah,0bh
    int  21h
    test al,al
    je  AGAIN11           ;有键按下,则退出;否则跳到跳转中继处。

    mov al,intimr
    out 21h,al            ;恢复原状态
    mov dx,intoff
    mov ax,intseg
    mov ds,ax
    mov ax,250bh
    int 21h
    sti
    
 .exit          ;返回
    
 ;////////////////////////////////////////////   
    
delay    proc      ;延时
    push cx
    mov cx,3000 
delay1:   
    loop delay1
    pop cx
    ret
delay    endp
;//////////////newobh中断服务程序,实现数码管显示数字减一//////////
new0bh proc
    sti
    push ax
    push ds

    mov ax,@data
    mov ds,ax

    mov al,buf+1    ;读出个位数秒数
    cmp al,0        
    
    je intp1         ;为0跳转到 intp1
    dec al           ;不为0,个位数字减一
    mov buf+1,al     ;写回buff中
    jmp intp2        ;十位数字不改变并跳到结束
intp1:
    mov ah,buf       ;读出十位数字
    cmp ah,0
    je  intp2        ;十位数字为0,直接结束
    dec ah           ;十位数字不为0,使其减一
    mov buf,ah       ; 写回buff中
   
    mov al,9         ;使个位数字为9
    mov buf+1,al     ;写回
   
intp2:    
    
    mov al,20h        ;发送EOI
    out 20h,al
    pop ds
    pop ax
    iret
new0bh  endp

;///////////////led显示////////////////////
displayy   proc
    push ax
    push bx
    push cx
    push dx
    mov bl,buf      ;bl为要显示的数
    mov bh,0
    mov al,led[bx]  ;求出对应的led数码
    mov dx,288h     ;自8255A的口输出
    out dx,al
    
    mov dx,28ah
    in al,dx    
    
    or al,2        ;使左边的数码管亮
    out dx,al
    call delay      ;延时
    ;
    mov dx,28ah         ;关掉数码管显示
    in  al,dx
    and al,11111101b
    out dx,al
    ;
    mov bl,buf+1      ;bl为要显示的数
    mov bh,0
    mov al,led[bx]    ;求出对应的led数码
    mov dx,288h       ;自8255A的口输出
    out dx,al
    
    mov dx,28ah
    in al,dx    
    
    or al,1         ;使右边的数码管亮
    out dx,al
    call delay       ;延时
    ;
    mov dx,28ah         ;关掉数码管显示
    in  al,dx
    and al,11111110b
    out dx,al

    pop dx
    pop cx
    pop bx
    pop ax
    ret
displayy  endp

;////////////黄灯延时子程序////////////////
delayMs   proc
    push cx
    push dx 
    push ax
    push bx
    mov  cx,0
loop1:           ;实现循环65536次
    cmp  cx,0
    loop  loop1 
    pop bx
    pop ax
    pop dx
    pop cx
    ret
delayMs   endp

end

⌨️ 快捷键说明

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