当前位置:文档之家› 保护模式下的8259A 芯片编程及中断处理探究(下)

保护模式下的8259A 芯片编程及中断处理探究(下)

保护模式下的8259A 芯片编程及中断处理探究(下)
保护模式下的8259A 芯片编程及中断处理探究(下)

保护模式下的8259A芯片编程及中断处理探究

(下)Version: 0.01

谢煜波

Email: xieyubo@https://www.doczj.com/doc/bf16750250.html,

2004年4月

在上篇中,我们详细讲述了保护模式下对于中断的基本原理已及对可编程中断控制器8259A的编程方法。如果说上一篇更偏重有原理及特定的硬件编程方法,那么本篇就会偏软一点,将详细描述怎样编写操作系统中的中断处理程序,并将通过pyos进行验证。在此篇中,你将会详细了解到操作系统是怎样处理中断的,中断处理程序是怎样编写的,操作系统又是怎样调用中断处理程序的。希望本篇可以使你对上述问题有个比较清晰的认识。

本篇是独立的,当然,如果你阅读了上篇,那么对于理解本篇中所描述的内容无疑是有巨大帮助的。

pyos是一个实验性的架构系统,阅读本篇之后,你可以尝试着改动pyos中的中断处理部份,这样你将更可以详细而深入的理解多重中断,现场保护等内容,本篇在最后也将对于怎样进行这样的自我实验做些许描述。如果你在学习“操作系统”或“组成原理”的过程中,对于书中描述的内容感到不太直观,你可以试试用pyos去验证你所学习的知识。

再次声明:此文只是我在进行操作系统实验过程中的一点心得体会,记下来,避免自己忘记。对于其中可能出现的错误,欢迎你来信指证。

一、操作系统中断服务概述

现代计算机如果从纯硬件角度,我个人更倾向于将它理解为是利用的一种所谓的“中断驱动”机制,就相当于我们常常津津乐道的Windows的“消息驱动”机制一样。CPU在正常情况下按顺序执行程序,一旦有外部中断到来,CPU将会中断现行程序的运行,转到中断服务程序进行中断处理,当中断处理完成之后,CPU再回到原来执行程序被中断的地方继续执行,并等待下一个中断的来临。

CPU需要响应的中断有很多种,比如键盘中断、磁盘中断、CPU时钟中断等等,每种中断的功能都是不同的,而所需要的中断服务程序也是不同的,CPU又是怎么识别这种种不同的中断的呢?

二、中断描述符表及中断描述符

在上一篇中,我们知道了CPU是通过给这些不同的中断分配不同的中断号来识别的。一种中断就对应一个中断号,而一个中断号就对应一个中断服务程序,这样,当有中断到来的时候,CPU就会识别出这个中断的中断号,并将这个中断号作为一个索引,在一张表中查找此索引号对应的一个入口地址,而这个入口地址就是中断服务程序的入口地址,CPU 取得入口地址后,就跳转到这个地址所指示的程序处运行中断服务程序。

这张存放不同中断服务程序的表在系统中常常称为“中断向量表”。在保护模式下也常常称为“中断描述符表”(IDT),这个表中的每一项就是一个中断描述符,每一个中断描述符都包含中一个中断服务程序的地址,CPU通过将中断号做为索引值取得的就是这样一个“中断描述符”,通过“中断描述符”,CPU就可以得到中断服务程序的地址了,下面,我们就来看看中断描述符的结构:

上图就是一个“中断描述符”的结构,其中P位是存在为,置1的时候就是这个描符述可以被使用;DPL是特权级,可以指定为0~3中的一级;保留位是留给Inter将来用的,在现阶段,我们只需要简单的将其置零就可以;偏移量总共是32位,它表示一个中断服务程序在内存中的位置。由于保护模式下,内存的寻址是由段选择符与偏移量指定的,所以在中断描述符中也分别设定了段选择符与偏移量位,他们共同决定了一个中断服务程序在内存中的位置。(有关保护模式下内存的寻址方面的描述,可以参考《操作系统引导探究》一文。)在前面我们描述了,一个中断描述符是放在一张中断描述符表中的,而中断号就是中断描述符在中断描述符表中的索引或说下标。那么系统又怎么知道中断描述符表是放在什么地方的呢?这在系统中是通过一个称之为“中断描述符表寄存器”(IDTR)实现的,这个寄存器中就存放了“中断描述符表”在内存中的地址。下面,我们也来看看这个寄存器的结构:

(图二)

下面,我们可以比较完整的来欣赏一下CPU处理中断的流程:

(图三)

三、pyos中的中断系统实验

下面,我们将以pyos做为例子,用它来实验操作系统中中断系统的实现。当然,在实际的操作系统中这也许是非常复杂的,但我们现在通过pyos也完全可以进行这样的实验。

