东南大学微机原理第七次实验报告

《微机实验及课程设计》

实验报告

实验七 中断8255方式1

                  

姓    名:         学    号:    

专    业:  仪器科学与工程学院  实 验 室:计算机硬件技术   

实验时间: 201465日报告时间: 2014611

评定成绩:                    审阅教师:                  

一、           实验目的

1、掌握PC机中断处理系统的基本原理。

2、学会编写中断服务子程序。

3、掌握8255工作方式1时的使用及编程。

4、学会编写中断服务子程序。

二、           实验内容

1、必做内容

7-1、直接用手动产生单脉冲作为中断请求信号,要求每按一次开关产生中断一次,在屏幕上显示一次“TPC   pci  card  interrupt:”,冒号后面添加已经中断的次数,中断10次后程序退出。

2、选做内容

7-2、(输出)每按一次单脉冲产生一个正脉冲使8255产生一次中断,让CPU进行一次中断服务:依次输出01H、02H、04H、08H、10H、20H、40H、80H使L0~L7依次发光,中断8次结束。

7-3、(输入)每按一次单脉冲产生一个正脉冲使8255产生一次中断,让CPU进行一次中断服务:读取逻辑开关预制的ASCII码,在屏幕上显示其对应的字符,中断8次结束。

三、实验原理

1、PC机用户可使用的硬件中断只有可屏蔽中断,由8259中断控制器管理。中断控制器用于接收外部的中断请求信号,经过优先级等处理后向CPU发出可屏蔽中断请求。IBMPC/XT机中有一片8259中断控制器对外可以提供8个中断源。

2、这8个中断源的中断请求信号线IRQ0~IRQ7在主机的62线ISA总线插座中可以引出,系统已经设定为中断请求信号为边沿触发、普通结束方式(用户不需对8259再进行初始化)。

3、对于PC/AT及286以上的微机内有扩展了一片8259中断控制,IRQ2用于两片8259的级连,对外提供16个中断源。

4、PCI总线中的中断线只有四根,INTA#、INTB#、INTC#、INTD#,它们需要通过P&P的设置来和某一根中断相连才能进行中断申请。

20##-06-01_16-46-00-00020##-06-01_16-44-54-843

四、编程提示

1、由于TPC卡使用9054芯片连接微机,而9054的驱动程序影响直写9054芯片的控制寄存器,中断实验要在纯DOS环境下运行。纯DOS环境要在开机时,出现命令行的情况下选择由虚拟启动软盘启动选项。

2、由于TPC卡使用PCI总线,所以分配的中断好每台微机都不相同,编程时先要运行PORTR.EXE程序获得本机的中断向量号。

3、PC/XT机的主8259的地址是20H、21H,从8259的地址是0A0H、0A1H。

4、数据段内容的修改

         int_vect    equ   071h;中断向量号

      irq_mask_2_7    equ   11111011b;主片中断掩码

    irq_mask_9_15 equ    11111101b ;从片中断掩码

    ioport_cent  equ  0d800h ;9054芯片的io地址

当中断源为IRQ9时,程序如上面所示,当本机的中断向量后,应对相应的部分进行修改

五、实验接线

20##-06-01_16-33-28-000中断IRQ接单脉冲

20##-06-04_09-28-55-375                                               

20##-06-04_09-32-41-875

六、实验源程序和流程图:

20##-06-01_17-11-36-703     20##-06-01_17-13-01-781

7-1

data segment

int_vect equ 0bh;先要查询中断向量号,现在写的是IRQ3

irq_mask_2_7 equ 11110111b;这一行以及下一行设置参考实验书P56

irq_mask_9_15 equ 11111111b;

ioport_cent equ 0ec00h;这个地址查询方式参考ppt

csreg dw ?

ipreg dw ?;旧中断保存

irq_times dw ?;中断计数,在中断处理程序中设置,只要设置初始值,然后会自动减一

num dw ?

