大神带你玩转单片机:外部中断详解

今天开始我们正式进入中级阶段的学习:中断系统。

什么是中断

首先来讲一下什么是中断:当程序执行到某个地方时,发生了特殊的事件或请求,CPU暂停执行当前程序,转而去处理上述事件或请求,处理完毕后在返回断点继续执行当前程序。

用我们生活中的事情来举个例子。假如你正在吃饭(当前程序),突然接到了快递员的电话让你现在下去拿快递(中断请求),你回答:“好的”(中断响应),然后暂停吃饭下去拿快递(中断处理),拿完快递上来继续吃饭(执行完中断返回执行当前程序)。

“图1"
图1

在我们上课老师讲的时候,很多老师都会说51单片机共有5个中断源分别是:外部中断0、定时器溢出中断0、外部中断1、定时器溢出中断1、串口中断。

“图2"
图2

仔细观察单片机芯片的IO口时就会发现,P3端口是有第二功能的。

我们来看一下与中断有关的P3端口各引脚第二功能的定义:

  • P3^0:RXD串行口输入

  • P3^1:TXD串行口输出

  • P3^2:INT0外部中断0输入

  • P3^3:INT1外部中断1输入

  • P3^4:T0定时计数器0外部输入

  • P3^5:T1定时计数器1外部输入

其中P3^0、P3^1引脚用来与外部设备进行串口通信;P3^2、P3^3引脚用于接收外部电平变化来产生外部中断,P3^4、P3^5引脚用于接收外部脉冲来计数。

外部中断

接下来我们看一下中断系统的内部结构图,如图3所示。

“图3”
图3

今天我们主要结合这个框图讲解一下外部中断0、外部中断1。

01、IE寄存器

我们先来看图中红色框中的IE寄存器,见图3。

“图4”
图4

IE寄存器主管中断的允许与禁止,图3中IE寄存器画成了一个个的开关,也就是说我们要开启需要的中断时,就要把对应的开关打开。那么,假设我们要开启外部中断0,需要打开哪些开关呢?图中INT0通道中IE寄存机共有两个开关,分别是“EX0”(这个是数字0,可别看成字母O了)、“EA”,都是需要打开的。

好的,我们来看图4的介绍中,“EA”为总中断允许控制位,EA=0的时候会屏蔽掉所有的中断请求,所以要配置“EA=1”;EX0为外部中断0的中断允许位,同样的要配置“EX0=1”。这样一来,外部中断0的IE寄存器就配置好了。同理,外部中断1也是这样配置哦。

02、TCON寄存器

接下来我们看蓝色框里的TCON寄存器,见图3。

“图5”
图5

还是先以外部中断0(INT0)为例,在图3的通道中,我们可以看到,TCON寄存器中与INT0有关的共有两位,分别是“IT0”、“IE0”。再看图5中的介绍可知,IT0用来控制INT0的触发方式,这里我们一般使用下降沿触发方式,所以配置成:“IT0=1”。

IE0则是INT0中断的标志位,当产生中断后,IE0将被自动置1,当CPU相应了中断以后,IE0又会被硬件置1,所以说,这一位我们不需要配置。外部中断1也是一样的。

03、IP寄存器

接下来是绿色框里的“IP”寄存器,见图3.

在这之前,先来讲一下中断优先级的概念。每个中断都有不同的优先级,当两个中断同时触发时,优先级高的先执行,执行完以后再执行优先级低的中断,所以说:优先级高的中断可以中断优先级低的中断,而高优先级中断不可被低优先级或者同级优先级中断打断。

“图6”
图6
  • PX0:外部中断0优先级设定

  • PT0:定时计数器0中断优先级设定

  • PX1:外部中断1优先级设定

  • PT1:定时计数器1中断优先级设定

  • PS:串行口中断优先级设定

  • PT2:定时计数器2中断优先级设定

IP寄存器用来分配各个中断的优先级,每一位都可以将对应的中断设置为高优先级模式或者低优先级模式(配置成1为高优先级模式,0为低优先级模式)。

当同时收到优先级相同的中断时,中断响应顺序取决于内部查询顺序(外部中断0>定时计中断0>外部中断1>定时计中断1>串行口中断,该顺序与图2中中断编号相同)。由于51单片机中断相对来说还是比较少的,所以IP寄存器一般情况下并不会用到。

中断函数编写

好的,关于外部中断的配置到这里就讲完了,接下来是中断处理函数的编写。

与其他的自定义函数相类似,中断处理函数只需要在声明自定义函数时,在后边加上“ interrupt ‘中断编号’ ”就可以了。

举个栗子

我们写一下外部中断0的处理函数:

void int_0 () interrupt 0(写外部中断1时,把这里的0改为2就可以)
{
    /*  中断处理程序在这里写  */
    (执行完这里的程序再返回执行主程序)
}    

最后,我用程序来编写一下有关于外部中断0的使用方法(外部中断1也是类似的):

#include “reg52.h”

void mian()
{
    EA = 1;  EX0 = 1;  //打开总中断和INT0中断
    IT0 = 1;    //配置INT0为下降沿触发模式
    while(1)
    {
        /*  运行主程序  */
    }
}

void int_0() interrupt 0
{
    /*  中断处理程序  */
} 

这个中断服务函数可以写在任何地方,所以为了方便一点,我通常会写在最后边,嘻~ (#^.^#)

到这里了有的同学可能会有疑问,这些我都写好了,那么外部中断到底在什么时候才能触发呢?

还记得我前边讲的P3端口的第二功能嘛。对的,当P3^2端口接收到下降沿以后中断就被触发啦。

而P3^2引脚又连接了板子上的S5按键,所以,当我们按下S5按键时,外部中断0就被触发啦(外部中断1也是一样的)。

如果我们想用其他的按键或是其他的外设、引脚来触发外部中断0怎么办呢?只要用一根杜邦线把P3^2引脚与对应的引脚连接起来就可以啦。

外部中断差不多讲完啦,留下来两个小练习给大家做一下吧:

(1)使用外部中断0,通过按键S5来控制流水灯的方向 [ 初始为 P1^0 -> P1^7,按下按键时改为P1^7 -> P1^0,再次按下时改为P1^0 -> P1^7... ]

(2)数码管任意一位显示数字0,通过LED灯来触发外部中断,让任意LED灯以一定间隔闪烁,每当灯亮起来的时候数码管显示的数字加1(做这题时仔细品一下上面那段话)

相关阅读:
大神带你玩转单片机之机械按键详解

本文转载自:电子产品世界(作者:阿飞)
免责声明:本文为转载文章,转载此文目的在于传递更多信息,版权归原作者所有。本文所用视频、图片、文字如涉及作品版权问题,请联系小编进行处理。

点击这里,获取更多关于应用和技术的有关信息
点击这里,获取更多工程师博客的有关信息

最新文章