在实验正式开始之前,你许要下载本实验所用到的源代码,这可以在我们的网站“纯C论坛”(https://www.doczj.com/doc/bf16750250.html,)“操作系统实验专区”中下载,也可以来信向作者索要。对于实验环境的搭建你也许需要看看“操作系统实验专区”中“When Do We Write Our Chinese Os (1)”对此的描述。

在实验正式开始之前,我们将详细描述一下pyos的文件组织形式。Go~~~

3.1 pyos 的文件组织形式

本实验用到的pyos目前的文件组织如下:“boot.asm”、“setup.asm”这两个文件是操作系统引导文件,他们负责把pyos的内核读入内存,然后转到内核执行。(这方面的内容可以参见《操作系统引导探究》一文。)“kernel.cpp”就是pyos的内核,pyos是用c++开发的,因此它的内核看起来非常简单,也比较有结构,下面就是“kernel.cpp”中的内容:

#include "system.h"

#include "video.h"

extern "C" void Pyos_Main()

{

/* 系统初始化 */

class_pyos_System::Init() ;

class_pyos_Video::ClearScreen() ;

class_pyos_Video::PrintMessage( "Welcome to Pyos :)" ) ;

for(;;);

}

我想,这样的程序也许不用我做什么注释了。“system.h”中定义了一个名为“class_pyos_System”的系统类,用来做系统初始化的工作,“vide.h”中定义了一个名为“class_pyos_Video”的显卡类,它封装了对VGA显卡的操作,从上面的代码中我们可以看见,系统先通过class_pyos_System类的Init()完成系统初始化,然后调用class_pyos_Video类中的ClearScreen()进行清屏,最后用PrintMessage()输出了一条欢迎信息。下面,我就一步一步的来剥开上面看上去很神秘的Init()——系统初始化函数。对于显卡类,你可以参看源代码,本篇中将不进行描述,也许以后我会用专门的一篇来详细描述它。当然,你如果看过“When Do We Write Our Chinese OS (3)”的话,对于显卡类的理解就易容反掌了。

3.2 pyos 的系统初始化

下面,我们来看看 pyos 的系统初始化函数:

#include "interrupt.h"

/* 系统初始化 */

void class_pyos_System::Init()

{

/* 初始化Gdt表 */

InitGdt() ;

/* 初始化段寄存器 */

InitSegRegister() ;

/* 初始化中断 */

class_pyos_Interrupt::Init() ;

是的,他就是这么简单,由于InitGdt与InitSegRegister的内容在《操作系统引导探究》中已经描述过了,这里我们就专注于我们本篇的核心内容——对于中断系统的初始化。

从上面的代码中我们可以看出,系统首先在“interrupt.h”中定义了一个名为“class_pyos_Interrup”的中断类,专门来处理系统的中断部份。然后,系统调用中断类的Init()函数,来进行初始化。呵呵,我们马上就去看看这个中断类的初始化函数到底做了些什么:

/* 初始化中断服务 */

void class_pyos_Interrupt::Init()

{

/* 初始化中断可编程控件器 8259A */

Init8259A() ;

/* 初始化中断向量表 */

InitInterruptTable() ;

/* 许可键盘中断 */

class_pyos_System::ToPort( 0x21 , 0xfd ) ;

/* 汇编指令,开中断 */

__asm__( "sti" ) ;

}

我想,对于这样自说明式的代码,解释是多余的,我们还是抓紧时间来看看它首先是怎样初始化 8259A 的吧:

/* 初始化中断控制器 8259A */

void class_pyos_Interrupt::Init8259A()

{

// 给中断寄存器编程

// 发送 ICW1 : 使用 ICW4,级联工作

class_pyos_System::ToPort( 0x20 , 0x11 ) ;

class_pyos_System::ToPort( 0xa0 , 0x11 ) ;

// 发送 ICW2,中断起始号从 0x20 开始(第一片)及 0x28开始(第二片)

class_pyos_System::ToPort( 0x21 , 0x20 ) ;

class_pyos_System::ToPort( 0xa1 , 0x28 ) ;

// 发送 ICW3

class_pyos_System::ToPort( 0x21 , 0x4 ) ;

class_pyos_System::ToPort( 0xa1 , 0x2 ) ;

// 发送 ICW4

class_pyos_System::ToPort( 0x21 , 0x1 ) ;

class_pyos_System::ToPort( 0xa1 , 0x1 ) ;

// 设置中断屏蔽位 OCW1 ,屏蔽所有中断请求

class_pyos_System::ToPort( 0x21 , 0xff ) ;

class_pyos_System::ToPort( 0xa1 , 0xff ) ;

从上面的代码可以看出程序是通过向 8259A 发送4个ICW对8259A进行初始化的。其中ToPort是class_pyos_System类中定义的一个成员函数,它的声明如下:

/* 写端口 */

void class_pyos_System::ToPort( unsigned short port , unsigned char data ) OK,好像又不需要我多解释了,当然,你也许会问,为什么会放送这几个值的数据,而不是其它值的数据。对于这个问题,因为在“上篇”中已经详细描述了,这里就不再浪费大家的时间了。:)

3.3 初始化 pyos 的中断向量表

从中断初始化的代码中我们可以清楚的看见,pyos在进行完8259A的初始化后,调用InitInterruptTable()对中断向量表进行了初始化,这可是本篇的核心内容,我们这就来看看这个核心函数:

/* 中断描述符结构 */

struct struct_pyos_InterruptItem{

unsigned short Offset_0_15 ; // 偏移量的0~15位

unsigned short SegSelector ; // 段选择符

unsigned char UnUsed ; // 未使用,须设为全零

unsigned char Saved_1_1_0 : 3 ; // 保留,需设为 110

unsigned char D : 1 ; // D 位

unsigned char Saved_0 : 1 ; // 保留,需设为0

unsigned char DPL : 2 ; // 特权位

unsigned char P : 1 ; // P 位

unsigned short Offset_16_31 ; // 偏移量的16~31位

} ;

/* IDTR所用结构 */

struct struct_pyos_Idtr{

unsigned short IdtLengthLimit ;

struct_pyos_InterruptItem* IdtAddr ;

} ;

static struct_pyos_InterruptItem m_Idt[ 256 ] ; // 中断描述符表项

static struct_pyos_Idtr m_Idtr ; // 中断描述符寄存器所用对象

extern "C" void pyos_asm_interrupt_handle_for_default() ; // 默认中断处理函数

/* 初始化中断向量表 */

void class_pyos_Interrupt::InitInterruptTable()

{

/* 设置中断描述符,指向一个哑中断,在需要的时候再填写 */

struct_pyos_InterruptItem tmp ;

tmp.Offset_0_15 = ( unsigned int )pyos_asm_interrupt_handle_for_default ;

tmp.Offset_16_31 = ( unsigned int )pyos_asm_interrupt_handle_for_default >> 16 ;

tmp.SegSelector = 0x8 ; // 代码段

tmp.UnUsed = 0 ;

tmp.P = 1 ;

tmp.DPL = 0 ;

tmp.Saved_1_1_0 = 6 ;

tmp.Saved_0 = 0 ;

tmp.D = 1 ;

for( int i = 0 ; i < 256 ; ++i ){

m_Idt[ i ] = tmp ;

}

m_Idtr.IdtAddr = m_Idt ;

m_Idtr.IdtLengthLimit = 256 * 8 - 1 ; // 共 256项,每项占8个字节

// 内嵌汇编,载入 ldt

__asm__( "lidt %0" : "=m"( m_Idtr ) ) ; //载入GDT表

}

程序首先说明了两个结构,一个用来描述中断描述符,一个用来描述中断描述符寄存器。大家可以对照前面的描述看看这两个结构中的成员分别对应硬件系统中的哪一位。

之后,程序建立了一个中断描述符数组m_Idt,它共有256项,这是因为CPU可以处理256个中断。还建立了一个中断描述符寄存器所用的对象。随后,程序开始为这些变量赋值。

从程序中我们可以看出,pyos现在是将每个中断描述符都设成一样的,均指向一个相同的中断处理程序:pyos_asm_interrupt_handle_for_default(),在一个实际的操作系统中,在最初初始化的时候,也常常是这样做的,这个被称之为“默认中断处理程序”的程序通常是一个什么也不干的“哑中断处理程序”或者是一个只是简单报错的处理程序。而要等到实际需要时,才实用相应的处理程序替换它。

程序在建立“中断描述符表”后,用lidt指令将中断描符述表寄存器所用的内容载入了中断描述符寄存器(IDTR)中,对于“中断描述符表”的初始化就完成了,下面我们可以来看看,pyos_asm_interrupt_handle_for_default()这个程序到底做了些什么事:

3.4 中断处理程序的编写

pyos_asm_interrupt_handle_for_default:

;保护现场

pushad

;调用相应的C++处理函数

call pyos_interrupt_handle_for_default

;恢复现场

popad

;告诉硬件中断处理完毕,即发送 EOI 消息

mov al , 0x20

out 0x20 , al

out 0xa0 , al

;返回

iret

这个程序是在一个名为“interrupt.asm”的汇编文件中,显然,它是一个汇编语言写的源程序。为什么这里又要用汇编语言编写而不直接用C++内嵌汇编编写呢,比如写成下面这样:

void pyos_asm_interrupt_handle_for_default()

{

__asm__( "pushad" ) ;

/* do something */

__asm__( "popad" ) ;

__asm__( "iret" ) ;

}

这里我们需要了解这样一个问题。中断服务程序是由CPU直接调用的,随后,它使用iret指令返回,而不想一般的c/c++函数由ret返回。c/c++的编译器在处理c/c++语言的函数的时候,会在这个函数的开头与结尾加上很多栈操作,以支持程序调用,比如上边的代码就有可能被c/c++编译器处理成如下形式:(其中绿色为编译器自行加上的代码)

pusha

pushad

/* do something */

popad

iret

popa

ret

请注意这样一个实事,当程序运行到iret时就返回了,而随后的popa就不会被执行,因此这样就破坏了堆栈,于是,我们就只能通过汇编语言编写中断处理程序。

现在再来看看pyos中用汇编语言写的中断处理程序,首先它用pushad指令把寄存器中的内容压入堆栈,这常常称之为保护现场,因为之后程序需要返回被中断的程序中继续运行,因此这些寄存器中的内容也必须在中断处理程序结束时恢复。保护现场完了之后,它调用了一个c++语言程序pyos_interrupt_handle_for_default(),然后,它弹出原先保存在堆栈中的寄存器的内容,这常常称为恢复现场,随后,它发送了EOI消息通知8259A中断处理完成(关于EOI消息,在“上篇”中有详细描述),最后通过iret返回被中断的程序处继续执行。

晕!原来pyos_asm_interrupt_handle_for_default()只是一个汇编的壳,而真正的处理函数是pyos_interrupt_handle_for_default()!怪不得它会在名字中多个“asm”呢?:),下面,我们不得不来看看真正的中断处理程序做了什么:

extern "C" void pyos_interrupt_handle_for_default()

{

/* 处理中断 */

/* 读 0x60 端口,获得键盘扫描码 */

char ch = class_pyos_System::FromPort( 0x60 ) ;

/* 显示键盘扫描码 */

class_pyos_Video::PrintMessage( ch ) ;

}

yeah!这才是真正的中断处理程序,不过它的内容很简单,就是读键盘的0x60端口,获得键盘的扫描码,然后显示这个扫描码。是不是很简单?:)

