原创 【基础教程】MCS51中断系统

2010-4-24 19:38 3336 8 8 分类: 通信



本文章来自www.zyxmcu.com(张彦欣单片机),更多内容,敬请登录。


    就像指针是C语言中的精华一样,中断系统就算称不上MCS51的精华,起码也是一个极其重要的资源。像是我们众所周知的单片机RTOS(实施操作系统)大部分都是以中断方式工作的。中断技术是现代计算机控制系统中一项非常重要的技术,终端系统由硬件和软件组成。有了中断系统,能使计算机的功能更强、效率更高、更加灵活方便。中断的意义如此巨大,我们有必要好好的学习一下:
中断系统的概念:
    在计算机系统(包括单片机)在处理常规事务的时候(顺序执行程序),如果遇到紧急事务,需要立即执行相关的代码,在执行完这些代码以后,需要转回来继续执行原先的代码,这个过程就是中断。
    举个例子,我们在吃饭的时候,突然有人来敲门,我们响应这个“中断”(敲门),转向执行中断程序(去开门),在发现是敲错门的情况下,回来继续吃饭(执行原来的程序)。这个过程就是一个典型的中断过程。当然,我们可以不理睬这个“中断”,而是采用“查询”的方式工作:我们吃饭的时候,每隔10秒就去门口看看有没有人敲门,然后回来吃饭。
    我们可以明显的看出来,中断方式使计算机的工作效率更加的高效,中断也是计算机工作不可或缺的技术。这也是我们今天为什么要详细讨论的原因。







中断系统的几个重要概念:
1.中断系统
能够实现中断处理功能的部件称为中断系统。
2.中断源
向CPU提出中断请求的源成为中断源。(这个请求叫做中断请求或是中断申请)
3.中断服务子程序
CPU同意处理相关请求,就叫中断响应。处理中断请求的程序称为中断服务子程序。
4.保护现场
CPU同意中断处理,去执行中断服务子程序之前,需要保存相关寄存器的值,这个过程就叫做“保护现场”。
5.恢复现场
在完成中断服务子程序后,恢复有关的工作寄存器、累加器、标志位等,叫做“恢复现场”。
6.中断返回
退出中断服务子程序,回到原来的程序,继续执行原来程序,叫做“中断返回”。








中断源
我们说了,“中断源”就是可以向CPU产生“中断申请”的机构。其实就是中断的“触发者”。MCS51单片机的中断系统含有5个中断源。



  中断号


  中断源类型  


   入口地址 


 0


 外部中断(/INT0)

 0x 0003

1

 定时/计数器T0溢出中断 0x 000B

2

 外部中断(/INT1) 0x 0013

 3

 定时/计数器T1溢出中断 0x 001B

 4

 串行口中断 0x 0023


说明:
    1./INT0(带有上划线,意思是低电平有效)--由单片机的/INT0引脚(P3.2)引脚输入,中断请求标志位(这个后面会讨论)为IE0;当P3.2引脚出现低电平时,将触发相关的中断事件(前提是开启了中断系统)。
    2./INT1(带有上划线,意思是低电平有效)--由单片机的/INT1引脚(P3.3)引脚输入,中断请求标志位(这个后面会讨论)为IE1;当P3.3引脚出现低电平时,将触发相关的中断事件(前提是开启了中断系统)。
    3.定时/计数器T0溢出中断请求--中断标志位TF0.(定时计数器将另外单独讨论)
    4.定时/计数器T1溢出中断请求--中断标志位TF1.(定时计数器将另外单独讨论)
    5.串行中断请求--串行通信中断请求,标志位TI或是RI。
    总而言之,单片机MCS51的中断系统的相关中断源触发了中断事件,硬件电路就会将相关的中断标志位寄存器置1,如果我们编程时开启了中断系统,就会响应相关的中断,执行中断服务程序;程序执行完毕后,返回原来的程序。







编程方法:
    在程序中,编写一个中断函数一般包括这么几个步骤:
1.开启全局中断(CPU开中断,如果CPU不开中断,所有的中断均不响应)。
2.开启特定中断(打开局部中需要开启的中断,比如开启定时计数器T0中断等)。
3.编写中断服务子程序(其中需要清除中断标志位)。
    在汇编语言中,中断函数的编写凭借的是中断函数的“入口地址”,也就是说,发生了相关的中断后,CPU就会自动执行“某一个地址”的程序。比如,在开启中断的情况下,当发生外部中断0的时候,CPU会自动执行 0003处的程序。
    在C语言中,中断函数的编写就不需要使用“入口地址”,而是使用“中断号”。其实就是中断的编号,比如,在开启中断的情况下,当发生外部中断0的时候,CPU会自动执行带有interrupt 1 后缀的函数。下面看看一个典型的C语言中断函数的编写(本程序以实验板L-20为基础。P0口上反向接着8个LED灯,低电平有效;按键S1所对应的P2.0口通过杜邦线连接到了P3.2口):
#include <REG51.h>
unsigned char FLAG;
void main()
{
     EA="1";       //开启中断系统。CPU开中断。
     EX0=1;     //允许外部中断0(P3.2引脚输入)
     P0 = 0xFF; //关闭P0口上的LED灯。
     for(;;)
     {
     }
}
void  Function() interrupt 0
{
    P0=0x00;   //打开P0口上的LED灯。
    ET0=0;      //在退出中断程序的时候记得清除标志位。
}

    编译链接后,将程序下载到L-20实验板上,可以看到,在程序运行开始P0口上的LED灯全部不亮,当按键S1按下后(P3.2端口低电平)P0口的LED灯全部点亮。说明中断程序运行正常。




 2010422212520228.jpg2010422212557706.jpg 

 按下按键之前(中断发生前)


 按下按键之后(中断发生后)


关于中断,需要注意的是:
1.在中断中,一般不要执行大量的代码。也尽量不要调用过多的函数。一般在中断中只操作标志位。试想,如果中断中代码过长,本次中断还没有执行完毕,第二次中断又发生……这必将导致中断函数不能正常运行或是外部请求不能得到及时响应。
2.中断是有优先级的。优先级高的中断将首先得到响应,执行完毕后才响应中断优先级低的中断请求。上面我们提到的中断号从1-5,中断优先级依次降低,也就是说外部中断0具有最高的中断优先级。当然,在MCS51中,是可以设置中断的优先级的,寄存器是IP。另外,如果在一个中断中,你不希望中断被打断,你可以在中断服务子程序中先执行"EA=0;"关闭所有中断,这样中断就不会被打断,但是同时也不会响应更高级的中断。
3.注意中断系统发生的频率,否则可能导致占用CPU的时间过多,使常规代码得不到运行。
 




43.gif未经书面允许,禁止转载,否则将追究责任43.gif




文章评论0条评论)

登录后参与讨论
我要评论
0
8
关闭 站长推荐上一条 /2 下一条