本帖最后由 Shuyang 于 2019-1-24 14:30 编辑
4.2 中断的工作过程
要想学会使用中断,需要先了解一下中断的工作过程。一个中断过程可以分为4个阶段。
1) 中断事件发生
首先,中断事件的发生是一个中断的起点。中断事件指的是可以导致CPU进入中断的外部事件,MSP430中有许多外设可以产生中断事件,例如串口、GPIO、定时器、ADC等等。
以GPIO为例,I/O口上的电平变化就可以是一个中断事件,如果I/O口外接按键,那么按键按下或抬起所造成的电平变化就可以导致中断事件发生。MSP430系列大部分型号允许两组I/O口(P1和P2)作为中断输入。
2) 中断标志位被置位
当中断事件被单片机探测到之后,对应的中断标志位(interrupt flag,简称IFG)就会被自动置位(置为1)。置位之后除非进行复位,否则中断标志位会一直保持置位状态。这样做的好处是当有些中断事件发生的时间很短时,中断信号不会被CPU所忽略。MSP430的外设中有该外设中断所对应的IFG寄存器,中断事件发生时这些寄存器就会被改写。
中断信号是如何到达CPU的呢?中断事件发生以后,对应的外设IFG寄存器被置位,但这并不意味着CPU能够接收到中断信号,要想CPU能接收到中断信号,必须将中断使能位(Interruptenable bits,简称IE)置为1。
中断使能位的存在是使得CPU能够自由选择对哪个中断事件作出响应。在单片机工作过程中,可能会产生多个不同外设的中断事件,例如定时器溢出、串口接到数据、I/O口电平变化等,但单片机CPU并不一定想对所有这些中断事件作出响应。有了中断使能位,就像有了开关,CPU就可选择只响应那些需要响应的中断事件。
默认情况下,所有中断使能位都是关闭的(除了看门狗以外)。我们需要通过编程来打开需要的中断使能位。例如想要检测P1.3口所连接的按键,就要将P1端口的中断使能寄存器(P1IE)中的BIT3置为1。
除了上述中断使能位以外,CPU中还有一个全局中断使能位,它相当于一个总开关。MSP430的全局中断使能位称为GIE,它在SR寄存器中。
3) CPU响应中断
现在我们假设一个中断事件已经发生,IFG也已被置位,对应的中断使能位也已经打开,这样我们确保中断信号能够顺利到达CPU。那么CPU接收到中断信号之后如何做出反应呢?
CPU接收到中断信号之后,会暂停正在执行的工作,并执行中断服 务函数(interrupt ser-vice routine,简称ISR)。这句话说起来简单,但实际上CPU为了保证执行完中断服 务函数之后能够顺利的回到之前的工作,需要做一系列的准备工作,如下图中第3项所述。
在执行完当前一条指令后,CPU会保存当前程序计数器(PC)的值,这样就记录下现在程序执行到的位置,以便中断结束后能返回主程序继续执行。同时状态寄存器SR的值也会被保存起来。接下来CPU会将SR寄存器清零,这将使单片机退出所有低功耗状态以便执行中断程序。另外SR寄存器中的全局中断使能位GIE也将被禁用,这样就避免了在执行中断服 务函数时CPU再响应其他中断。退出中断后CPU会重新取回SR寄存器的值,程序回到进入中断之前的位置继续执行。
接下来中断向量的地址会被加载到程序计数器(PC)中,这样就会进入到中断服 务函数的入口开始执行中断程序。CPU之所以能识别出中断的源头,是因为每一个中断标志位(IFG)是与一个中断服 务函数(ISR)一一对应的,这个对应关系存在一个表里面,这个表叫做中断向量表。例如P1端口的中断就与中断向量PORT1_VECTOR对应,因此检测到P1口的中断信号后就会自动进入PORT1_VECTOR对应的中断服 务函数。更多关于中断向量表的知识将在后续章节中详细介绍。
4) 执行中断服 务函数
中断服 务函数(ISR)里的内容是由用户编程的,想要单片机在中断时执行什么任务,就在中断服 务函数中编写相应指令。例如想要实现按键按下时LED灯亮起,那么就在GPIO中断函数中加入LED控制的语句。
中断服 务函数所做的事情由上图第4项描述,其中最关键的就是红色的“Runyour interrupt’s code”。不过需要注意在此之前,还需要判断是否为“grouped interrupt”。由于MSP430的中断资源是很宝贵的,很多中断会共用一个中断向量入口。例如前面提到的P1端口中断,当P1口的8个I/O口中的任何一个检测到中断事件时,都会进入中断服 务函数。这时就需要在中断服 务函数中先查询中断标志位,以判断究竟是哪个I/O口“出事”了。
|