3.5 class_pyos_Interrupt::Init()的最后工作

现在让我们重新回到中断类的初始化程序Init()中吧。Init()在完成了8259A及中断描述符表的初始化工作之后,它的工作就也近尾声了。随后,它调用了下面一个程序: /* 许可键盘中断 */

class_pyos_System::ToPort( 0x21 , 0xfd ) ;

这是向8259A发送中断屏蔽字,十六进制fd所对应的二进制为1111 1101,在“上篇”中我们知道了1代表屏蔽,而0代表不屏蔽,因此fd就表示屏蔽了IRQ0、IRQ2~IRQ7,而唯IRQ1没有屏蔽。通过“上篇”我们知道IRQ1是代表的键盘中断,因此这一语句的意思就是屏蔽掉除键盘中断之外的所有中断,也即:只响应键盘中断。最后,程序用sti汇编指令打开了CPU的中断请求功能。

3.6 实验结果

想想我们前面所描述的代码,你现在应当知道了本实验最后所应达到的一个实验结果:pyos起动后,会响应键盘中断,而中断服务程序的功能是输出键盘的扫描码,也就是说如果你敲击键盘的话,你可以看见计算机的屏蔽上输出键盘的扫描码。下面我们就能看看我们的实验是否达到了程序所预期的效果。下面,我们在Virtual PC中启动我们自己的操作系统——pyos:)

我们可以看见,现在pyos已经启动了,现在让我们随便敲击一下键盘:

呵呵,屏幕上出现了方才敲键的扫描码。看来我们程序的目的的确是达到了,不过怎么有两个字符呢?再敲一次试试:)

呵呵,又出来两个字符,看来的确是按一个键发生了两次键盘中断,为什么会这样呢?这个问题留到下一篇再解决吧。:)

3.7 实验的改进

pyos是一个实验系统,开发他的目的就是为了做实验,检验所学,因此,你完全可以用它来进行实验。比如,你可以少屏蔽两个中断,为每个中断指定不同的中断服务程序,以观察多重中断是怎样工作的,中断屏蔽又是怎样起作用的。你还可以用“上篇”所介绍的方法,改变不同中断的优先级,看看中断优先级又是怎样工作的。本实验中的“中断”二字还体现的不明显,但你马上就可以改改,比如在主程序中,不要让它空循环,把原来:for( ;; ) ;

改成:

for( ;; ){

class_pyos_Video( ‘0’ ) ;

}

然后,你再敲击键盘,你就会体会到“中断”二字的含义。可以完成的实验很多,只要你愿意去做,也非常欢迎你能来信与笔者交流。:)

后记:关于pyos

有关pyos实验的心得体会,我已断断续续写了几篇,都在放在自己所维护的纯C论坛上,及哈工大紫丁香BBS的Programming版了。最初只是自己的一个兴趣,写下一点东西也只是为了留了笔记,以利于自己以后查看方便,避免遗忘。没想很多朋友下载看后都很感兴趣,很多朋友都给我发来电子邮件鼓励我把实验继续下去,也给我提出了很多建议,并指点了我实验中很多错误,在此,真诚的向所有关心的朋友表达一种真诚的谢意。也有许多朋友来寻问我开发的进度安排及pyos的定位,以及为什么不用c而要用c++开发的问题。在此,我想简单的描述一下我目前对此一系列问题的看法。

在以前,我对pyos并没有一个很明确的定位,只是做为自己学习的一种兴趣,想到哪儿写到哪儿,而现在虽然也是想到哪儿写到哪儿但我确有一个比较明确的定位了:pyos将是一个给教师及学生使用的实验性操作系统。

pyos并不打算做成一个能实际大众化应用的系统,因为这样的系统Linux、Windows 就已经很好了,还有很多其它非常优秀的系统,pyos是绝不可能达到那样的水准的,而且似乎也没有那样的必要。然而对于适合于中国学生学习操作系统原理来说的操作系统,目前似乎还没有一个很好的这样的系统。我目前还是一个本科学生,对于这一点,我是深有感触的,不论是Linux还是更简单一点的Minix,它们都过于庞大了,而且对于中国学生普遍较低的英文水平来说,阅读代码中的注释与相关的文献资料,都不是一件非常容易的事情。这也就造成了大多数同学在学习操作系统学习组成原理的时候感到一种枯燥,因为他们没有可以实际动手做实验的这样的一种系统。pyos正希望成为这样的角色,通过现代的c++语言,pyos可以有一个更好的结构化的设计,它的各部份都是可以替换的,比如你可以自己写一个中断类或者显卡类能实现你对系统的控制。因此pyos采用了c++来开发,它并没有考虑一种效率性,也没有期望可以夸平台,它的目标就是能在虚拟机下运行、实验的操作系统。另外,一个中国人,且英语极烂的人写的系统是不会在里面加入英文注释的:)。

如果在将来,老师会用pyos给学生做演示,会让学生用pyos做实验,我就心满意足了:)pyos正随着自己的实验的进行,还在不断的编写改进中,离成熟还有十万八千里,我也不知自己是否真能如愿完成这样的一个系统,但我会让自己尽力而为之。

感谢大家,关希望大家继续关心与支持!谢谢!

谢煜波

2004.4.1晚

单片机 实验2-外部中断程序设计-中断按键按下次数计数数码管显示-硬件和程序设计参考

硬件电路参考如下:

程序参考如下: #pragma sfr #pragma interrupt INTP0 LED_INTP0 /* 定义使用INTP0中断,中断函数名LED_INTP0*/ #pragma di /*禁止使用中断功能声明*/ #pragma ei /*允许使用中断功能声明*/ /*数码管编码数组*/ unsigned char LED_light[10]={0x30,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x3F}; unsigned char j=0; /*按键次数变量*/ void hdinit() /*硬件初始化*/ { PM1=0; /*P1口输出数码管字型码,所以设置为输出*/ PU1=0XFF; /*由于P1口直接驱动数码管显示,为增大驱动,设置为内部上拉*/ PM12.0=0; /*P12.0口线要作为中断多功能,设置为输出和内部上拉 */ PU12.0=1; PIF0=0; /*中断请求标志,没有中断请求*/ PMK0=0; /*中断屏蔽标志,允许中断*/ PPR0=1; /*中断优先级,低优先级*/ EGP.0=1; /*与EGN组合,上升沿有效*/ EGN.0=0; } void main (void) { DI(); /*首先做准备,禁止中断*/ IMS=0XCC; IXS=0X00; hdinit(); EI(); /*准备完成,允许中断*/ while(1) { /*啥也不干,就等待中断,仅是在这个实验中使用中断,实际不是这样/* } } __interrupt void LED_INTP0() /*中断函数*/ { P1= LED_light[j]; /*P1赋值,数码管显示相应数值*/ j++; /*按键次数加一*/ if(j==10) /*如果按键次数达到十次,按键计数归0*/ {j=0;} } 思考: 如果用两位数码管,从0—99循环计数又该怎样设计硬件和软件呢?

中断原理应用程序设计

第六章中断原理应用程序设计 6.1 中断系统的基本概念 CPU在处理某一事件A时,发生了另一事件B请求CPU迅速去处理(中断发生);CPU暂时中断当前的工作,转去处理事件B(中断响应和中断服务);待CPU将事件B处理完毕后,再回到原来事件A被中断的地方继续处理事件A(中断返回),这一过程称为中断。 中断源 引起CPU中断的根源,称为中断源。中断源向CPU提出的中断请求。CPU暂时中断原来的事务A,转去处理事件B。对事件B处理完毕后,再回到原来被中断的地方(即断点),称为中断返回。实现上述中断功能的部件称为中断系统(中断机构)。 MCS-51单片机提供了5个中断源,其中两个为外部中断请求源(P3.2)和(P3.3),两个片内定时器/计数器T0和T1的溢出请求中断源TF0(TCON的第5位)和TF1(TCON的第7位),1个片内串口发送或接收中断请求源TI(SCON的第1位)和RI(SCON的第0位)。 中断优先级 同一优先级中的中断申请不止一个时,则有中断优先权排队问题。同一优先级的中断优先权排队,由中断系统硬件确定的自然优先级形成,其排列如所示: 表6-4 MCS-51单片机中断源的自然优先级及入口地址