msg1 db 0dh,0ah,'TPC pci card interrupt:','$'

msg2 db 0dh,0ah,'Press any key to exit.',0dh,0ah,'$'

data ends

;-------------------------------------------------------

stacks segment stack

db 100 dup(?)

stacks ends

;-------------------------------------------------------

;---------------------------------------------------------

code segment

assume cs:code,ds:data,ss:stacks,es:data

main proc far

start:   cli;清中断标志

     mov ax,data

     mov ds,ax

     mov es,ax

     mov ax,stacks

     mov ss,ax

;到这里是初始化各段

     mov dx,ioport_cent+68h

     in ax,dx

     or ax,0900h

     out dx,ax

;到这里是设置中断使能

     mov al,int_vect

     mov ah,25h

     int 21h

     mov ax,es

     mov csreg,ax;附加段基址

     mov ipreg,bx

;到这里是保存原中断向量,参见实验书P197

     mov ax,cs

     mov ds,ax

     mov dx,offset int_proc

     mov al,int_vect

     mov ah,35h

     int 21h

;到这里是设置新中断向量

     in al,21h;先设置主片掩码,从片为0A0H、0A1H

     and al,irq_mask_2_7   

     out 21h,al

     in al,0a1h

     and al,irq_mask_9_15

     out 0a1h,al

;到这里是设置主从两片中断掩码

;---------------------------前面全部属于初始化

     mov ax,data

     mov ds,ax

     mov dx,offset msg2

     mov ah,09h

     int 21h 

     mov irq_times,10;设置中断计数初值为10

     mov num,10

     sti;使能中断标志

;---------------------------至上方完成基本任务

loop1:   cmp irq_times,0

     jz exit

     mov ah,1

     int 16h

     jnz exit

     call disp;没满十次且无键按下,则继续循环

     jmp loop1

exit:    cli

;-------------------下面一大段都是退出时做的恢复工作,基本不需要改动

     mov bl,irq_mask_2_7

     not bl

     in al,21h

     or al,bl

     out 21h,al

     mov bl,irq_mask_9_15

     not bl

     in al,0a1h

     or al,bl

     out 0a1h,al;至此为恢复中断掩码

     mov dx,ipreg

     mov ax,csreg

     mov ds,dx

     mov ah,25h;设置中断向量,详见实验书本附录195

     mov al,int_vect

     int 21h;至此为恢复中断向量

     mov dx,ioport_cent+68h

     in ax,dx

     and ax,0f7ffh

     out dx,ax

;至此为关闭TPC中断,退出工作结束

     mov ah,4ch

     int 21h

     main endp;主程序结束

;---------------------------------------------------

;---------------------------------------------------

disp proc near ;显示子程序

     push ds

     push dx;询问老师为什么不能用PUSHA

     push cx

     push ax

     mov cx,irq_times

     mov ax,cx

     mov bx,num

     cmp ax,bx

     jz disp1

     mov ax,data

     mov ds,ax

     mov dx,offset msg1

     mov ah,09h   

     int 21h

     and cx,00ffh

     mov dl,30h

     add dl,10

     sub dl,cl;这四行用于显示一位数字ASCII码,10的时候会出问题,再说

     mov ah,02h

     int 21h

     mov num,cx

disp1:   pop ax

     pop cx

     pop dx

     pop ds

     ret

     disp endp

;---------------------------------------------------

int_proc proc far;中断处理程序

     push ax

     push cx;询问老师为什么不能用PUSHA

     push dx

     push ds

     mov ax,data

     mov ds,ax

     dec irq_times

     mov cx,0ffffh

loop2:   nop

     loop loop2;中断延时

     pop ds

     pop dx

     pop cx

     mov al,20h  ;中断结束命令,咨询老师

     out 0a0h,al

     out 20h,al

     pop ax

     iret

int_proc endp

code ends

     end start

7-2

data segment

ioport equ 0ec00h-280h

io8255a equ ioport+288h

io8255c equ ioport+28ah

