嵌入式系统 - 中断
中断是由硬件或软件向处理器发出的信号,表示需要立即关注的事件。每当发生中断时,控制器就会完成当前指令的执行并开始执行中断服务例程 (ISR) 或中断处理程序。ISR 会告诉处理器或控制器在发生中断时该做什么。中断可以是硬件中断,也可以是软件中断。
硬件中断
硬件中断是从外部设备(如磁盘控制器或外部外围设备)发送到处理器的电子警报信号。例如,当我们按下键盘上的某个键或移动鼠标时,它们会触发硬件中断,从而使处理器读取按键或鼠标位置。
软件中断
软件中断是由异常情况或指令集中的特殊指令引起的,当处理器执行该指令时会导致中断。例如,如果处理器的算术逻辑单元运行命令将数字除以零,则会导致除以零异常,从而导致计算机放弃计算或显示错误消息。软件中断指令的工作原理类似于子程序调用。
什么是轮询?
持续监控的状态称为轮询。微控制器不断检查其他设备的状态;在此过程中,它不执行其他操作,而是将所有处理时间都用于监控。可以使用中断来解决此问题。
在中断方法中,控制器仅在发生中断时才响应。因此,控制器不需要定期监控接口和内置设备的状态(标志、信号等)。
中断与轮询
这是一个区分中断和轮询的类比 −
中断 | 轮询 |
---|---|
中断就像店主。如果有人需要服务或产品,他会去找他并告知他的需求。在发生中断的情况下,当收到标志或信号时,它们会通知控制器需要服务。 | 轮询方法就像销售员。销售员挨家挨户推销产品或服务。同样,控制器会逐一监控所有设备的标志或信号,并为需要服务的组件提供服务。 |
中断服务例程
对于每个中断,必须有一个中断服务例程 (ISR) 或中断处理程序。发生中断时,微控制器将运行中断服务例程。对于每个中断,内存中都有一个固定位置,用于保存其中断服务例程 ISR 的地址。留出用于保存 ISR 地址的内存位置表称为中断向量表。

中断向量表
8051 中有六个中断,包括 RESET。
中断 | ROM 位置(十六进制) | 引脚 |
---|---|---|
中断 | ROM 位置(十六进制) | |
串行 COM(RI 和TI) | 0023 | |
定时器 1 中断 (TF1) | 001B | |
外部 HW 中断 1 (INT1) | 0013 | P3.3 (13) |
外部 HW 中断 0 (INT0) | 0003 | P3.2 (12) |
定时器 0 (TF0) | 000B | |
重置 | 0000 | 9 |
当重置引脚激活时,8051 跳转到地址位置 0000。这是上电重置。
为定时器预留了两个中断:一个用于定时器 0,一个用于定时器 1。中断向量表中的内存位置分别为 000BH 和 001BH。
为硬件外部中断预留了两个中断。端口 3 中的引脚 12 和引脚 13 分别用于外部硬件中断 INT0 和 INT1。中断向量表中的内存位置分别为 0003H 和 0013H。
串行通信具有一个属于接收和发送的中断。内存位置 0023H 属于此中断。
执行中断的步骤
当中断激活时,微控制器将执行以下步骤 −
微控制器关闭当前正在执行的指令,并将下一个指令 (PC) 的地址保存在堆栈上。
它还在内部保存所有中断的当前状态(即不在堆栈上)。
它跳转到中断向量表的内存位置,该位置保存中断服务例程的地址。
微控制器从中断向量表中获取 ISR 的地址并跳转到该地址。它开始执行中断服务子程序,即 RETI(从中断返回)。
执行 RETI 指令后,微控制器返回到被中断的位置。首先,它通过将堆栈顶部字节弹出到 PC 中来从堆栈中获取程序计数器 (PC) 地址。然后,它从该地址开始执行。
边缘触发与电平触发
中断模块有两种类型:电平触发或边沿触发。
电平触发 | 边沿触发 |
---|---|
只要中断源的电平有效,电平触发中断模块就会生成中断。 | 边沿触发中断模块仅在检测到中断源的边沿有效时生成中断。当中断源电平实际发生变化时,才会检测到边沿。也可以通过定期采样并在前一个样本取消断言时检测断言级别来检测它。 |
如果固件中断处理程序处理中断时中断源仍处于断言状态,则中断模块将重新生成中断,从而再次调用中断处理程序。 | 无论中断源如何表现,边沿触发的中断模块都可以立即采取行动。 |
级别触发的中断对固件来说很麻烦。 | 边沿触发的中断使固件的代码复杂度保持在较低水平,减少了固件的条件数量,并在处理中断时提供了更大的灵活性。 |
启用和禁用中断
重置后,所有中断即使已激活也将被禁用。必须使用软件启用中断,以便微控制器响应这些中断。
IE(中断启用)寄存器负责启用和禁用中断。IE 是一个可位寻址的寄存器。
中断启用寄存器
EA | - | ET2 | ES | ET1 | EX1 | ET0 | EX0 |
---|
EA − 全局启用/禁用。
- − 未定义。
ET2 − 启用定时器 2 中断。
ES − 启用串行端口中断。
ET1 − 启用定时器 1 中断。
EX1 − 启用外部 1 中断。
ET0 − 启用定时器 0 中断。
EX0 −启用外部 0 中断。
要启用中断,我们采取以下步骤 −
IE 寄存器 (EA) 的 D7 位必须为高,以使寄存器的其余部分生效。
如果 EA = 1,则如果 IE 中相应的位为高,则将启用中断并响应中断。如果 EA = 0,则不会响应任何中断,即使 IE 寄存器中与其相关的引脚为高。
8051 中的中断优先级
我们可以通过将更高的优先级分配给任何一个中断来更改中断优先级。这是通过编程一个称为 IP(中断优先级)的寄存器来实现的。
下图显示了 IP 寄存器的位。重置后,IP 寄存器包含所有 0。为了赋予任何中断更高的优先级,我们使 IP 寄存器中的相应位置高。
- | - | - | - | PT1 | PX1 | PT0 | PX0 |
---|
- | IP.7 | 未实现。 |
- | IP.6 | 未实现。 |
- | IP.5 | 未实现。 |
- | IP.4 | 未实现。 |
PT1 | IP.3 | 定义定时器 1 中断优先级。 |
PX1 | IP.2 | 定义外部中断 1优先级。 |
PT0 | IP.1 | 定义定时器 0 中断优先级。 |
PX0 | IP.0 | 定义外部中断 0 优先级。 |
中断内中断
如果 8051 正在执行属于中断的 ISR,而另一个中断处于活动状态,会发生什么情况?在这种情况下,高优先级中断可以中断低优先级中断。这称为中断内中断。在 8051 中,低优先级中断可以被高优先级中断中断,但不能被任何其他低优先级中断中断。
通过软件触发中断
有时我们需要通过模拟来测试 ISR。这可以通过简单的指令来完成,将中断设置为高,从而使 8051 跳转到中断向量表。例如,将定时器 1 的 IE 位设置为 1。指令 SETB TF1 将中断 8051 正在执行的任何操作,并强制其跳转到中断向量表。