需要说明的是,为了便于用C语言编写单片机中断程序,C51编译器也支持51单片机的中断服务程序,而且用C语言编写中断服务程序,比用汇编语言方便的多。C语言编写中断服务函数的格式如下: 函数类型函数名(形式参数列表)[interrupt n] [using m] 其中,interrupt后面的n是中断编号,取值范围0~4,;using中的m表示使用的工作寄存器组号(如不声明,则默认用第0组)。 例如,定时器T0的中断函数可用如下方法编写: void Timer(void) interrupt 1 using 0 //定时器T0的中断服务函数,T0的中断编号为1,使用第0组工作寄存器 { ........//中断服务程序 } 6.2 中断系统的控制 定时器/计数器控制寄存器TCON TCON的功能是接收外部中断源(、)和定时器(T0、T1)送来的中断请求信号。字节地址为88H,可以进行位操作。表5-5列出了TCON的格式。 8FH 8EH 8DH 8CH 8BH 8AH 89H 88H TF1 TR1 TF0 TR0 IT0 IT1 IE0 IT0 表6-5 定时器/计数器控制寄存器TCON的格式

《8259中断控制器实验》的实验报告

实验六8259中断控制器实验 6.1 实验目的 (1) 学习中断控制器8259的工作原理。 (2) 掌握可编程控制器8259的应用编程方法。 6.2 实验设备 PC微机一台、TD-PIT+实验系统一套。 6.3 实验内容 1. 单中断应用实验 (1)编写中断处理程序,利用PC机给实验系统分配的中断线,使用单次脉冲单元的KK1+按键模拟中断源,每次PC机响应中断请求,在显示器上显示一个字符。 (2)编写中断处理程序,利用PC机给实验系统分配的中断线,使用单次脉冲单元的KK1+按键模拟中断源,每次PC机响应中断请求,在显示器上显示“Hello”,中断5次后退出。 2.扩展多中断源实验 利用实验平台上8259控制器对扩展系统总线上的中断线INTR进行扩展。编写程序对8259控制器的IR0和IR1中断请求进行处理。 6.4 实验原理 1. 8259控制器的介绍 中断控制器8259A是Intel公司专为控制优先级中断而设计开发的芯片。它将中断源优先级排队、辨别中断源以及提供中断矢量的电路集于一片中,因此无需附加任何电路,只需对8259A进行编程,就可以管理8级中断,并选择优先模式和中断请求方式,即中断结构可以由用户编程来设定。同时,在不需增加其他电路的情况下,通过多片8259A的级连,能构成多达64级的矢量中断系统。它的管理功能包括:1)记录各级中断源请求,2)判别优先级,确定是否响应和响应哪一级中断,3)响应中断时,向CPU传送中断类型号。8259A的内部结构和引脚如图6-1所示。 8259A的命令共有7个,一类是初始化命令字,另一类是操作命令。8259A的编程就是根据应用需要将初始化命令字ICW1-ICW4和操作命令字OCW1-OCW3分别写入初始化命令寄存器组和操作命令寄存器组。ICW1-ICW4各命令字格式如图6-2所示,

汇编语言中断程序设计

汇编语言程序设计实验报告 学院:计算机科学与技术专业:计算机科学与技术班级:计科131

LEA DX,FNAME MOV CX,0 ;语句1 INT 21H JC EXIT MOV FNUM,AX MOV BX,AX ;语句2 MOV CX,100 MOV AH,40H LEA DX ,BUF INT 21H MOV BX,FNUM MOV AH,3EH INT 21H EXIT: MOV AH,4CH INT 21H CODE ENDS END START 使用相应的文本编辑器建立文件,内容如上所示。 2.汇编并运行此程序后,在当前目录建立的文件名是什么其内容是什么 1>汇编: C:\masm> masm lab7; 2>连接: C:\masm> link lab7; 3>运行: C:\masm> lab7 3.若将语句1 改为mov cx,1,则运行情况与前面会有什么区别 4.若将语句1 改为mov cx,2,则运行结果同上会有什么不同并简要说明此语句的作用. 5.若将语句2 改为mov bx,1,则运行结果会有什么不同简要说明则语句的作用. 实验二:编写0 号中断的处理程序,使得在除法溢出发生时,在屏幕中间显示字符串“divide error!”,然后返回到DOS。源程序下: assume cs:code code segment start: mov ax,cs mov ds,ax

mov si,offset do mov ax,0 mov es,ax mov di,200h mov cx,offset doend-offset do ;安装中断例程cld rep movsb mov word ptr es:[0],200h mov word ptr es:[2],0 ;设置中断向量表 mov dx,0ffffh mov bx,1 ;测试一下 div bx mov ax,4c00h int 21h do:jmp short dostart db 'divide error!' dostart: mov ax,0 mov ds,ax mov si,202h mov ax,0b800h mov es,ax mov di,160*12+60 mov cx,13 s: mov al,ds:[si] mov ah,15 mov es:[di],ax inc si inc di inc di loop s mov ax,4c00h int 21h doend:nop code ends end start

定时器中断程序设计实验

实验一定时器/中断程序设计实验 一、实验目的 1、掌握定时器/中断的工作原理。 2、学习单片机定时器/中断的应用设计和调试 二、实验仪器和设备 1、普中科技单片机开发板; 2、Keil uVision4 程序开发平台; 3、PZ-ISP 普中自动下载软件。 三、实验原理 805l 单片机内部有两个 16 位可编程定时/计数器,记为 T0 和 Tl。8052 单片机内除了 T0 和 T1 之外,还有第三个 16 位的定时器/计数器,记为 T2。它们的工作方式可以由指令编程来设定,或作定时器用,或作外部脉冲计数器用。定时器 T0 由特殊功能寄存器 TL0 和 TH0 组成,定时器 Tl 由特殊功能寄存器 TLl 和 TH1 组成。定时器的工作方式由特殊功能寄存器 TMOD 编程决定,定时器的运行控制由特殊功能寄存器 TCON 编程控制。T0、T1 在作为定时器时,规定的定时时间到达,即产生一个定时器中断,CPU 转向中断处理程序,从而完成某种定时控制功能。T0、T1 用作计数器使用时也可以申请中断。作定时器使用时,时钟由单片机内部系统时钟提供;作计数器使用时,外部计数脉冲由 P3 口的 P3.4(或 P3.5)即 T0(或 T1)引脚输入。 方式控制寄存器 TMOD 的控制字格式如下: 低 4 位为 T0 的控制字,高 4 位为 T1 的控制字。GATE 为门控位,对定时器/计数器的启动起辅助控制作用。GATE=l 时,定时器/计数器的计数受外部引脚输入电平的控制。由由运行控制位 TRX (X=0,1)=1 和外中断引脚(0INT 或 1INT)上的高电平共同来启动定时器/计数器运行;GATE=0时。定时器/计数器的运行不受外部输入引脚的控制,仅由 TRX(X=0,1)=1 来启动定时器/计数器运行。 C/-T 为方式选择位。C/-T=0 为定时器方式,采用单片机内部振荡脉冲的 12 分频信号作为时钟计时脉冲,若采用 12MHz 的振荡器,则定时器的计数频率为 1MHZ,从定时器的计数值便可求得定时的时间。 C/-T=1 为计数器方式。采用外部引脚(T0 为 P3.4,Tl 为 P3.5)的输入脉冲作为计数脉冲,当 T0(或 T1)输入信号发生从高到低的负跳变时,计数器加 1。最高计数频率为单片机时钟频率的 1/24。 M1、M0 二位的状态确定了定时器的工作方式,详见表。

