目录
一、中断的基本概念
在STM32中,中断系统是一种非常强大的功能,他允许CPU在执行代码的时候,暂停当前任务,然后转而执行特定的中断服务函数(ISR),处理完成后,再返回主函数中继续执行原来的代码。这种机制使得STM32能够高效的相应外部事件和内部状态变化,无需不断的轮询检测,从而大大提高了CPU的利用率。
中断是一种异步事件的处理机制,他打破了当前程序的执行流程。当中断发生时,当前任务会被中断,保存上下文(如寄存器的值,堆栈的指针等),然后跳转到中断向量表中找到对应的中断服务函数(ISR),去处理中断事件,处理完毕后,CPU会恢复原来的上下文,继续执行以前的任务。
STM32中内置了灵活且功能强大的中断寄存器(NVIC,Nested Vectored Interrupt Controller),他负责管理和分配中断(IQR)请求的优先级,处理程序的执行顺序,以及中断处理过程的调度。每一个中断源都有一个特定的中断号(IQRn),并通过中断向量表和相对应的ISR关联起来。
STM32中包含了68个可屏蔽中断通道,包含EXTI、TIM、ADC、USART、SPI、I2C、RTC等多个外设 使用NVIC统一管理中断,每个中断通道都拥有16个可编程的优先等级,可对优先级进行分组,进一步设置抢占优先级和响应优先级
下图是中断向量表
中断向量表是计算机系统中一个重要的组成部分,它用于存放中断向量,即中断类型号与对应的中断服务程序入口地址之间的映射关系。由于硬件原因CPU只能从某些特定的地址处访问中断函数,即只能从中断向量表中的地址去访问。我们写的中断服务函数,其名称和入口地址通常会在链接时被放置在中断向量表的相应位置。这样,当中断发生时,CPU就能根据中断向量表找到并跳转到我们编写的中断服务函数执行。
二、NVIC
1.NVIC的概念
NVIC(Nested Vectored Interrupt Controller)是STM32微控制器中的**中断控制器,它负责管理和处理微控制器的中断。(即相当于CPU的中断助手,帮助CPU来管理中断)**NVIC提供了灵活、高效、可扩展的中断处理机制,支持多级优先级、多向中断、嵌套向量中断等特性。其主要功能包括:
- 中断向量表:存储所有中断的服务程序地址,当中断发生时,CPU会根据中断向量表跳转到对应的中断服务程序执行。
- 中断优先级管理:允许为不同中断分配不同的优先级,以控制中断的响应顺序。NVIC的中断优先级由优先级寄存器的4位(0~15)决定,这4位可以进行切分,分为高n位的抢占优先级和低4-n位的响应优先级。抢占优先级高的中断可以打断低优先级的中断,实现中断嵌套。响应优先级高的中断在相同抢占优先级下可以优先排队。
- 中断使能和禁用:可以启用或禁用特定的中断,以便根据系统需求灵活控制中断的响应。
- 中断触发方式:支持多种中断触发方式,如上升沿、下降沿等,以满足不同中断源的需求。
2、NVIC的组成
NVIC由以下几个部分组成:
- 中断优先级和控制器:负责中断的挂起、解挂和优先级管理。
- 向量表:存储每个中断源对应的中断处理程序的入口地址。
- 系统控制寄存器:提供了对NVIC中断控制器的配置和控制。
- 特殊功能寄存器:NVIC中断控制器对外暴露的寄存器,用于实现对中断处理的控制,包括中断使能、中断标志、中断状态等。
3、NVIC的应用
NVIC在STM32中的应用非常广泛,主要包括以下几个方面:
- 中断优先级设置:用户可以根据不同的需求对中断优先级进行设置,以实现对中断的响应和处理。这有助于确保系统在有多个中断发生时能够高效地处理优先级较高的中断事件。
- 中断嵌套处理:NVIC支持中断嵌套处理,即高优先级的中断可以打断低优先级的中断。这有助于系统在处理紧急中断事件时能够迅速响应并处理。
- 低功耗模式下的中断管理:当CPU处于低功耗模式时,NVIC提供了挂起和解挂中断的机制,可以根据不同需求设置相应的中断使能和关闭。这有助于降低系统的功耗并延长电池寿命。
- 中断标志复位: NVIC提供了中断标志复位功能,可以清除某个中断事件的标志位。这在中断处理过后需要清除标志位的情况下尤为重要,以确保系统能够正确识别和处理后续的中断事件**。**
4.NVIC的结构
每一个中断都要被NVIC管理起来,所以一旦就中断产生,都要经过NVIC来确认优先级,才能被NVIC递交给CPU。
三、外部中断EXTI
1.外部中断的概念
对于互联型产品,外部中断/事件控制器由20个产生事件/中断请求的边沿检测器组成 ,对于其它产品,则有19个能产生事件/中断请求的边沿检测器。每个输入线可以独立地配置输入类型 (脉冲
或挂起)和对应的触发事件 (上升沿或下降沿或者双边沿都触发)。每个输入线都可以独立地被屏
蔽。挂起寄存器保持着状态线的中断请求。
EXTI可以监测指定GPIO口的电平信号,当其指定的GPIO口产生电平变化时,EXTI将立即向NVIC发出中断申请,**经过NVIC裁决后即可中断CPU主程序,**使CPU执行EXTI对应的中断程序 支持的触发方式:上升沿/下降沿/双边沿/软件触发 支持的GPIO口:所有GPIO口,但相同的Pin不能同时触发中断 通道数:16个GPIO_Pin,外加PVD输出、RTC闹钟、USB唤醒、以太网唤醒 触发响应方式:中断响应/事件响应
2.EXTI基本结构
从下图中可以看到,在初始化中,首先会通过APIO进行引脚选择,然后由AFIO将选择的引脚传递给EXTI进行边沿检测和控制。这时EXTI就开始检测被选择的引脚了,当中断来临的时候,EXTI就看看是哪一路中断发生了,然后通过对应的EXTI信道传递给NVIC。NVIC再来对中断进行管理:如果同时有多个中断来临,则判断优先级递交给CPU;如果来了优先级更高的中断,则进行中断嵌套等等。
下面的图片是AFIO的示意图。
AFIO就是一个选择器,当我们软件选择了某个引脚作为EXTI的时候,则AFIO会把这个引脚对应的线路连接到EXTIX上,从而实现后面的过程。但是从下面的图中可以看到,当Pin脚号相同的时候,只能有一个Pin脚被选中(即不能有同样的Pin脚作为EXTI)
四、EXTI外部中断的配置流程
配置STM32的中断系统通常需要经过以下几个步骤:
-
启用外设时钟:要启用与中断相关的外设(如GPIO、定时器等),首先需要为这些外设启用时钟。
-
配置外设为中断模式:根据中断源的类型,配置相应的外设为中断模式。例如,对于外部中断,需要配置对应的GPIO引脚为中断输入模式,并设置触发方式(如上升沿触发、下降沿触发或双边沿触发)。
-
配置NVIC:通过NVIC设置中断的优先级,并启用对应的中断。STM32的NVIC支持中断优先级的配置,可以通过相关函数设置中断的抢占优先级和子优先级。优先级较高的中断可以中断正在执行的低优先级中断处理程序。
-
编写ISR:为每个中断源编写相应的ISR(中断服务程序)。ISR是实际处理中断事件的函数,需要按照固定的函数原型编写。在ISR中,应首先检查中断发生标志,然后执行相应的中断处理逻辑,最后清除中断标志以准备下一次中断。
-
使能中断:确保在主函数中启用了外部中断并进入主循环。在主循环中,可以执行其他任务,等待中断的发生。
1.开启APB2中的GPIO口/AFIO时钟
按道理来说是需要开启NVIC和EXTI的时钟的,但是这两个时钟是由内部提供,无需我们手动开启,默认一直都是打开的状态,而且标准库中也没有相关的库函数
2.GPIO配置成输入模式
因为要检测外部中断,GPIO配置成输入模式是必然的
3.AFIO选择中断引脚
在这个函数中选择要对哪一个GPIO的哪一个Pin脚选中
4.EXTI初始化
初始化的结构体
结构体中的内容填充
5.NVIC配置
NVIC中断分组
注意 :在STM32的系统代码中,NVIC中断分组通常只设置一次,并且一旦设置后就不再更改。这是因为随意改变分组会导致中断管理混乱,程序可能出现意想不到的执行结果。因此,在系统初始化时,会根据需要选择一个合适的分组配置,并在整个系统运行过程中保持不变。
中断优先级的设置
用来初始化的结构体
NVIC_IRQChannel(中断请求信道)的定义
如此一来,EXTI外部中断的所有初始化配置就已经完成了,我们还需要一个中断服务函数
6.中断服务函数
中断服务函数与其他的函数不同,他被定义在启动文件Start_up_stm32f10x_md.s中,我们找的时候一定不要找到EXTI文件中了,否则是怎么样都找不到的。
在51单片机中,我们使用interrupt X的形式来定义中断服务函数的,在STM32中,中断服务函数的名字被限制死了,必须是中断向量表其中的名字。
中断向量表
在中断处理函数中,值得注意的一点是,为了节约资源,EXTI的10-15和5-9号中断函数都用的是一个相同的函数名,这使得我们在中断服务函数中必须要检测是哪个信道产生的中断,再来决定下一步的执行逻辑。此外,还需要我们手动清除中断标志位。
检测是哪一个中断信道产生的中断(检测中断挂起标志位)
清除中断挂起标志位
完整的中断服务函数就如下面这样