io8255k equ ioport+28bh

int_vect equ 0bh;先要查询中断向量号,现在写的是IRQ3

irq_mask_2_7 equ 11110111b;这一行以及下一行设置参考实验书P56

irq_mask_9_15 equ 11111111b;

ioport_cent equ 0ec00h;这个地址查询方式参考ppt

csreg dw ?

ipreg dw ?;旧中断保存

irq_times dw ?;中断计数,在中断处理程序中设置,只要设置初始值,然后会自动减一

num dw ?

msg1 db 0dh,0ah,'TPC pci card interrupt:','$'

msg2 db 0dh,0ah,'Press any key to exit.',0dh,0ah,'$'

led db 01h

data ends

;-------------------------------------------------------

stacks segment stack

db 100 dup(?)

stacks ends

;-------------------------------------------------------

;---------------------------------------------------------

code segment

assume cs:code,ds:data,ss:stacks,es:data

main proc far

start:   cli;清中断标志

     mov ax,data

     mov ds,ax

     mov es,ax

     mov ax,stacks

     mov ss,ax

     mov dx,io8255k

     mov al,0a0h;8255控制字写入,方式1,A口输出

     out dx,al

;到这里是初始化各段,以及8255初始化

     mov dx,ioport_cent+68h

     in ax,dx

     or ax,0900h

     out dx,ax

;到这里是设置中断使能

     mov al,int_vect

     mov ah,35h

     int 21h

     mov ax,es

     mov csreg,ax;附加段基址

     mov ipreg,bx

;到这里是保存原中断向量,参见实验书P197

     mov ax,cs

     mov ds,ax

     mov dx,offset int_proc

     mov al,int_vect

     mov ah,35h

     int 21h

;到这里是设置新中断向量

     in al,21h;先设置主片掩码,从片为0A0H、0A1H

     and al,irq_mask_2_7   

     out 21h,al

     in al,0a1h

     and al,irq_mask_9_15

     out 0a1h,al

;到这里是设置主从两片中断掩码

;---------------------------前面全部属于初始化

     mov ax,data

     mov ds,ax

     mov dx,offset msg2

     mov ah,09h

     int 21h 

     mov irq_times,8;设置中断计数初值为10

     mov num,8

     sti;使能中断标志

;---------------------------至上方完成基本任务

loop1:   cmp irq_times,0

     jz exit

     mov ah,1

     int 16h

     jnz exit

     call disp;没满十次且无键按下,则继续循环

     jmp loop1

exit:    cli

;-------------------下面一大段都是退出时做的恢复工作,基本不需要改动

     mov bl,irq_mask_2_7

     not bl

     in al,21h

     or al,bl

     out 21h,al

     mov bl,irq_mask_9_15

     not bl

     in al,0a1h

     or al,bl

     out 0a1h,al;至此为恢复中断掩码

     mov dx,ipreg

     mov ax,csreg

     mov ds,dx

     mov ah,25h;设置中断向量,详见实验书本附录195

     mov al,int_vect

     int 21h;至此为恢复中断向量

     mov dx,ioport_cent+68h

     in ax,dx

     and ax,0f7ffh

     out dx,ax

;至此为关闭TPC中断,退出工作结束

     mov ah,4ch

     int 21h

     main endp;主程序结束

;---------------------------------------------------

;---------------------------------------------------

disp proc near ;显示子程序

     push ds

     push dx;询问老师为什么不能用PUSHA

     push cx

     push ax

     mov cx,irq_times

     mov ax,cx

     mov bx,num

     cmp ax,bx

     jz disp1

     mov ax,data

     mov ds,ax

     mov dx,offset msg1

     mov ah,09h   

     int 21h

     and cx,00ffh

     mov dl,30h

     add dl,8

     sub dl,cl;这四行用于显示一位数字ASCII码,10的时候会出问题,再说

     mov ah,02h

     int 21h

     mov num,cx

