目录
文章目录
前言
STM32F4
中断
NVIC
简介
NVIC
是嵌套向量中断控制器,控制着整个芯片中断相关的功能,它跟内核紧密耦合,是内核里面的一个外设。但是各个芯片厂商在设计芯片的时候会对Cortex-M4
内核里面的NVIC
进行裁剪,把不需要的部分去掉,所以说STM32
的NVIC
是Cortex-M4
的NVIC
的一个子集。
STM32F4
的每个IO
都可以作为外部中断的中断输入口。STM32F407
的中断控制器支持22个外部中断/事件请求。每个中断设有状态位,每个中断/事件都有独立的触发和屏蔽设置。
优先级定义
在NVIC
有一个专门的寄存器:中断优先级寄存器NVIC_IPRx
用来配置外部中断的优先级,IPR
宽度为8bit
,原则上每个外部中断可配置的优先级为0~255
,数值越小,优先级越高。在STM32F4
中使用了高4位设置中断优先级,也就是有16个可编程优先级。
中断优先级被分组为抢占优先级和子优先级。如果有多个中断同时响应,抢占优先级高的就会抢占抢占优先级低的优先得到执行,如果抢占优先级相同,就比较子优先级。如果抢占优先级和子优先级都相同的话,就比较他们的硬件中断编号,编号越小,优先级越高。
NVIC_InitTypeDef
结构体
typedef struct
{
uint8_t NVIC_IRQChannel; // 设置中断源,不同的中断源不一样
uint8_t NVIC_IRQChannelPreemptionPriority; // 抢占优先级
uint8_t NVIC_IRQChannelSubPriority; // 子优先级
FunctionalState NVIC_IRQChannelCmd; // 中断使能
} NVIC_InitTypeDef;
EXTI
外部中断/事件控制器
STM32F4 IO
口都可以作为外部中断的中断输入口。STM32F4
的中断控制器支持23个外部中断/事件请求的边沿检测器。每根输入线都可单独进行配置,以选择类型(中断或者事件)和相应的触发事件(上升沿触发、下降沿触发或者边沿触发)。每根输入线还可单独屏蔽。挂起寄存器用于保持中断请求的状态线。
EXTI
功能框图
编号1是输入线,EXTI
控制器有23个中断/事件输入线,这些输入可以通过寄存器设置为任意一个GPIO
,也可以是一些外设的事件,输入线一般是存在电平变化的信号。
编号2是一个边沿检测电路,它会根据上升沿触发选择寄存器(EXTI_RTSR
)和下降沿触发选择寄存器(EXTI_FTSR
)对应为的设置来控制信号触发。边沿检测电路以输入线作为信号输入端,如果检测到有边沿跳变就输出有效信号1给编号3电路,否则输出无效信号0。
编号4电路是一个与门电路,它的一个输入为编号3电路,另外一个输入来自中断屏蔽寄存器(EXTI_IMR
)。与门电路要求输入都为1才输出1,导致的结果如果EXTI_IMR
设置为0时,不管编号3电路的输出信号是1还是0,最终编号4电路输出的信号都为0;如果EXTI_IMR
设置为1时,最终编号4电路输出的信号才由编号3电路的输出信号决定,这样我们就可以简单控制EXTI_IMR
来实现是否产生中断的目的。编号4电路输出的信号会被保存到挂起寄存器中(EXTI_PR
)内,如果确定编号4电路输出为1就会把EXTI_PR
对应位置1.
编号5是将EXTI_PR
寄存器内容输出到NVIC
内,从而实现系统中断事件控制。
产生中断线路目的是把输入信号输入到NVIC
,进一步会运行中断服务函数,实现功能,这是软件级的。
EXTI初始化结构体详解
typedef struct
{
uint32_t EXTI_Line; // EXTI_Line:EXTI中断/事件线选择,可选EXTI0或EXTI22
EXTIMode_TypeDef EXTI_Mode; // EXTI_Mode:EXTI模式选择,可选为产生中断(EXTI_Mode_Interrupt)或者产生事件(EXTI_Mode_Event)
EXTIMode_TypeDef EXTI_Mode; // EXTI边沿触发事件,可选上升沿(EXTI_Trigger_Rising)、下降沿触发(EXTI_Trigger_Falling)或者上升沿和下降沿都触发(EXTI_Trigger_Rising_Falling)
FunctionalState EXTI_LineCmd; // 控制是否使能EXTI线,可选使能EXTI线(ENABLE)或禁用(DISABLE)
}EXTI_InitTypeDef;
IO
口外部中断的一般步骤
- 使能
IO
口时钟,初始化IO
口为输入 - 使能
SYSCFG
时钟,设置IO
口与中断线的映射关系 - 初始化线上中断,设置触发条件等
- 配置中断分组(
NVIC
),并使能中断 - 编写中断服务函数
注意:中断服务函数在库函数中都特定的名称,可以看作是默认的环境变量。也就是在NVIC
检测到对应的中断的时候,就会去找到对应的中断服务函数标号。我使用的是正点原子的STM32F407
,其中的所有中断标号在这个文件中:startup_stm32f40xx.s
以下是部分代码截取:
EXPORT EXTI0_IRQHandler [WEAK]
EXPORT EXTI1_IRQHandler [WEAK]
EXPORT EXTI2_IRQHandler [WEAK]
EXPORT EXTI3_IRQHandler [WEAK]
EXPORT EXTI4_IRQHandler [WEAK]
总结
曾经对中断理解的不是很深刻,但是现在稍微花半天的时间就理解了STM32
的中断的大概设计!感觉就是到了一定的层次以后,学起来就会容易很多!
总的来说,外部中断作用于外设,也就是外设产生中断信号的机制就是外部中断,最终输入的外部中断信号给了NVIC
;而NVIC
是STM32
的内部中断外设,是STM32
的内部中断机制,NVIC
的输入是外部中断等一系列中断信号,NVIC
主要就是在接收到这些外部中断信号之后,反馈输出,对中断信号进行处理。
链接地址
《零死角玩转STM32—F429挑战者.pdf》
《STM32F4开发指南-库函数版本_V1.1.pdf》