单片机_C语言函数_中断函数(中断服务程序)

单片机_C语言函数_中断函数(中断服务程序) 在开始写中断函数之前,我们来一起回顾一下,单片机的中断系统。 中断的意思(学习过微机原理与接口技术的同学,没学过单片机,也应该知道),我们在这里就不讲了,首先来回忆下中断系统涉及到哪些问题。 (1)中断源:中断请求信号的来源。(8051有3个内部中断源T0,T1,串行口,2个外部中断源INT0,INT1(这两个低电平有效,上面的那个横杠不知道怎么加上去))(2)中断响应与返回:CPU采集到中断请求信号,怎样转向特定的中断服务子程序,并在执行完之后返回被中断程序继续执行。期间涉及到CPU响应中断的条件,现场保护,现场恢复。 (3)优先级控制:中断优先级的控制就形成了中断嵌套(8051允许有两级的中断嵌套,优先权顺序为INT0,T0,INT1,T1,串行口),同一个优先级的中断,还存在优先权的高低。优先级是可以编程的,而优先权是固定的。 80C51的原则是①同优先级,先响应高优先权②低优先级能被高优先级中断③正在进行的中断不能被同一级的中断请求或低优先级的中断请求中断。 80C51的中断系统涉及到的中断控制有中断请求,中断允许,中断优先级控制 (1)3个内部中断源T0,T1,串行口,2个外部中断源INT0,INT1 (2)中断控制寄存器:定时和外中断控制寄存器TCON(包括T0、T1,INT0、INT1),串行控制寄存器SCON,中断允许寄存器IE,中断优先级寄存器IP 具体的是什么,包括哪些标志位,在这里不讲了,所有书上面都会讲。 在这里我们讲下注意的事项 (1)CPU响应中断后,TF0(T0中断标志位)和TF1由硬件自动清0。 (2)CPU响应中断后,在边沿触发方式下,IE0(外部中断INT0请求标志位)和IE1由硬件自动清零;在电平触发方式下,不能自动清楚IE0和IE1。所以在中断返回前必须撤出INT0和INT1引脚的低电平,否则就会出现一次中断被CPU多次响应。 (3)串口中断中,CPU响应中断后,TI(串行口发送中断请求标志位)和RI(接收中断请求标志位)必须由软件清零。 (4)单片机复位后,TCON,SCON给位清零。 C51语言允许用户自己写中断服务子程序(中断函数) 首先来了解程序的格式: void 函数名() interrupt m [using n] {} 关键字 interrupt m [using n] 表示这是一个中断函数 m为中断源的编号,有五个中断源,取值为0,1,2,3,4,中断编号会告诉编译器中断程序的入口地址,执行该程序时,这个地址会传个程序计数器PC,于是CPU开始从这里一条一条的执行程序指令。 n为单片机工作寄存器组(又称通用寄存器组)编号,共四组,取值为0,1,2,3 中断号中断源 0 外部中断0 1 定时器0 2 外部中断1 3 定时器1中断 4 串行口中断 (在上一篇文章中讲到的ROM前43个存储单元就是他们,这5个中断源的中断入口地址为: 这40个地址用来存放中断处理程序的地址单元,每一个类中断的存储单元只有8B,显然不

单片机中断实验报告

人的一生要疯狂一次,无论是为一个人,一段情,一段旅途,或一个梦想 ------- 屠呦呦 实验三定时器中断实验 一、实验目的 1、掌握51单片机定时器基本知识; 2、掌握定时器的基本编程方法; 3、学会使用定时器中断。 二、实验内容 1、利用定时器设计一个秒表,计数范围为0—59,并在数码管实时显示。 三、实验设备 PC 机一台、单片机实验箱 主要器件:AT89C52、7SEG-BCD、 四、实验步骤 1、使用Proteus设计仿真原理图; 2、使用Keil设计程序; 3、联合调试仿真。 五、实验流程图 六、实验程序与结果 #include #define uint unsigned int #define uchar unsigned char sbit F=P2^1;

void timer1_init() { TMOD=0x10;//将定时器1设置为工作方式1 TH1=(65536-6000)/256;//定时器每加一时间为1/fsoc,定时时间为1/500 //(1/500)s/(1/3000000)s=6000 TL1=(65536-6000)%256;//fsoc=3000000,所以装入16位定时器中值为65536-6000 EA=1; ET1=1; TR1=1; } void main() { timer1_init(); while(1); } void timer1() interrupt 3 { TH1=(65536-6000)/256;//每次进入中断,重装初值TL1=(65536-6000)%256; F=~F;//每次进入中断P1.1口取反 } #include #define uint unsigned int #define uchar unsigned char sbit F=P2^1; void timer0_init() {TMOD=0x01;//将定时器0设置为工作方式1 TH0=(65536-83)/256;//定时器每加一时间为1/fsoc,定时时间为2Khz,既500us //500us/6us=83.3333 TL0=(65536-83)%256;//fsoc=6000000,所以装入16位定时器中值为65536-83 EA=1; ET0=1; TR0=1; }void main() { timer0_init(); while(1); } void timer0() interrupt 1 { TH0=(65536-83)/256;//每次进入中断,重装初值 TL0=(65536-83)%256; F=~F;//每次进入中断P1.1口取反,表示定时时间到 } #include // 包含51单片机寄存器定义的头文件 #define seg_data P1 #define seg_data2 P3 #define uint unsigned int sbit D1=P2^0; //将D1位定义为P2.0引脚 uint counter=0; unsigned int unit=0,decade=0,avs=0;//time=0;

中断服务程序流程图

第一讲: 第六章I/O接口原理-接口、端口、编址 回顾:微机系统的层次结构,CPU、主机、接口电路及外部设备之间的结构关联,输入/输出的一般概念。 重点和纲要:微机系统主机与外部设备之间的数据传送,包括I/O端口的寻址方式,输入/输出的传送控制方式。 讲授内容: 6. 1 输入/输出数据的传输控制方式 一、输入/输出的一般概念 1.引言 输入/输出是微机系统与外部设备进行信息交换的过程。输入/输出设备称为外部设备,与存储器相比,外部设备有其本身的特点,存储器较为标准,而外部设备则比较复杂,性能的离散性比较大,不同的外部设备,其结构方式不同,有机械式、电动式、电子式等;输入/输出的信号类型也不相同,有数字信号,也有模拟信号;有电信号,也有非电信号;输入/输出信息的速率也相差很大。因此,CPU与外部设备之间的信息交换技术比较复杂。 CPU与外设之间的信息交换,是通过它们之间接口电路中的I/O端口来进行的,由于同一个外部设备与CPU之间所要传送的信息类型不同,方向不同,作用也不一样(例如数据信息、状态信息、控制信息、输入/输出等),所以接口电路中可以设置多个端口来分别处理这些不同的信息。 2.输入/输出端口的寻址方式 微机系统采用总线结构形式,即通过一组总线来连接组成系统的各个功能部件(包括CPU、内存、I/O端口),CPU、内存、I/O端口之间的信息交换都是通过总线来进行的,如何区分不同的内存单元和I/O端口,是输入/输出寻址方式所要讨论解决的问题。

根据微机系统的不同,输入/输出的寻址方式通常有两种形式:(1).存储器对应的输入、输出寻址方式 这种方式又称为存储器统一编址寻址方式或存储器映象寻址方式。 方法:把外设的一个端口与存储器的一个单元作同等对待,每一个I/O端口都有一个确定的端口地址,CPU与I/O端口之间的信息交换,与存储单元的读写过程一样,内存单元与I/O端口的不同,只在于它们具有不同的的地址。优点: ①CPU对I/O端口的读/写操作可以使用全部存储器的读/写操作指令,也可 以用对存储器的不同寻址方式来对I/O端口中的信息,直接进行算术、逻辑运算及循环、移位等操作。 ②内存与外设地址的分配,可以用统一的分布图。 ③不需要专门的输入、输出操作指令。 缺点: ①内存与I/O端口统一编址时,在地址总线根数一定的情况下,使系统中 实际可以直 接寻址的内存单元数减少。 ②一般情况下,系统中I/O端口数远小于内存单元数,所以在用直接寻址方 式来寻址这些端口时,要表示一个端口地址,必须用与表示内存单元地址相同的字节数,使得指令代码较长,相应地读/写执行时间也较长,这对提高系统的运行速度是不利的。 Mortorola公司的M6800CPU等均采用这种寻址I/O端口的方式。 3. CPU与外设之间所传送的信息类型 CPU与I/O端口之间所交换的信息,可以有下列几种类型: ①数据信息:包括数字量、模拟量、开关量等,可以输入、也可以输出 ②状态信息:这是I/O端口送给CPU的有关本端口所对应的外设当前状态 的信息。供CPU进行分析、判断、决策。 ③控制信息:这是CPU送给I/O端口的控制命令,使相应的外部设备完成 特定的操作。 数据信息、状态信息和控制信息是不同类型的信息,它们所起的作用也不一样。但在8086/8088微机系统中,这三种不同类型的信息的输入、输出过程是相同的。为了加以区分,可以使它们具有不同的端口地址,在端口地址相同的情况下,可以规定操作的顺序,或者在输入/输出的数据中设置特征位。

微机接口实验报告-8259中断控制器应用实验

姓名 院专业班 年月日实验内容8259中断控制器实验指导老师 【实验目的】 (1)学习中断控制器8259的工作原理。 (2)掌握可编程控制器8259的应用编程方法。 【试验设备】 PC微机一台、TD-PIT+实验系统一套。 【实验内容】 (1) 编写中断处理程序,利用PC机给实验系统分配的中断线,使用单次脉冲单元的KK1+按键模拟中断源,每次PC机响应中断请求,在显示器上显示一个字符。 (2) 编写中断处理程序,利用PC机给实验系统分配的中断线,使用单次脉冲单元的KK1+按键模拟中断源,每次PC机响应中断请求,在显示器上显示“9”,中断显示6次后退出。 【实验原理】 1. 8259控制器的介绍 中断控制器8259A是Intel公司专为控制优先级中断而设计开发的芯片。它将中断源优先级排队、辨别中断源以及提供中断矢量的电路集于一片中,因此无需附加任何电路,只需对8259A进行编程,就可以管理8级中断,并选择优先模式和中断请求方式,即中断结构可以由用户编程来设定。同时,在不需增加其他电路的情况下,通过多片8259A的级连,能构成多达64级的矢量中断系统。它的管理功能包括:1)记录各级中断源请求,2)判别优先级,确定是否响应和响应哪一级中断,3)响应中断时,向CPU传送中断类型号。8259A的内部结构和引脚如图6-1所示。 8259A的命令共有7个,一类是初始化命令字,另一类是操作命令。8259A的编程就是根据应用需要将初始化命令字ICW1-ICW4和操作命令字OCW1- OCW3分别写入初始化命令寄存器组和操作命令寄存器组。ICW1-ICW4各命令字格式如图6-2所示,OCW1-OCW3各命令字格式如图6-3所示,其中OCW1用于设置中断屏蔽操作字,OCW2用于设置优先级循环方式和中断结束方式的操作命令字,OCW3用于设置和撤销特殊屏蔽方式、设置中断查询方式以及设置对8259内部寄存器的读出命令。 图6-1 8259内部结构和引脚图