disp1:   pop ax

     pop cx

     pop dx

     pop ds

     ret

     disp endp

;---------------------------------------------------

int_proc proc far;中断处理程序

     push ax

     push cx;询问老师为什么不能用PUSHA

     push dx

     push ds

     mov ax,data

     mov ds,ax

     dec irq_times

     mov al,led

     mov dx,io8255a

     out dx,al

     rol al,1;循环左移,实现要求

     mov led,al;保存下一次结果       

     mov cx,0ffffh

loop2:   nop

     loop loop2;中断延时

     pop ds

     pop dx

     pop cx

     mov al,20h  ;中断结束命令,咨询老师

     out 0a0h,al

     out 20h,al

     pop ax

     iret

int_proc endp

code ends

     end start

 

第二篇:东南大学微机原理第五次实验报告

《微机实验及课程设计》

实验报告

实验五 8255并行输入输出

                  

姓    名:        学    号:     

专    业:  仪器科学与工程学院  实 验 室:计算机硬件技术   

实验时间: 20140522日报告时间: 20140528

评定成绩:                    审阅教师:                  

一、实验目的

1、掌握8255方式0的工作原理及使用方法,利用直接输入输出进行控制显示。

2、掌握8段数码管的动态刷新显示控制。

二、实验内容

1、8段数码管静态显示: 编程从键盘输入一位十进制数字(0~9),在数码管上显示出来。

2、8段数码管动态显示:在两个数码管上同时显示不同的两位数字或字母,保持不变直至退出。(如56或7f,参考程序p69)

3、静态显示:用逻辑电平开关预置某个数字(0~9)的ASCII码,将该数据用8255的C口读入,并用A口输出,并在数码管显示出来;如果预置的ASCII码不是数字(0~9),数码管显示E字母。

4、动态显示:在两个数码管上滚动循环显示不同的0~f字符。(即开始时两个数码管显示01,12,23,34 ··f0,一直循环直至退出)(选作)

   

   

   

三、实验台的数码管显示电路

 

四、入实验接线图

    1、静态显示

                                               

                                         PA0~PA6分别接数码管的a~g

                                         PC0~PC7分别逻辑电平开关的K0~K7

                                         位选端S1接+5V

                                         位选端S0接地

                                         数码管dp端接地

2、动态显示

 

                                                             PA0~PA6分别接数码管的a~g

                                                       位选端S0 、S1接8255C口的PC0、PC1

                                                   

五、源代码

  1.input1.asm

data  segment

ioport            equ 0b800h-0280h

io8255a          equ ioport+288h

io8255b          equ ioport+28bh

led  db 3fh,06h,5bh,4fh,66h,6dh,7dh,07h,7fh,6fh

string  db  0dh,0ah,'Input a num (0--9h):',0dh,0ah,'$'

data ends                                                                    

stacks segment stack

       db 100 dup (?)

stacks ends

code segment

       assume cs:code,ds:data,ss:stacks

start: mov ax,stacks

    mov ss,ax

    mov ax,data

    mov ds,ax

    mov dx,io8255b         ;使8255的A口为输出方式

    mov ax,80h

    out dx,al

sss: mov dx,offset string       ;显示提示信息

    mov ah,09h

    int 21h

    mov ah,01              ;从键盘接收字符

    int 21h

    cmp al,'0'               ;是否小于0

    jl  exit                ;若是则退出

    cmp al,'9'              ;是否大于9

    jg  exit               ;若是则退出

    sub al,30h              ;将所得字符的ASCII码减30H

    mov bx,offset led        ;bx为数码表的起始地址

    xlat                   ;求出相应的段码

    mov dx,io8255a         ;从8255的A口输出

    out dx,al

    jmp sss                ;转SSS

exit: mov ah,4ch             ;返回DOS

    int 21h

code ends

end start

      2.output.asm

data  segment

ioport    equ 0b800h-0280h ;tpc卡中设备的io地址

io8255a   equ ioport+28ah  ;8255C口地址

