利用8259A的 IRQ2显示中断过程

 
 
 
 
微机原理课程设计
 
 
 
 
 
 
 
 
 
 
 
 
 
            设计题目:利用8259A的IRQ2显示中断过程
         学生姓名:王瑞(20042412)
         指导老师:周国祥
         实验时间:2007年1月
 
 
 
 
 
 
设计题目:
   利用8259A的 IRQ2显示中断过程
要求:
1.  主程序是在七段数码管上循环显示‘8’,从右到左显示。
2.  中断服务程序中,在七段数码管上依次显示全1,2,3,4,5,6,7,                                 8,9要去显示2秒左右的时间,可采用软件延迟(时间可通过调试大致2秒左右),总计中断9次,结束返回DOS。
3.  每次由手动产生IRQ2中断请求信号,引起中断。
设计思路:
  软件方面,程序有两个主要部分:主程序和中断服务子程序。
主程序首先要完成的是一些与处理工作,例如查找设备,设置TPC卡中 9054芯片IO口,保存原来的0AH号中断的中断向量,设置新的中断向量,设置中断掩码,显示提示信息,然后打开中断,进入主循环。在主循环中,不断的在LED上从右向左显示8。直到被IRQ2的中断信号打断。此外,在主程序中还对中断的执行进行计数。当计数满9次后,自动跳出。为了使主程序上的8的循环可以看的出来,故将显示8的延迟设计的比较长。当完成9次中断,主程序还要完成一些后续的处理工作:恢复中断掩码;恢复中断向量;设置 TPC卡中9054芯片IO口,关闭中断。返回DOS。
中断子程序完成在6位数码管上“同时”显示一个数的功能,这个数为1—9中的某一个,可以用循环次数作为参数。这里的同时显示实质上是利用视觉上的暂停效果,即只要每秒能在同一个数码管上显示信息超过24次,看起来就是同时了。而这一点在现在的计算机速度条件下很容易实现。为了不发生混乱,在中断子程序的执行过程中不允许再次中断。
另外,程序中还有两个子程序:findtpc和dispword,这些是为了完成查找设备等预处理。
硬件方面,实验时把总线上的IRQ2引脚与拨键开关相连以手动的产生中断信号。另外,再把LED的片选信号CS与210-217相连。(注:LED的显示是通过向LED的数据端口送入数据,再向LED的位选端口送入位选信号来实现)
 
 
  实验程序:
;386 以上微机适用
; dos 下才能使用
;tasm4.1 或以上编译
;**********************************************;
;*  利用 8259A IRQ2 显示中断过程 *;
;**********************************************;
 io_plx_device_id   equ 05406h      ;TPC 卡设备 ID
 io_plx_vendor_id equ 010b5h      ;TPC 卡厂商 ID
 IO_PLX_SUB_ID         EQU 0905410B5H ;TPC 卡子设备及厂商 ID
 portseg              EQU 211H-200H   ; 数码管端口地址
 portbit               EQU 210H-200H
 
data segment
 csreg dw ?
 ipreg   dw ?     ; 旧中断向量保存空间
 irq_times   dw 10   ; 中断计数
 msg1    db      0dh,0ah,'TPC pci card Interrupt',0dh,0ah,'$'
 msg2    db      0dh,0ah,'Press any key to exit!',0dh,0ah,'$'
 msg3    db      0dh,0ah,'Press DMC or wait to interrupt 10 times and exit!',0dh,0ah,'$'
 io_9054base_address       db 4 DUP(0)      ;TPC PCI 接口芯片 I/O 基地址暂存空间
 io_base_address db 4 DUP(0)      ;TPC I/O 基地址暂存空间
 interrupt_line         db 2 DUP(0)      ;TPC 卡中断号暂存空间
 pcicardnotfind              db 0dh,0ah,'TPC pci card not find or address/interrupt error !!!',0dh,0ah,'$'
 io9054baseaddress     db 0dh,0ah,'TPC pci card 9054 Chip I/O Base Address : ','$'
 iobaseaddress              db 0dh,0ah,'TPC pci card I/O Base Address : ','$'
 intnumber              db 0dh,0ah,'TPC pci card Interrupt Line : ','$'
 enter_return           db 0dh,0ah,'$'
 MESS DB         '8253A TIMER0 IN MODE3! COUNT=0200H',0AH,0DH
         DB        '8253A TIMER1 IN MODE2! COUNT=0aH',0AH,0DH,'$'
 irq_vect            db 08h,09h,0ah,0bh,0ch,0dh,0eh,0fh,70h,71h,72h,73h,74h,75h,76h,77h
                     ; 新的中断向量 , 中断 0-7 的向量为 :08h-0fh, 中断 8-15 的向量为 :70h-77h
 irq_mask_0_7_table    db 011111110b,011111101b,011111011b,011110111b
                     db 011101111b,011011111b,010111111b,001111111b
                     db 011111011b,011111011b,011111011b,011111011b
                     db 011111011b,011111011b,011111011b,011111011b
                     ; 新的中断掩码 , 中断 0-7 时从低至高相应位为零 , 中断 8-15 时第 2 位为零
 irq_mask_8_15_table db 0ffh,0ffh,0ffh,0ffh,0ffh,0ffh,0ffh,0ffh
                     db 011111110b,011111101b,011111011b,011110111b
                     db 011101111b,011011111b,010111111b,001111111b
                     ; 新的中断掩码 , 中断 0-7 时全一 , 中断 8-15 时从低至高相应位为零