单片机中断实验报告

实验三定时器中断实验 一、实验目的 1、掌握51单片机定时器基本知识; 2、掌握定时器的基本编程方法; 3、学会使用定时器中断。 二、实验内容 1、利用定时器设计一个秒表,计数范围为0—59,并在数码管实时显示。 三、实验设备 PC 机一台、单片机实验箱 主要器件:AT89C52、7SEG-BCD、 四、实验步骤 1、使用Proteus设计仿真原理图; 2、使用Keil设计程序; 3、联合调试仿真。 五、实验流程图 六、实验程序与结果 #include #define uint unsigned int #define uchar unsigned char sbit F=P2^1; void timer1_init() 开始 设置显示初值启动定时器 判断是否到59 继续 是 否

{ TMOD=0x10;//将定时器1设置为工作方式1 TH1=(65536-6000)/256;//定时器每加一时间为1/fsoc,定时时间为1/500 //(1/500)s/(1/3000000)s=6000 TL1=(65536-6000)%256;//fsoc=3000000,所以装入16位定时器中值为65536-6000 EA=1; ET1=1; TR1=1; } void main() { timer1_init(); while(1); } void timer1() interrupt 3 { TH1=(65536-6000)/256;//每次进入中断,重装初值TL1=(65536-6000)%256; F=~F;//每次进入中断P1.1口取反 } #include #define uint unsigned int #define uchar unsigned char sbit F=P2^1; void timer0_init() {TMOD=0x01;//将定时器0设置为工作方式1 TH0=(65536-83)/256;//定时器每加一时间为1/fsoc,定时时间为2Khz,既500us //500us/6us=83.3333 TL0=(65536-83)%256;//fsoc=6000000,所以装入16位定时器中值为65536-83 EA=1; ET0=1; TR0=1; }void main() { timer0_init(); while(1); } void timer0() interrupt 1 { TH0=(65536-83)/256;//每次进入中断,重装初值 TL0=(65536-83)%256; F=~F;//每次进入中断P1.1口取反,表示定时时间到 } #include // 包含51单片机寄存器定义的头文件 #define seg_data P1 #define seg_data2 P3 #define uint unsigned int

Windows 中断程序设计(一)

Windows 中断程序设计(一) 摘要该文探讨Windows3.1的中断机制,并结合DPMI接口给出一种中断程序设计方法,以越过系统和应用程序的消息队列,处理外部实时事件。 一、前言 Windows提供强大的功能以及友好的图形用户界面(GUI),使得它不仅广泛的用作管理事务型工作的支持平台,也被工业领域的工程人员所关注。但Windows3.1并非基于优先级来调度任务,无法立即响应外部事件中断,也就不能满足工业应用环境中实时事件处理和实时控制应用的要求。因此,如何在Windows环境中处理外部实时事件一直是技术人员尤其是实时领域工程人员所关注的问题。目前已有的方法大都采用内挂实时多任务内核的方式,如Windows下的实时控制软件包FLX等,而iRMX实时操作系统则把Windows3.1当作它的一个任务来运行。对于大型的工程项目,开发人员可采用购买实时软件然后集成方式。 对中小项目,从投资上考虑就不很经济。如何寻找一种简明的方法来处理外部实时事件依然显得很必要。 本文首先阐述Windwos的消息机制及中断机制,然后结合DPMI接口,给出一种保护模式下中断程序的设计方法,以处理外部实时事件。经实际运行结果表明,该方法具有简洁、实用、可靠的特点,并同样可运行于Win95。 二、Windows的消息机制 Windows是一消息驱动式系统,见图1。Windows消息提供了应用程序

与应用程序之间、应用程序与Windows系统之间进行通讯的手段。应用程序要实现的功能由消息来触发,并靠对消息的响应和处理来完成。Windows系统中有两种消息队列,一种是系统消息队列,另一种是应用程序消息队列。计算机的所有输入设备由Windows监控,当一个事件发生时,Windows先将输入的消息放入系统消息队列中,然后再将输入的消息拷贝到相应的应用程序队列中。应用程序中的消息循环从它的消息队列中检索每一个消息并发送给相应的窗口函数中。一个事件的发生,到达处理它的窗口函数必需经历上述过程。值得注意的是消息的非抢先性,即不论事件的急与缓,总是按到达的先后排队(一些系统消息除外),这就使得一些外部实时事件可能得不到及时的处理。 图1 三、Windows的保护模式及中断机制 1.Windows的保护模式 保护模式指的是线性地址由一个选择符间接生成的,该选择符指向描述表中的某一项;而实模式中则通过一个段/偏移量对来直接寻址。80386(486)CPU提供的保护模式能力包括一个64K的虚拟地址空间和一个4G的段尺寸。Windows3.1实现时有所差别,它支持标准模式和增强模式。标准模式针对286机器,不属本文探讨范围。增强模式是对386以上CPU而言,Windows正是使用保护模式来打破1M的屏障并且执行简单的内存保护。它使用选择器、描述器和描述器表控制访问指定内存的位置和段。描述器表包括全局描述器表、局部描述器表、中断描

操作系统实验一中断处理

实习一中断处理 一、实习内容 模拟中断事件的处理。 二、实习目的 现代计算机系统的硬件部分都设有中断机构,它是实现多道程序设计的基础。中断机 构能发现中断事件,且当发现中断事件后迫使正在处理器上执行的进程暂时停止执行,而让操作系统的中断处理程序占有处理器去处理出现的中断事件。对不同的中断事件,由于它们的性质不同,所以操作系统应采用不同的处理。通过实习了解中断及中断处理程序的作用。本实习模拟“时钟中断事件”的处理,对其它中断事件的模拟处理,可根据各中断事件的性质确定处理原则,制定算法,然后依照本实习,自行设计。 三、实习题目 模拟时钟中断的产生及设计一个对时钟中断事件进行处理的模拟程序。 [提示]: (1) 计算机系统工作过程中,若出现中断事件,硬件就把它记录在中断寄存器中。中 断寄存器的每一位可与一个中断事件对应,当出现某中断事件后,对应的中断寄存器的某一位就被置成―1‖。 处理器每执行一条指令后,必须查中断寄存器,当中断寄存器内容不为―0‖时,说明有中断事件发生。硬件把中断寄存器内容以及现行程序的断点存在主存的固定单元,且让操作系统的中断处理程序占用处理器来处理出现的中断事件。操作系统分析保存在主存固定单元中的中断寄存器内容就可知道出现的中断事件的性质,从而作出相应的处理。 本实习中,用从键盘读入信息来模拟中断寄存器的作用,用计数器加1 来模拟处理器 执行了一条指令。每模拟一条指令执行后,从键盘读入信息且分析,当读入信息=0 时,表示无中断事件发生,继续执行指令;当读入信息=1 时,表示发生了时钟中断事件,转时钟中断处理程序。 (2)假定计算机系统有一时钟,它按电源频率(50Hz)产生中断请求信号,即每隔20 毫秒产生一次中断请求信号,称时钟中断信号,时钟中断的间隔时间(20 毫秒)称时钟单

中断实验报告

沈阳工程学院 学生实验报告 实验室名称:微机原理实验室实验课程名称:微机原理及应用 实验项目名称:8259中断控制器实验实验日期:年月日 班级:姓名:学号: 指导教师:批阅教师:成绩: 一.实验目的 1.熟悉8086中断系统及8259的扩展方法。 2.理解8259中断控制器的工作原理。 3.初步掌握8259的应用编程方法。 二.实验设备 PC机一台,TD-PITE实验装置一套。 三.实验内容 1.实验原理 (1)在Intel 386EX芯片中集成有中断控制单元(ICU),该单元包含有两个级联中断控制器:一个为主控制器,一个为从控制器。从片的INT连接到主片的IR2信号上构成两片8259的级联。主片8259的中断请求信号IR6和IR7开放,从片的中断请求信号IR1开放,以供实验使用。 (2)单次脉冲输出与主片8259的MIR7相连,每按动一次单次脉冲开关,产生一个外部中断,在显示器上输出一个字符。 8259中断实验接线图 2.实验步骤 (1)补全实验程序,按实验接线图接线。 (2)对实验程序进行编译、链接无误后,加载到实验系统。 (3)执行程序,并按动单次脉冲开关KK1或KK2,观察程序执行结果。 3.程序清单 SSTACK SEGMENT STACK DW 32 DUP(?) SSTACK ENDS CODE SEGMENT ASSUME CS:CODE,SS:SSTACK START: PUSH DS MOV AX, 0000H MOV DS, AX ·1·

8259中断控制实验 ·2· MOV AX, OFFSET MIR7 ①MOV SI, ( ) MOV [SI], AX MOV AX, CS ②MOV SI, ( ) MOV [SI], AX CLI POP DS MOV AL, 11H OUT 20H, AL MOV AL, 08H OUT 21H, AL MOV AL, 04H OUT 21H, AL MOV AL, 01H OUT 21H, AL MOV AL, ( ) OUT 21H, AL STI AA1: NOP JMP AA1 MIR7: STI CALL DELAY MOV AX, 0137H INT 10H MOV AX, 0120H INT 10H MOV AL, 20H OUT 20H, AL IRET DELAY: PUSH CX MOV CX, 0F00H AA0: PUSH AX POP AX LOOP AA0 POP CX RET CODE ENDS END START 四.实验结果及分析 根据实验回答下列问题: 1.按动单次脉冲输入KK1后,屏幕显示字符 。 2.分析中断矢量地址能改成别的数值吗?为什么? 3.改变接线,KK1连接MIR6。修改程序行①为 ,修改程序行②为 ,重新设置中断向量,以及中断屏蔽字改为 。 4.如果输出数字9,如何修改程序? 5.如何屏蔽MIR7上的中断请求?按下KK1会有什么现象? 6.选做:如果采用级联方式扩展一片8259从片,应如何修改程序呢?请将程序写在背面。 成绩评定 对实验原理的掌握情况 2 1 0 — 实验步骤正确性 3 2 1 0 实验数据记录正确性 2 1 0 — 实验结果及分析的正确性 3 2 1 成 绩 批阅教师: 20 年 月 日

计算机组成原理中断实验报告

北京建筑大学 2015/2016 学年第二学期 课程设计 课程名称计算机组成原理综合实验 设计题目微程序控制器设计与实现 系别电信学院计算机系 班级计141 学生姓名艾尼瓦尔·阿布力米提 学号 完成日期二〇一六年七月八日星期五 成绩 指导教师 (签名) 计算机组成综合实验任务书

指令执行流程图; ?5、利用上端软件,把所编写的微程序控制器内容写入实验台中控制器中。 ?6、利用单拍测试控制器与编程的要求是否一致。如果有错误重新修改后再写入控制器中。 7、编写一段测试程序,测试控制器运行是否正确。 实验目的 1.融合贯通计算机组成原理课程,加深对计算机系统各模块的工作原理及相互联系(寄存器堆、运算器、存储器、控制台、微程序控制器)。 2.理解并掌握微程序控制器的设计方法和实现原理,具备初步的独立设计能力;3.掌握较复杂微程序控制器的设计、调试等基本技能;提高综合运用所学理论知识独立分析和解决问题的能力。 实验电路 1. 微指令格式与微程序控制器电路 2.微程序控制器组成 仍然使用前面的CPU组成与机器指令执行实验的电路图,但本次实验加入中断系统。这是一个简单的中断系统模型,只支持单级中断、单个中断请求,有中断屏蔽功能,旨在说明最基本的原理。

中断屏蔽控制逻辑分别集成在2片GAL22V10(TIMER1 和TIMER2)中。其ABEL语言表达式如下: INTR1 := INTR; INTR1.CLK = CLK1; IE := CLR & INTS # CLR & IE & !INTC; IE.CLK= MF; INTQ = IE & INTR1; 其中,CLK1是TIMER1产生的时钟信号,它主要是作为W1—W4的时钟脉冲,这里作为INTR1的时钟信号,INTE的时钟信号是晶振产生的MF。INTS微指令位是INTS机器指令执行过程中从控制存储器读出的,INTC微指令位是INTC机器指令执行过程中从控制存储器读出的。INTE是中断允许标志,控制台有一个指示灯IE显示其状态,它为1时,允许中断,为0 时,禁止中断。当INTS = 1时,在下一个MF的上升沿IE变1,当INTC = 1时,在下一个MF的上升沿IE变0。CLR信号实际是控制台产生的复位信号CLR#。当CLR = 0时,在下一个CLK1的上升沿IE变0。当 CLR=1 且INTS = 0 且 INTC = 0时,IE保持不变。 INTR是外部中断源,接控制台按钮INTR。按一次INTR按钮,产生一个中断请求正脉冲INTR。INTR1是INTR经时钟CLK1同步后产生的,目的是保持INTR1与实验台的时序信号同步。INTR脉冲信号的上升沿代表有外部中断请求到达中断控制器。INTQ是中断屏蔽控制逻辑传递给CPU的中断信号,接到微程序控制器上。当收到INTR脉冲信号时,若中断允许位INTE=0,则中断被屏蔽,INTQ仍然为0;若INTE =1,则INTQ =1。

中断实验报告

上机实验报告课程名称计算机接口与外设上机内容中断实验 学院计算机学院 专业计算机科学与技术班级 学号 学生姓名 指导教师吴以凡 完成日期2014-12-9

一、实验目的 1、掌握8259中断控制器的工作原理。 2、学会编写中断服务程序。 二、实验内容及成果展示 实验1:使用软中断 代码: start: M OV AX,DATA M OV DS,AX CLI M OV SI,0CH*4 M OV AX, OFFSET INTSERVICE ;中断入口偏移地址 M OV ES:[SI], AX M OV AX, SEG INTSERVICE ;中断入口的段地址 M OV ES:[SI+2], AX S TI ;开中断 M OV AL,CNT ; 初始CNT=1 M OV DX,0000H ; led的地址 O UT DX,AL ;开始第一个灯亮 LI: CALL INTSERVICE ;调用软件中断 C ALL DELAY ;延时 J MP LI ;中断服务程序---------------------------------- INTSERVICE PROC P USH DS M OV AL,CNT ;cnt=1; R OL AL,1 ;cnt=cnt<<1 M OV CNT,AL

M OV DX,0000H ;led=cnt<<1 O UT DX,AL P OP DS INTSERVICE ENDP ;------------------------------------------------- ;软件延时子程序---------------------------------- DELAY PROC P USH BX ;这里用到堆栈 P USH CX M OV BX,1 L P2:MOV CX,0 L P1:LOOP LP1 D EC BX J NZ LP2 P OP CX P OP BX R ET DELAY ENDP code ENDS END start实验结果: 实验2:使用1片8259A + 按钮硬件中断

第5章 中断服务程序设计

第5章中断服务程序设计 中断服务程序(ISR)是嵌入式应用系统获取各种事件的基本手段,而“事件”是实时性问题的讨论基础和时间计算的起点。ISR的设计质量直接影响到系统的实时性指标和操作系统的工作效率。 只要没有关中断,中断服务程序可以中断任何任务的运行,可将中断服务程序可成比最高优先级(0级)还高的“任务”。 5.1中断优先级安排原则 中断源是系统及时获取异步事件的主要手段,其优先级安排原则如下: ●紧迫性:触发中断的事件允许耽误的时间越短,设定的中断优先级就越高。 ●关键性:触发中断的事件越关键(重要),设定的中断优先级就越高。 ●频繁性:触发中断的事件发生越频繁,设定的中断优先级就越高。 ●快捷性:ISR处理越快捷(耗时短),设定的中断优先级就越高。 中断服务程的功能应尽量简单,只要将获取的异步事件通信给关联任务,后续处理由关联任务完成。 5.2不受操作系统管理的中断服务程序 正常情况下,ISR应受操作系统的管理,因很多任务是靠ISR触发的。 但在两种情况下ISR不受操作系统管理:①没有必要;②操作系统没有对该ISR进行管理。 实时操作系统uC/OS-Ⅱ移植到ARM7体系的CPU上时,没有对FIQ进行处理,即FIQ 是不受操作系统管理的。 选用FIQ来响应实时性要求最高的高速采样操作是一个有效措施,保护现场的工作量很小(FIQ专有的8个寄存器不需要保护)。 在工程模板的系统启动文件Startup.s中,已经把汇编代码部分处理好,用户只需要用C 语言编写快速中断服务函数FIQ_Exception()即可,不需考虑保护现场和恢复现场的问题。 程序:Startup.s中队FIQ的处理 Reset ;异常向量表 LDR PC,ResetAddr ;跳转到复位入口地址 LDR PC,UndefinedAddr LDR PC,SWI_Addr ;跳转到软件中断入口地址 LDR PC,PrefetchAddr LDR PC,DataAbortAddr DCD 0xb9205f80 LDR PC,[PC,#-0xff0] ;跳转到向量中断入口地址(向量中断控制器) LDR PC,FIQ_Addr ;跳转到快速中断入口地址 ResetAddr DCD ResetInit UndefinedAddr DCD Undefined SWI_Addr DCD SoftwareInterrupt PrefetchAddr DCD PrefetchAbort Nouse DCD 0

中断处理程序设计

课程实验报告 课程名称:汇编语言程序设计 实验名称:实验四 实验时间: 2015-6-16,14:30-17:30 实验地点:南一楼804室 指导教师:李专 专业班级:学号: 姓名: 同组学生: 报告日期: 成绩: 计算机科学与技术学院

一、原创性声明 本人郑重声明:本报告的内容由本人独立完成,有关观点、方法、数据和文献等的引用已经在文中指出。除文中已经注明引用的内容外,本报告不包含任何其他个人或集体已经公开发表的作品或成果,不存在剽窃、抄袭行为。 特此声明! 学生签字: 日期: 二、评语与成绩评定 1.指导老师评语 2.实验成绩评定 实验完成质量得分(70分)(实验步骤清晰详细深入,实验记录真实完整等)报告撰写质量得分(30分) (报告规范、完整、通顺、 详实等) 总成绩(100分) 指导教师签字: 日期:

目录 1.实验目的 (1) 2.实验内容 (1) 2.1任务一 (1) 2.2任务二 (1) 2.3任务三 (2) 2.4任务四 (2) 3实验过程 (2) 3.1任务一 (2) 3.1.1实验要求 (2) 3.1.2实验结果 (2) 3.2任务二 (4) 3.2.1设计思想及存储分配 (4) 3.2.2程序框图 (5) 3.2.3源程序代码 (6) 3.2.4实验结果 (7) 3.3任务三 (7) 3.3.1源程序代码 (7) 3.3.2实验结果 (11) 3.4任务四 (12) 3.4.1源程序代码 (12) 3.4.2实验结果 (16) 4.实验体会 (16)

1.实验目的 (1) 掌握中断矢量表的概念 (2)掌握中断处理程序设计的技巧 (3)掌握简化段定义、函数调用伪指令 (4)了解Win32程序的编程方法及编译、链接方法 2.实验内容 2.1任务一 用三种方式获取中断类型码10H对应的中断处理程序的入口地址。 要求:(1) 直接运行调试工具(TD.EXE),观察中断矢量表中的信息; (2) 编写程序,用 DOS功能调用方式获取,观察相应的出口参数与(1) 中看到的结果是否相同(使用TD观看即可) (3) 编写程序,直接读取相应内存单元,观察读到的数据与(1)看到的结 果是否相同(使用TD观看即可)。 2.2任务二 编写一个中断服务程序并驻留内存,要求在程序返回DOS操作系统后,键盘的按键A变成了按键B、按键B变成了按键A。 提示:(1) 对于任何DOS程序,不管其采用什么方法获取按键,最后都是通过执行16H号软中断的0号和10H号功能调用来实现的。所以,你只需接 管16H号软中断的0号和10号功能调用并进行相应的处理; (2) 获得一个按键扫描码的方法:在TD中执行16H中断的0号和10H号 功能调用,按相应的键,观察AH中的内容。 资料:16H中断的0号和10H号功能 功能描述:从键盘读入字符 入口参数:AH = 00H——读键盘 = 10H——读扩展键盘 出口参数:AH =键盘的扫描码 AL =字符的ASCII码

相关主题
文本预览
相关文档 最新文档