51单片机中断服务
1.中断的概念
在51单片机中,中断是一种机制,可以让单片机在执行某个任务时,暂停当前程序的执行,转而去执行另外一个优先级更高的任务,待该任务执行完毕后,再回到原来的任务继续执行。中断机制可以有效提高单片机的实时性和响应速度。在51单片机中,中断可以通过设置中断向量表来实现。
中断向量表是一个存储区域,它记录了所有中断服务程序的入口地址。当中断发生时,单片机会根据中断类型(外部中断、定时器中断、串口中断等)去中断向量表中查找对应的中断服务程序的入口地址,然后跳转到该地址执行中断服务程序。
让CPU产生中断信号的称为中断源(中断请求源),定时器/计数器实际上就是中断源。例如“当定时/延时50 ms的时间后,定时器内部总线自动向CPU发出一个中断请求:‘停止当前定时/计数的工作,转而去执行中断程序(如点亮一个LED灯)’”,执行完后,再返回接着执行原来的工作。
8051单片机提供了5个中断源,它们可以向CPU发送中断请求。如果一个中断源向它发出中断请求信号,它就会产生中断,但是如果同时有两个中断源发出中断请求信号,CPU会根据优先级决定接受哪一个中断请求,先接受高优先级的中断请求,再接受低优先级的中断请求。
中断源 | 优先级 | 中断入口地址 | 中断编号 |
---|---|---|---|
外部中断 INT0 | 高 | 0003H | 0 |
定时器 T0 | 较高 | 000BH | 1 |
外部中断 INT1 | 适中 | 0013H | 2 |
定时器 T1 | 较低 | 001BH | 3 |
串行通信中断R1或T1 | 低 | 0023H | 4 |
2.中断子程序的写法
定义中断服务程序的入口地址:
1.定义中断服务程序的入口地址:
中断类型 中断服务程序名称() interrupt 中断类型号
{
//中断服务程序的代码
}
2.中断服务函数的完整语法:
void 函数名(void)interrupt n [using r]
{
//中断服务程序的代码
}
其中:
n(0~4)代表中断号,其编号意义如上表所示。
r(0~3)代表第r组寄存器,如果不声明,则默认第0组寄存器。有如下4个寄存器:
(1)定时器/计数器控制寄存器TCON;
(2)串行通信控制寄存器SCON;
(3)中断允许寄存器IE;
(4)中断优先级控制寄存器IP;
调用中断函数时,要求中断过程调用的函数所使用的寄存器组必须与其相同,逻辑上,一个中断服务程序不能传递参数进去,也不可返回值。
其中,中断类型可以是外部中断、定时器中断、串口中断等;中断服务程序名称是用户自定义的程序名称;interrupt 是51单片机中断向量表中的关键字,用于告诉单片机这是一个中断服务程序;中断类型号是中断向量表中对应的中断类型号。
3.设置中断向量表
void main()
{
//设置中断向量表
EA = 1; //开总中断
EX0 = 1; //开外部中断0
IT0 = 1; //设置外部中断0为下降沿触发
TMOD = 0x01; //设置定时器0为模式1
TH0 = 0xFC; //设置定时器0初值
TL0 = 0x67;
ET0 = 1; //开定时器0中断
TR0 = 1; //启动定时器0
while(1)
{
//主程序代码
}
}
在main函数中,需要设置中断向量表,包括开总中断、开外部中断、设置外部中断触发方式、开定时器中断、设置定时器初值、启动定时器等。这些操作会在单片机中断发生时,使得单片机能够根据中断类型去中断向量表中查找对应的中断服务程序的入口地址。
4.编写中断服务程序
void external0_isr() interrupt 0
{
//外部中断0服务程序的代码
}
void timer0_isr() interrupt 1
{
//定时器0服务程序的代码
}
在中断服务程序中,需要根据实际需求编写对应的代码,实现对中断事件的响应。在中断服务程序的开头和结尾需要加上关中断和开中断的指示,确保中断服务程序执行过程中不会被其他中断打断。
5.关中断和开中断
void external0_isr() interrupt 0
{
EA = 0; //关总中断
//外部中断0服务程序的代码
EA = 1; //开总中断
}
void timer0_isr() interrupt 1
{
EA = 0; //关总中断
//定时器0服务程序的代码
EA = 1; //开总中断
}
在中断服务程序的开头和结尾,需要加上关中断和开中断的指示,以确保中断服务程序的执行过程中不会被其他中断打断。在开头处关中断,可以避免在执行中断服务程序时,又发生同样的中断事件,造成重复执行;在结尾处开中断,可以使得其他优先级更低的中断能够在该中断服务程序执行完毕后立即得到响应,提高单片机的实时性和响应速度。总的来说,编写51单片机中断子程序需要注意以下几点:
- 定义中断服务程序的入口地址,包括中断类型、中断服务程序名称、中断类型号等。
- 设置中断向量表,包括开总中断、开外部中断、设置外部中断触发方式、开定时器中断、设置定时器初值、启动定时器等。
- 编写中断服务程序,根据实际需求编写对应的代码,确保中断服务程序执行过程中不会被其他中断打断。
- 在中断服务程序的开头和结尾加上关中断和开中断的指示,以确保中断服务程序的执行过程中不会被其他中断打断。
6.中断优先级
在51单片机中,不同类型的中断有不同的优先级,而同一类型的中断则是按照中断产生的先后顺序决定优先级。如果同时有多个中断请求,优先级高的中断将被先响应,而优先级低的中断则需要等待优先级高的中断服务程序执行完毕后才能被响应。
当需要处理多个中断事件时,需要根据实际需求设置不同的中断优先级,以确保系统能够在高优先级中断事件发生时及时响应并处理,从而提高系统的实时性和可靠性。
7.中断嵌套
在51单片机中,允许中断嵌套,即在一个中断服务程序执行期间,又触发了另一个中断请求。为了避免中断服务程序被打断,需要使用嵌套中断的方式来处理多个中断事件。
当出现嵌套中断时,需要根据实际需求设置不同的中断优先级,以确保系统能够在高优先级中断事件发生时及时响应并处理,从而提高系统的实时性和可靠性。
总之,51单片机中断子程序的写法是非常重要的,它能够帮助我们实现单片机的实时响应和高可靠性运行。在编写中断子程序时,需要注意中断类型、中断服务程序名称、中断向量表、中断优先级和中断嵌套等相关问题,从而确保中断子程序的正确性和可靠性。
8.中断标志位的清除
在51单片机中,当一个中断事件被响应后,需要清除中断标志位,以允许下一个中断事件被响应。在编写中断服务程序时,需要根据实际需求清除对应的中断标志位。
例如,在使用定时器中断时,需要清除定时器中断标志位TF0,代码如下所示:
void timer0_isr() interrupt 1
{
EA = 0; //关总中断
//定时器0服务程序的代码
TF0 = 0; //清除定时器0中断标志位
EA = 1; //开总中断
}
9.中断服务程序的调试
在编写中断服务程序时,需要注意调试的问题。由于中断服务程序不是在主程序中调用的,因此在调试时需要使用其他方法来检查中断服务程序的正确性和可靠性。一般来说,可以使用调试工具来监控中断服务程序的执行情况,并对中断服务程序的代码进行调试和优化。
总的来说,51单片机中断子程序的写法需要综合考虑多个因素,包括中断类型、中断服务程序名称、中断向量表、中断优先级、中断嵌套、中断标志位的清除和中断服务程序的调试等。只有在考虑到这些因素的基础上,才能编写出正确、可靠、高效的中断子程序,从而提高单片机的实时响应能力和可靠性运行。
10.中断服务程序的实现
在实现中断服务程序时,需要注意以下几个问题:
- 中断服务程序需要满足特定的格式要求,包括使用特定的关键字、参数等。
- 中断服务程序需要尽可能地简单,避免使用复杂的代码结构和算法。
- 中断服务程序需要尽可能地快速执行,避免过长的执行时间。
- 中断服务程序需要对共享资源进行保护,以避免出现竞态条件等问题。
例如,在使用定时器中断时,需要使用volatile关键字来声明变量,避免出现编译器优化导致的问题;同时,在修改共享资源时需要使用关中断的方式进行保护,避免出现竞态条件,代码如下所示:
volatile unsigned char count = 0;
void timer0_isr() interrupt 1
{
unsigned char temp;
EA = 0; //关总中断
temp = TH0;
temp = TL0;
TH0 = 0xFC; //重新赋初值,1ms定时
TL0 = 0x67;
count++;
EA = 1; //开总中断
}
void main()
{
unsigned char num;
TMOD = 0x01; //设置定时器0为模式1
TH0 = 0xFC; //给定时器0赋初值,1ms定时
TL0 = 0x67;
TR0 = 1; //定时器0开始计时
ET0 = 1; //允许定时器0中断
EA = 1; //开总中断
while(1)
{
if(count >= 10) //10ms到达
{
count = 0;
num++;
}
}
}
在上述代码中,中断服务程序只是简单地对计数器进行加1操作,并在主程序中使用计数器来实现10ms的计时功能。同时,中断服务程序也对共享资源计数器进行了保护,避免出现竞态条件等问题。
中断是单片机中实现实时响应的重要机制之一,可以在单片机运行过程中对外部事件进行及时处理。在51单片机中,中断子程序的编写需要考虑多个因素,包括中断类型、中断服务程序名称、中断向量表、中断优先级、中断嵌套、中断标志位的清除和中断服务程序的调试等。只有在考虑到这些因素的基础上,才能编写出正确、可靠、高效的中断子程序,从而提高单片机的实时响应能力和可靠性运行。
同时,在编写中断服务程序时,需要注意格式要求、简单性、执行速度和共享资源保护等问题。只有在考虑到这些问题的基础上,才能编写出正确、可靠、高效的中断服务程序,从而实现单片机的实时响应功能。
总的来说,中断子程序的编写是单片机编程中非常重要的一个方面,需要充分理解中断机制的原理和实现方式,结合具体的应用场景进行设计和实现。
11.汇总