LED      DB             06,5BH,4FH,66H,6DH,7DH,07,7FH,6FH
data ends
stacks segment
 db 100 dup (?)
stacks ends
code segment
        assume     cs:code,ds:data,ss:stacks,es:data
start:
;Enable Local Interrupt Input
.386
cli
mov     ax,data
mov     ds,ax
mov     es,ax
    mov     ax,stacks
   mov     ss,ax
       call        findtpc         ; 查找 TPC 卡资源并显示
 
       mov  dx,word ptr io_9054base_address
       add    dx,68h ; 设置 tpc 卡中 9054 芯片 io , 使能中断
   in          ax,dx
   or          ax,0900h
   out       dx,ax
 
mov     bx,word ptr interrupt_line     ; 保存原中断向量
       mov     al,byte ptr [irq_vect+bx]
       mov     ah,35h
int         21h
       mov     ax,es
       mov     csreg,ax
       mov      ipreg,bx
 
   mov     bx,word ptr interrupt_line     ; 设置新中断向量
   mov     al,byte ptr [irq_vect+bx]
   mov     cx,cs
   mov     ds,cx
       mov     dx,offset int_proc
       mov     ah,25h
   int       21h
 
       mov     ax,data
       mov     ds,ax
       mov     es,ax
   in        al, 21h         ; 设置中断掩码
   mov     bx,word ptr interrupt_line
       mov     ah,byte ptr [irq_mask_0_7_table+bx]
       and              al,ah
   out     21h, al
   in       al, 0a1h
   mov     bx,word ptr interrupt_line
       mov     ah,byte ptr [irq_mask_8_15_table+bx]
       and           al,ah
   out    0a1h, al
 
   mov   dx,offset msg2
       mov   ah,09h
       int     21h
   mov     dx,offset msg3
       mov     ah,09h
       int         21h
   mov irq_times,0
       sti                ; 开中断
       
loop1:
   cmp irq_times,9                ; 等待中断并判断中断 9 次后退出
    jz exit
   mov          ax,data
   mov          ds,ax
       mov      al,7FH
       mov  dx,word ptr io_base_address
       add              dx,portseg
       out        dx,al
       mov      al,bl
       mov  dx,word ptr io_base_address
       add              dx,portbit
       out        dx,al
   push cx
 
    mov    cx,0FFFFh
skip3:
    push   cx
   mov    cx,03FFH
skip4:
loop   skip4
    pop   cx
   loop          skip3
   pop    cx
 
shl    bl,1
   cmp          bl,40h
   jne           skip5
   mov          bl,01h
skip5:
   jmp              loop1
 
exit:  
cli
   mov     bx,word ptr interrupt_line            ; 恢复中断掩码
       mov     ah,byte ptr [irq_mask_0_7_table+bx]
       not       ah
       in           al, 21h
       or           al, ah
       out        21h, al
   mov     bx,word ptr interrupt_line
       mov     ah,byte ptr [irq_mask_8_15_table+bx]
       not       ah
       in           al, 0a1h
       or           al, ah
       out        0a1h, al
 
mov     bx,word ptr interrupt_line            ; 恢复原中断向量
       mov     al,byte ptr [irq_vect+bx]
   mov     dx,ipreg
       mov     cx,csreg
       mov     ds,cx
       mov     ah,25h
   int         21h
 
       mov     ax,data ; 设置 tpc 卡中 9054 芯片 io , 关闭中断
   mov     ds,ax
       mov     dx,word ptr io_9054base_address
       add      dx,68h
       in        ax,dx
   and      ax,0f7ffh
       out       dx,ax
 
       mov     ax,4c00h
       int         21h              ; 退出
 
int_proc proc far
    cli
   push    ax
push    dx
   push    ds
mov          bl,01h
   mov          ax,data
   mov          ds,ax
   mov  si,irq_times
   mov          cx,05FFH       
again:
   mov          al,LED[si]
       mov  dx,word ptr io_base_address
       add              dx,portseg
       out        dx,al
       mov      al,bl
       mov  dx,word ptr io_base_address
       add              dx,portbit
       out        dx,al
   shl    bl,1
   cmp          bl,40h
   jne           skip6
    mov          bl,01h
skip6:
   push   cx
   mov          cx,0FFFFH
again2:
   push cx
   mov          cx,10
again4:
loop  again4
   pop   cx
   loop          again2
   pop   cx
loop   again
 
    mov     al,20h              ;Send EOI
   out       0a0h,al
   out       20h,al
 
   inc      irq_times
    pop      ds
   pop      dx
   pop      ax
   sti
    iret
