一、引言
在嵌入式系统的广袤世界里,中断就如同一位高效的调度员,发挥着举足轻重的作用。想象一下,一个嵌入式系统就像一个繁忙的工厂,CPU 如同工厂里的核心工人,负责执行各种任务。如果没有中断机制,CPU 就需要不断地检查各个设备的状态,就像工人要不断停下手中的工作去询问其他部门的工作进展,这无疑会浪费大量的时间和精力。而中断的出现,就像是给每个设备都配备了一个紧急呼叫按钮,当设备有紧急事情需要处理时,比如传感器检测到了异常数据、外部设备发送了重要信息,就可以通过中断信号通知 CPU。CPU 收到信号后,会暂停当前正在执行的任务,优先处理中断事件,处理完成后再返回原来的任务继续执行。这样一来,CPU 就可以更加高效地工作,系统的响应速度和实时性也得到了极大的提升。
今天我们要深入探讨的主角 ——STM32F103C8T6,它作为一款被广泛应用于各种嵌入式项目的微控制器,其外部中断功能更是为开发者们提供了强大的工具。无论是智能硬件开发中对外部信号的实时响应,还是工业控制领域里对设备状态的及时监测,STM32F103C8T6 的外部中断都能大显身手。接下来,就让我们一起揭开它神秘的面纱,深入了解其外部中断的原理、配置与应用。
二、中断基础概念
(一)中断定义
中断,简单来说,就是在主程序运行过程中,当出现特定的中断触发条件(即中断源)时,CPU 会暂停当前正在执行的程序,转而去执行中断服务程序。这个过程就好比你正在专心写作业,突然手机响了(中断源),你会暂停写作业(暂停主程序),去查看手机消息(执行中断服务程序),看完消息后再回来继续写作业(返回主程序继续执行) 。在 STM32F103C8T6 中,中断源可以是外部设备的信号变化,如按键按下、传感器数据更新,也可以是内部定时器溢出、串口数据接收等事件。中断的出现,使得系统能够及时响应各种异步事件,大大提高了系统的实时性和效率。
(二)中断优先级
当有多个中断源同时向 CPU 申请中断时,就需要有一个裁决机制来决定 CPU 先响应哪个中断。这就引入了中断优先级的概念。STM32F103C8T6 的中断优先级由 NVIC(Nested Vectored Interrupt Controller,嵌套向量中断控制器)进行管理。NVIC 为每个中断通道都分配了一个优先级,优先级数值越小,表示优先级越高。例如,假设同时有按键中断和定时器中断申请,而按键中断的优先级设置为 1,定时器中断的优先级设置为 2,那么 CPU 会优先响应按键中断,待按键中断处理完成后,才会去处理定时器中断。通过合理设置中断优先级,可以确保重要的中断事件能够得到及时处理,避免因低优先级中断的干扰而导致关键任务延迟。
(三)中断嵌套
中断嵌套是指在一个中断服务程序执行过程中,又有更高优先级的中断源申请中断,此时 CPU 会暂停当前正在执行的中断服务程序,转而去处理更高优先级的中断服务程序,待处理完成后,再返回到原来被中断的中断服务程序继续执行。这就像你在处理手机消息(执行中断服务程序)时,突然来了一个紧急电话(更高优先级的中断源),你会暂停处理消息(暂停当前中断服务程序),先去接电话(处理更高优先级的中断服务程序),接完电话后再回来继续处理消息(返回原来的中断服务程序继续执行)。在 STM32F103C8T6 中,要实现中断嵌套,需要正确配置 NVIC 的优先级分组,将抢占优先级设置为不同的值,使得高优先级的中断能够打断低优先级的中断。例如,将外部中断 0 的抢占优先级设置为 1,外部中断 1 的抢占优先级设置为 2,当外部中断 0 正在执行中断服务程序时,如果外部中断 1 产生中断请求,由于外部中断 0 的抢占优先级更高,所以不会被外部中断 1 打断;反之,如果外部中断 1 正在执行中断服务程序,外部中断 0 产生中断请求,那么外部中断 1 的中断服务程序会被暂停,优先执行外部中断 0 的中断服务程序。
(四)中断执行流程
中断请求:当某个中断源产生特定事件时,如按键按下、定时器溢出等,会向 CPU 发送中断请求信号。这个信号就像是一个紧急通知,告诉 CPU 有事情需要它立即处理。
中断响应:CPU 在每个指令周期结束时,会检查是否有中断请求。如果有,且中断允许位被设置(即中断未被屏蔽),CPU 会暂停当前正在执行的程序,将当前的程序计数器(PC)、程序状态寄存器(PSR)等重要寄存器的值压入堆栈进行保存,这一步就像是在离开之前记录好自己的位置和状态。然后,CPU 根据中断向量表找到对应的中断服务程序的入口地址,跳转到中断服务程序开始执行。中断向量表就像是一个索引表,记录了每个中断源对应的中断服务程序的入口地址。
中断服务:在中断服务程序中,首先会保护现场,即将其他需要用到的寄存器的值也压入堆栈保存,防止这些数据在中断处理过程中被破坏。然后,根据中断源的具体需求,执行相应的处理代码,比如读取传感器数据、处理按键事件等。处理完成后,再恢复现场,将之前压入堆栈的寄存器的值弹出,恢复到原来的状态。
中断返回:当中断服务程序执行完毕,最后会执行中断返回指令。这时候,CPU 会从堆栈中弹出之前保存的程序计数器(PC)和程序状态寄存器(PSR)的值,回到原来被中断的程序处继续执行,就像完成了紧急任务后,又回到原来的工作中。
三、STM32 中断系统
(一)STM32 中断资源
STM32F103C8T6 拥有丰富的中断资源,为嵌入式系统的多样化需求提供了有力支持。它包含多达 60 个可屏蔽中断通道 ,涵盖了众多关键的外设中断。
其中,EXTI(External Interrupt/Event Controller,外部中断 / 事件控制器)是其外部中断的核心。EXTI 可以监测指定 GPIO 口的电平信号,当指定 GPIO 口产生电平变化时,能立即向 NVIC 发出中断申请。例如,在智能安防系统中,我们可以将外部入侵检测传感器连接到 STM32F103C8T6 的某个 GPIO 口,并通过 EXTI 配置为上升沿触发中断。当传感器检测到有人入侵,输出电平发生变化时,就会触发中断,通知系统进行相应的处理,如启动报警装置、记录入侵时间等。
除了 EXTI,定时器中断(TIM)也是常用的中断资源之一。STM32F103C8T6 的定时器功能强大,有基本定时器(TIM6、TIM7)、通用定时器(TIM2、TIM3、TIM4、TIM5)和高级定时器(TIM1)。这些定时器可以用于精确计时、PWM 信号生成、事件触发等多种场景。以工业电机控制为例,通用定时器可以配置为 PWM 模式,生成不同占空比的 PWM 信号来控制电机的转速和转向。同时,通过定时器中断,可以实现周期性地读取电机的运行状态,如电流、温度等,以便及时调整控制策略,确保电机的稳定运行。
此外,ADC(Analog - to - Digital Converter,模数转换器)中断在数据采集领域发挥着重要作用。当 ADC 完成一次模数转换时,会触发中断,通知 CPU 读取转换后的数据。在环境监测项目中,通过 ADC 中断,可以实时采集温度、湿度、光照等传感器的模拟信号,并将其转换为数字信号进行处理和存储。
还有串口通信(USART)中断、SPI 通信中断、I2C 通信中断等,为 STM32F103C8T6 与外部设备的数据交互提供了高效的中断处理机制。在智能家居系统中,通过串口通信中断,STM32 可以与各类智能设备进行通信,接收设备的状态信息,发送控制指令,实现家居设备的智能化控制。
(二)NVIC(嵌套向量中断控制器)
1. 基本结构
NVIC 作为 Cortex - M3 内核的重要组成部分,就像是 CPU 的得力助手,负责管理中断的方方面面。它的结构设计精妙,与 CPU 和中断源之间有着紧密的连接 。从硬件层面来看,NVIC 一端连接着众多的中断源,这些中断源来自于 STM32F103C8T6 的各个外设,如前面提到的 EXTI、TIM、ADC 等;另一端则与 CPU 紧密相连,直接参与中断的裁决和处理流程。
当多个中断源同时向 CPU 申请中断时,NVIC 就发挥了关键的调度作用。它不会让 CPU 直接面对混乱的中断请求,而是像一个有序的调度员,先对中断请求进行收集和整理。NVIC 根据每个中断源预先设定的优先级,对这些中断请求进行排序,然后将优先级最高的中断请求传递给 CPU。这样一来,CPU 只需专注于处理 NVIC 筛选后的中断,大大提高了中断处理的效率和准确性。
例如,假设同时有定时器中断和串口中断申请,NVIC 会先查看它们的优先级设置。如果定时器中断的优先级高于串口中断,NVIC 就会将定时器中断请求传递给 CPU,让 CPU 优先处理定时器中断。在这个过程中,串口中断请求会被暂时挂起,等待 CPU 处理完当前的高优先级中断。
2. 优先级分组
在 NVIC 中,中断优先级分为抢占优先级和响应优先级,这两个概念对于理解中断的处理顺序至关重要。
抢占优先级:它决定了中断是否可以打断其他正在执行的中断,实现中断嵌套。简单来说,具有高抢占优先级的中断可以在低抢占优先级的中断处理过程中被响应。例如,在一个实时控制系统中,可能有一个紧急故障检测中断,其抢占优先级设置得很高。当系统正在处理普通的定时器中断时,如果紧急故障检测中断发生,由于其抢占优先级更高,就会立即打断定时器中断的处理,转而执行紧急故障检测中断服务程序。这样可以确保系统能够及时响应紧急事件,避免因处理普通中断而延误对关键问题的处理。
响应优先级:当两个中断源的抢占优先级相同时,响应优先级就发挥了作用。它决定了在抢占优先级相同的情况下,中断的响应顺序。也就是说,当两个抢占优先级相同的中断同时到达时,响应优先级高的中断会先被处理。例如,假设有两个串口中断,它们的抢占优先级都设置为相同的值,但其中一个串口中断的响应优先级设置为 1,另一个设置为 2。那么当这两个串口中断同时发生时,响应优先级为 1 的串口中断会先被处理,处理完成后才会处理响应优先级为 2 的串口中断。
STM32F103C8T6 通过对优先级寄存器的 4 位进行分组设置,来确定抢占优先级和响应优先级的具体位数。总共有 5 种分组模式:
第 0 组:所有 4 位用于指定响应优先级,此时没有抢占优先级的区分,所有中断按照响应优先级的高低顺序处理。
第 1 组:最高 1 位用于指定抢占优先级,最低 3 位用于指定响应优先级。这样可以有 2 个抢占优先级级别(0 和 1),8 个响应优先级级别(0 - 7)。
第 2 组:最高 2 位用于指定抢占优先级,最低 2 位用于指定响应优先级。有 4 个抢占优先级级别(0 - 3),4 个响应优先级级别(0 - 3)。
第 3 组:最高 3 位用于指定抢占优先级,最低 1 位用于指定响应优先级。有 8 个抢占优先级级别(0 - 7),2 个响应优先级级别(0 和 1)。
第 4 组:所有 4 位用于指定抢占优先级,没有响应优先级的区分,中断按照抢占优先级的高低顺序处理。
在实际应用中,我们可以根据项目的需求,使用固件库函数NVIC_PriorityGroupConfig()
来选择合适的优先级分组模式。例如,如果我们的项目中需要较多的抢占优先级级别来处理不同紧急程度的中断,就可以选择第 3 组或第 4 组;如果项目中对响应优先级的区分要求较高,而抢占优先级的需求相对简单,就可以选择第 1 组或第 2 组。通过合理配置优先级分组和每个中断源的优先级,我们能够优化系统的中断处理机制,提高系统的性能和稳定性。
四、EXTI(外部中断)
(一)EXTI 介绍
工作原理:EXTI(External Interrupt/Event Controller)作为 STM32F103C8T6 中负责外部中断的关键部件,其工作原理精妙而高效。它就像一个时刻保持警惕的信号监测员,持续监测着指定 GPIO 口的电平信号 。当指定 GPIO 口的电平发生变化时,比如从低电平变为高电平(上升沿),或者从高电平变为低电平(下降沿),EXTI 会迅速捕捉到这个变化,并立即向 NVIC(Nested Vectored Interrupt Controller,嵌套向量中断控制器)发出中断申请。NVIC 在收到申请后,会根据预先设定的中断优先级进行裁决,决定是否中断当前正在运行的 CPU 主程序。如果裁决结果是允许中断,那么 CPU 就会暂停主程序的执行,转而执行 EXTI 对应的中断服务程序。在中断服务程序中,开发者可以编写相应的代码来处理这个中断事件,比如读取传感器数据、控制外部设备等。处理完成后,CPU 会返回原来被中断的主程序位置,继续执行主程序。