io8255b   equ ioport+28bh  ;8255控制寄存器端口地址

io8255c   equ ioport+288h  ;8255A口地址

led  db 3fh,06h,5bh,4fh,66h,6dh,7dh,07h,7fh,6fh ;段码

buffer1  db  5,6          ;存放要显示的个位和十位

bz  dw   ?              ;位码

data ends

stacks segment stack

       db 100 dup (?)

stacks ends

code segment

       assume cs:code,ds:data,ss:stacks

start: mov ax,stacks

    mov ss,ax                                                                                                          

    mov ax,data

    mov ds,ax

    mov dx,io8255b               ;将8255设为A口输出

    mov al,80h

    out dx,al

    mov di,offset buffer1        ;设di为显示缓冲区

loop2:mov bh,02

lll:   mov byte ptr bz,bh

     push di

     dec di

     add di, bz

     mov bl,[di]                  ;bl为要显示的数

     pop di

     mov al,0

     mov dx,io8255a

     out dx,al

     mov bh,0

     mov si,offset led            ;置led数码表偏移地址为SI

     add si,bx                    ;求出对应的led数码

     mov al,byte ptr [si]

     mov dx,io8255c               ;自8255A的口输出

     out dx,al

     mov al,byte ptr bz           ;使相应的数码管亮

     mov dx,io8255a

     out dx,al

     mov cx,3000

delay:loop delay                   ;延时

     mov bh,byte ptr bz

     shr bh,1

     jnz lll

     mov dx,0ffh

     mov  ah,06

     int  21h

     je  loop2                    ;有键按下则退出

     mov dx,io8255a

     mov al,0                     ;关掉数码管显示

     out dx,al

     mov ah,4ch                   ;返回

     int 21h

code ends

end start

3.input2.asm

data  segment

ioport                equ 0b800h-0280h  ;tpc卡中设备的io地址

io8255a             equ ioport+288h   ;8255A口地址  

io8255b             equ ioport+28bh   ;8255控制寄存器端口地址

io8255c             equ ioport+28ah   ;8255C口地址

led      db        3fh,06h,5bh,4fh,66h,6dh,7dh,07h,7fh,6fh,79h

data ends

stacks segment stack

       db 100 dup (?)

stacks ends

code segment

       assume cs:code,ds:data,ss:stacks

main proc far

start:        mov ax,stacks

         mov ss,ax

        mov ax,data

         mov ds,ax

         mov dx,io8255b            ;设8255为C口输入,A口输出

         mov al,8bh

         out dx,al

inout:  mov dx,io8255c            ;从C口输入一数据

         in al,dx

         cmp al,30h                ;是否小于0

         jl  error                 ;若是则显示E

         cmp al,39h                ;是否大于9

         jg  error                 ;若是则显示E

        sub al,30h

        jmp show 

error:  mov al,0gfah                ;显示E

show:   mov bx,offset led         ;bx为数码表的起始地址

         xlat                      ;求出相应的段码

        mov dx,io8255a            ;从A口输出刚才自C口所输入的数据

         out dx,al              

         mov dl,0ffh               ;判断是否有按键

         mov ah,06h

         int 21h

         jz inout                 ;若无,则继续自C口输入,A口输出

         mov ah,4ch               ;否则返回DOS

         int 21h

main endp

code ends

           end start

六、思考与总结

本次实验中遇到的主要问题有:

1、设备损坏

本次实验中用到两片数码管皆各有损坏,表现为各有几处一直处于亮着的状态。导致显示时出现了差错。一开始以为是程序编写出错,后来经检查程序无误,修改参数后发现是数码管的问题。

解决方案:更换要显示的字符,避开坏掉的几处。

2、动态显示时显示数字不稳定

这主要是因为延迟时间过短,导致左右两根数码管亮灭时间不一致,被人眼识别到,反映出来为两根数码管亮度不一致。

解决方案:更改延迟时间,适当加长。

相关推荐