int_proc endp
 
findtpc proc near            ; 查找 TPC 卡资源并显示
       pushad
       pushfd
       mov      ax,0b101h
       int          1ah
       jc           findtpc_notfind        ; 检查 PCI BIOS 是否存在
 
       mov      ax,0b102h
       mov      cx,io_plx_device_id
       mov      dx,io_plx_vendor_id
       mov      si,0
       int          1ah
       jc           findtpc_notfind        ; 检查 tpc 卡是否安装 , 设备号、厂商号
 
       mov      ax,0b10ah
       mov      di,02ch
       int          1ah
       jc           findtpc_notfind
       cmp      ecx,io_plx_sub_id
       jnz        findtpc_notfind        ; 检查 tpc 卡是否安装 , 子设备号、厂商号
 
       mov      ax,0b10ah
       mov      di,14h
       int          1ah
       jc           findtpc_notfind        ; TPC 9054 芯片 I/O 基址信息
       mov      dword ptr io_9054base_address,ecx
       and              ecx,1
       jz           findtpc_notfind        ; 检查是否为 i/o 基址信息
    mov      ecx,dword ptr io_9054base_address
       and              ecx,0fffffffeh
   mov      dword ptr io_9054base_address,ecx ; 去除 i/o 指示位并保存
 
       MOV     AX,0B10AH
       MOV     DI,18H
       INT 1AH
       JC findtpc_notfind        ; TPC I/O 基址信息
       mov      dword ptr io_base_address,ecx
       and       ecx,1
       jz    findtpc_notfind        ; 检查是否为 i/o 基址信息
       mov      ecx,dword ptr io_base_address
       and       ecx,0fffffffeh
       mov      dword ptr io_base_address,ecx ; 去除 i/o 指示位并保存
 
       mov      ax,0b10ah
       mov      di,3ch
       int          1ah
       jc           findtpc_notfind        ; TPC 卡中断信息
       and              cx,0ffh
       mov      word ptr interrupt_line,cx     ; 去除 interrupt 其它指示位并保存
 
    mov      dx,offset io9054baseaddress     ; 显示 i/o 提示信息
       mov      ah,09h
       int          21h
   mov      ax,word ptr io_9054base_address
       call        dispword                   ; 显示 i/o 基地址
 
       mov      dx,offset iobaseaddress              ; 显示 i/o 提示信息
       mov      ah,09h
       int          21h
       mov      ax,word ptr io_base_address
       call        dispword                   ; 显示 i/o 基地址
 
       mov      dx,offset intnumber              ; 显示 interrupt 提示信息
       mov      ah,09h
       int          21h
       mov      ax,word ptr interrupt_line
       call        dispword                   ; 显示中断号
 
       mov      dx,offset enter_return           ; 加回车符 , 换行符
       mov      ah,09h
       int          21h
       popfd
       popad
       ret
findtpc_notfind:
       mov     dx,offset pcicardnotfind              ; 显示未找到 tpc 卡提示信息
       mov     ah,09h
       int         21h
       mov     ax,4c00h
       int         21h              ; 退出
findtpc               endp
 
dispword    proc     near             ; 显示子程序
       push    dx
       push    cx
       push     bx
       mov     cx,4
       mov     bx,16
dispword_loop1:
       push    ax
       push    cx
       sub      bx,4
       mov     cx,bx
       shr       ax,cl
       and      al,0fh                         ; 首先取低四位
       mov     dl,al
       cmp     dl,9                             ; 判断是否 <=9
       jle         dispword_num        ; 若是则为 '0'-'9',ASCII 码加 30H
       add      dl,7                             ; 否则为 'A'-'F',ASCII 码加 37H
dispword_num:
       add      dl,30h
       mov     ah,02h ; 显示
       int         21h
       pop      cx
       pop      ax
       loop     dispword_loop1
       pop      bx
       pop      cx
       pop      dx
       ret                                      ; 子程序返回
dispword    endp
code    ends
end      start
实验心得:
       本实验的难点在 LED 的显示上,由于在此之前,我一直认为 LED 的显示是由 8255A 驱动,所以一开始做这个程序时,我首先想到的是利用 8255A 。但是结合实验箱上的 LED 我才发现这样的方法行不同。于是,再回头认真的学习了一下 LED 的显示原理。才发现 LED 的显示其实很简单。只要往数据端口送数据,再往位选端口送入位选代码就可以了。这下程序流程变得豁然开朗。另外,在设计的时候,我和其他同学讨论了手动中断信号的种种产生方式,最终发现用开关直接与总线插槽上的 IRQ2 直接相连时最简单的方法!本实验的一些预处理操作和有关 TPC 实验板的初始化、后处理,都是结合平时实验的程序,在此基础上修改完成的。经过小组成员的一致努力,我们圆满的完成了这次的实验任务!经过此次实验,我体验了从实践到学习再到实践的过程的乐趣。
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值