STM32嵌套中断向量控制器NVIC

一、嵌套终端向量控制器NVIC

1.1NVIC介绍

NVIC(Nest Vector Interrupt Controller),嵌套中断向量控制器,作用是管理中断嵌套 先级。 核心任务是管理中断优

管理中断嵌套:我们在处理某个中断的过程中还没处理完这个中断,又来了一个中断,是否可以打断这个中断,不能就存在中断嵌套

特点:

68个可屏蔽中断通道(不包含16个Cortex-M3的中断线)

16个可编程的优先等级(使用了4位中断优先级)

低延迟的异常和中断处理

电源管理控制

系统控制寄存器的实现

12.优先级

抢占优先级和响应优先级

拥有较高抢占优先级的中断可以打断抢占优先级较低的中断

若两个抢占优先级的中断同时挂起,则优先执行响应优先级较高的中断

若两个挂起的中断优先级都一致,则优先执行位于中断向量表中位置较高的中断

响应优先级不会造成中断嵌套,也就是说中断嵌套是由抢占优先级决定的(抢占优先级数字越小,优先级越高)

8种分配方式:

所有8位全部用于指定响应优先级

第7位用于指定抢占式优先级,0-6位用于指定响应优先级

6-7位用于指定抢占式优先级,0-5位用于指定响应优先级

5-7位用于指定抢占式优先级,0-4位用于指定响应优先级

4-7位用于指定抢占式优先级,0-3位用于指定响应优先级

3-7位用于指定抢占式优先级,0-2位用于指定响应优先级

2-7位用于指定抢占式优先级,0-1位用于指定响应优先级

1-8位田干指定给上式优牛级 0位田干指定响应伏牛级

Cortex-M3允许具有较少中断源时使用较少的寄存器位指定中断源的优先级,因此STM32中断优先级的寄存器位只 用到AIRCR高四位,共有以下几种组合:

第0组:所有4位用于指定响应优先级

第1组:第7位用于指定抢占式优先级, 4-6位用于指定响应优先级 '

第2组:第6-7位用于指定抢占式优先级, 4-5位用于指定响应优先级

第3组:第5-7位用于指定抢占式优先级,第4位用于指定响应优先级 第4组:

所有4位用于指定抢占式优先级
使用固件库函数配置中断优先级得方法(misc.c中定义):
1 /**
2 * @brief Configures the priority grouping : pre ‐ emption priority and
3 * subpriority .
4 * @param NVIC_PriorityGroup : specifies the priority grouping bits 5 * length .
6 * This parameter can be one of the following values :
7 * @arg NVIC_PriorityGroup_0 : 0 bits for pre ‐ emption priority
8 * 4 bits for subpriority
9 * @arg NVIC_PriorityGroup_1 : 1 bits for pre ‐ emption priority
10 * 3 bits for subpriority
11 * @arg NVIC_PriorityGroup_2 : 2 bits for pre ‐ emption priority
12 * 2 bits for subpriority
13 * @arg NVIC_PriorityGroup_3 : 3 bits for pre ‐ emption priority
14 * 1 bits for subpriority
15 * @arg NVIC_PriorityGroup_4 : 4 bits for pre ‐ emption priority
16 * 0 bits for subpriority
17 * @retval None
18 */
19 void NVIC_PriorityGroupConfig ( uint32_t NVIC_PriorityGroup )
优先级组确定后,可以根据优先级组来配置对应IRQ的抢占优先级和响应优先级

1.3NVIC初始化

每个外部中断都由NVIC统一进行管理,所以NVIC包含了中断功能的使能和失能,优先级的
配置等功能。
固件库中关于NVIC的初始化函数
1 /**
2 * @brief Initializes the NVIC peripheral according to the specified
3 * parameters in the NVIC_InitStruct .
4 * @param NVIC_InitStruct : pointer to a NVIC_InitTypeDef structure
5 * that contains
6 * the configuration information for the specified NVIC
7 * peripheral .
8 * @retval None
9 */
10 void NVIC_Init ( NVIC_InitTypeDef * NVIC_InitStruct )
11
形参变量说明:
1 typedef struct
2 {
3 uint8_t NVIC_IRQChannel ;
4 uint8_t NVIC_IRQChannelPreemptionPriority ; 5 uint8_t NVIC_IRQChannelSubPriority ;
6 FunctionalState NVIC_IRQChannelCmd ;
7 }
1.NVIC_IRQChannel:外部中断通道(在stm32f10x.h中定义)
1 typedef enum IRQn
2 {
3 NonMaskableInt_IRQn = ‐ 14 , /*!< 2 Non Maskable Interrupt*/
4 MemoryManagement_IRQn = ‐ 12 , /*!< 4 Cortex‐M3 Memory Management Interrup
t*/
5 BusFault_IRQn = ‐ 11 , /*!< 5 Cortex‐M3 Bus Fault Interrupt*/
6 UsageFault_IRQn = ‐ 10 , /*!< 6 Cortex‐M3 Usage Fault Interrupt*/
7 SVCall_IRQn = ‐ 5 , /*!< 11 Cortex‐M3 SV Call Interrupt*/
8 DebugMonitor_IRQn = ‐ 4 , /*!< 12 Cortex‐M3 Debug Monitor Interrupt*/
9 PendSV_IRQn = ‐ 2 , /*!< 14 Cortex‐M3 Pend SV Interrupt*/
10 SysTick_IRQn = ‐ 1 , /*!< 15 Cortex‐M3 System Tick Interrupt*/
11
12 WWDG_IRQn = 0 , /*!< Window WatchDog Interrupt*/
13 PVD_IRQn = 1 , /*!< PVD through EXTI Line detection Interrupt*/
14 TAMPER_IRQn = 2 , /*!< Tamper Interrupt*/
15 RTC_IRQn = 3 , /*!< RTC global Interrupt*/
16 FLASH_IRQn = 4 , /*!< FLASH global Interrupt*/
17 RCC_IRQn = 5 , /*!< RCC global Interrupt*/
18 EXTI0_IRQn = 6 , /*!< EXTI Line0 Interrupt*/
19 EXTI1_IRQn = 7 , /*!< EXTI Line1 Interrupt*/
20 EXTI2_IRQn = 8 , /*!< EXTI Line2 Interrupt*/
21 EXTI3_IRQn = 9 , /*!< EXTI Line3 Interrupt*/
22 EXTI4_IRQn = 10 , /*!< EXTI Line4 Interrupt*/
23 DMA1_Channel1_IRQn = 11 , /*!< DMA1 Channel 1 global Interrupt*/
24 DMA1_Channel2_IRQn = 12 , /*!< DMA1 Channel 2 global Interrupt*/
25 DMA1_Channel3_IRQn = 13 , /*!< DMA1 Channel 3 global Interrupt*/
26 DMA1_Channel4_IRQn = 14 , /*!< DMA1 Channel 4 global Interrupt*/
27 DMA1_Channel5_IRQn = 15 , /*!< DMA1 Channel 5 global Interrupt*/
28 DMA1_Channel6_IRQn = 16 , /*!< DMA1 Channel 6 global Interrupt*/
29 DMA1_Channel7_IRQn = 17 , /*!< DMA1 Channel 7 global Interrupt*/
30 ...
31 }
2.NVIC_IRQChannelPreemptionPriority:抢占优先级(最大取值15)
3.NVIC_IRQChannelSubPriority:响应优先级(最大取值15) 4.NVIC_IRQChannelCmd:(ENABLE/DISABLE)
使能/失能对应的中断通道
GPIO的外部中断触发方式为高电平触发上升沿触发,上升沿触发一个中断交由EXTI中断控制器进行管理,再往上给到nvic,你想由cpu响应中断,首先由nvic管理,nvic给没个中断一个管理开关,没有nvic的管理就没有cpu对于中断的响应

1.4中断的具体行为

当CM3开始响应一个中断时,会做如下动作:
入栈: 把8个寄存器的值压入栈
取向量:从向量表中找出对应的服务程序入口地址
选择堆栈指针MSP(主堆栈)/PSP(进程堆栈),更新堆栈指针SP,更新链接寄存器
LR,更新程序计数器PC
1.4.1、入栈
响应异常的第一个动作,就是自动保存现场,依次把xPSR、PC, LR, R12以及R3-R0由

件寄存器自动压入适当的堆栈中。
1.4.2、取向量
数据总线(系统总线)在执行入栈的时候,指令总线从向量表中找出正确的异常向量,
然后在服务程序的入口处预取指。
(由此可以看到各自都有专用总线的好处:入栈与取指这两个工作能同时进行)
1.4.3、更新寄存器
在入栈和取向量操作完成之后,执行服务例程之前,还要更新一系列的寄存器.
SP:在入栈后会把堆栈指针更新到新的位置。在执行服务例程时,将由MSP负
责对堆栈的
访问。
PSR:更新IPSR位段的值为新响应的异常编号。
PC:在取向量完成后,PC将指向服务例程的入口地址,
LR:在出入ISR(Interrupt Service Routines)中断服务程序的时候,LR的值
将得到更新
(在异常进入时由系统计算并赋给LR,并在异常返回时使用它
1.5、异常/中断返回
当异常服务例程执行完毕后,需要恢复先前的系统状态,才能使被中断的程序得以继续执
行。
异常/中断处理完成后,执行如下处理:
出栈:恢复先前压入栈中的寄存器,堆栈指针的值也改回先前的值 更新NVIC寄存器:伴随着异常的返回,它的活动位也被硬件清除

二、外部中断

对于互联型产品,外部中断/事件控制器由20个产生事件/中断请求的边沿检测器组成,
对于其它
产品,则有19个能产生事件/中断请求的边沿检测器。每个输入线可以独立地配置输入类型
和对应的触发事件(上升沿或下降沿或者双边沿都触发)。每个输入线都可以独立地被屏蔽。
挂起寄存器保持着状态线的中断请求
EXTI 可分为两大部分功能,一个是产生中断,另一个是产生事件:
中断:
信号从输入线输入,经过边沿检测电路来控制信号触发(根据上升沿下降沿触发选择寄
存器的设置来控制),如果检测到有效信号后,将该有效信号输出到或门电路,由红色箭头
方向经过请求挂起寄存器和中断屏蔽寄存器,到达与门电路,条件满足送至NVIC
事件:
信号从输入线输入,经过边沿检测电路来控制信号触发(根据上升沿下降沿触发选择寄存器
的设置来控制),如果检测到有效信号后,将该有效信号输出到或门电路,由蓝色箭头方向
经过与门电路,送至买脉冲发生器,产生脉冲。这个脉冲信号可以给其他外设电路使用,比
如定时器 TIM、模拟数字转换器 ADC等等,这样的脉冲信号一般用来触发 TIM 或者 ADC
开始转换。
事件和中断的区别: 产生中断线路目的是把输入信号输入到 NVIC,进一步会运行中断服务函数,实现功能,这
样是软件级的。而产生事件线路目的就是传输一个脉冲信号给其他外设使用,并且是电路级
别的信号传输,属于硬件级的。
2.1、主要特性
每个中断/事件都有独立的触发和屏蔽
每个中断线都有专用的状态位
支持多达20个软件的中断/事件请求
检测脉冲宽度低于APB2时钟宽度的外部信号
2.2、外部中断/事件线路映像
通用I/O端口以下图的方式连接到16个外部中断/事件线上
另外四个EXTI线的连接方式如下:
● EXTI线16连接到PVD输出
● EXTI线17连接到RTC闹钟事件
● EXTI线18连接到USB唤醒事件
● EXTI线19连接到以太网唤醒事件(只适用于互联型产品)
2.1、主要特性
每个中断/事件都有独立的触发和屏蔽
每个中断线都有专用的状态位
支持多达20个软件的中断/事件请求
检测脉冲宽度低于APB2时钟宽度的外部信号
2.2、外部中断/事件线路映像
通用I/O端口以下图的方式连接到16个外部中断/事件线上
另外四个EXTI线的连接方式如下:
● EXTI线16连接到PVD输出
● EXTI线17连接到RTC闹钟事件
● EXTI线18连接到USB唤醒事件
● EXTI线19连接到以太网唤醒事件(只适用于互联型产品
2.3、EXTI相关数据结构与函数说明 2.3.1、初始化函数
1 void EXTI_Init ( EXTI_InitTypeDef * EXTI_InitStruct )
参数:EXTI_InitStruct
1 typedef struct
2 {
3 uint32_t EXTI_Line ; // 中断线
4 EXTIMode_TypeDef EXTI_Mode ; // 中断模式
5 EXTITrigger_TypeDef EXTI_Trigger ; // 中断触发方式
6 FunctionalState EXTI_LineCmd ; // 中断功能使能
7 }
@EXTI_Line
1 #define EXTI_Line0 (( uint32_t ) 0x00001 ) /*!< External interrupt line 0 */
2 #define EXTI_Line1 (( uint32_t ) 0x00002 ) /*!< External interrupt line 1 */
3 #define EXTI_Line2 (( uint32_t ) 0x00004 ) /*!< External interrupt line 2 */
4 #define EXTI_Line3 (( uint32_t ) 0x00008 ) /*!< External interrupt line 3 */
5 #define EXTI_Line4 (( uint32_t ) 0x00010 ) /*!< External interrupt line 4 */
6 #define EXTI_Line5 (( uint32_t ) 0x00020 ) /*!< External interrupt line 5 */
7 #define EXTI_Line6 (( uint32_t ) 0x00040 ) /*!< External interrupt line 6 */
8 #define EXTI_Line7 (( uint32_t ) 0x00080 ) /*!< External interrupt line 7 */
9 #define EXTI_Line8 (( uint32_t ) 0x00100 ) /*!< External interrupt line 8 */
10 #define EXTI_Line9 (( uint32_t ) 0x00200 ) /*!< External interrupt line 9 */
11 #define EXTI_Line10 (( uint32_t ) 0x00400 ) /*!< External interrupt line 10
*/
12 #define EXTI_Line11 (( uint32_t ) 0x00800 ) /*!< External interrupt line 11
*/
13 #define EXTI_Line12 (( uint32_t ) 0x01000 ) /*!< External interrupt line 12
*/
14 #define EXTI_Line13 (( uint32_t ) 0x02000 ) /*!< External interrupt line 13
*/
15 #define EXTI_Line14 (( uint32_t ) 0x04000 ) /*!< External interrupt line 14
*/
16 #define EXTI_Line15 (( uint32_t ) 0x08000 ) /*!< External interrupt line 15
*/
17 #define EXTI_Line16 (( uint32_t ) 0x10000 ) /*!< External interrupt line 16
Connected to the PVD Output */
18 #define EXTI_Line17 (( uint32_t ) 0x20000 ) /*!< External interrupt line 17
Connected to the RTC Alarm event */
19 #define EXTI_Line18 (( uint32_t ) 0x40000 ) /*!< External interrupt line 18
Connected to the USB Device/USB OTG FS 20 Wakeup from suspend event */
21 #define EXTI_Line19 (( uint32_t ) 0x80000 ) /*!< External interrupt line 19
Connected to the Ethernet Wakeup event */
@EXTI_Mode
1 typedef enum
2 {
3 EXTI_Mode_Interrupt = 0x00 , // 中断模式
4 EXTI_Mode_Event = 0x04 // 事件模式
5 } EXTIMode_TypeDef ;
@EXTI_Trigger
1 typedef enum
2 {
3 EXTI_Trigger_Rising = 0x08 , // 上升沿触发
4 EXTI_Trigger_Falling = 0x0C , // 下降沿触发
5 EXTI_Trigger_Rising_Falling = 0x10 // 双边沿触发
6 } EXTITrigger_TypeDef ;
@EXTI_LineCmd
1 ENABLE
2 DISABLE
2.3.2、获取中断状态
1 // 参数:中断线
2 ITStatus EXTI_GetITStatus ( uint32_t EXTI_Line );
2.3.3、清空中断标志位
1 // 参数:中断线
2 void EXTI_ClearITPendingBit ( uint32_t EXTI_Line );
2.3.4、软件产生中断
1 void EXTI_GenerateSWInterrupt ( uint32_t EXTI_Line )
2.4、中断回调函数
在startup_stm32f10x_xx.s中的中断向量表里:
1 DCD EXTI0_IRQHandler ; EXTI Line 0
2 DCD EXTI1_IRQHandler ; EXTI Line 1
3 DCD EXTI2_IRQHandler ; EXTI Line 2
4 DCD EXTI3_IRQHandler ; EXTI Line 3
5 DCD EXTI4_IRQHandler ; EXTI Line 4 6 DCD EXTI9_5_IRQHandler ; EXTI Line 9..5
7 DCD EXTI15_10_IRQHandler ; EXTI Line 15..10

相关推荐
hollq2 小时前
STM32F103RCT6+STM32CubeMX+keil5(MDK-ARM)+Flymcu实现串口重定向
arm开发·stm32·嵌入式硬件
小鱼儿电子4 小时前
17-基于STM32的宠物饲养系统设计与实现
stm32·嵌入式硬件·物联网·宠物·宠物饲养系统
小莞尔5 小时前
【51单片机】【protues仿真】基于51单片机四层电梯系统
单片机·嵌入式硬件
CFZPL5 小时前
使用江科大串口发送函数发送freertos的vTaskList出现跑飞
单片机
F133168929576 小时前
WD5030A,24V降5V,15A 大电流,应用于手机、平板、笔记本充电器
stm32·单片机·嵌入式硬件·51单片机·硬件工程·pcb工艺
易享电子7 小时前
基于单片机电器断路器保护器系统Proteus仿真(含全部资料)
单片机·嵌入式硬件·fpga开发·51单片机·proteus
爱倒腾的老唐9 小时前
01、如何学习单片机
单片机·嵌入式硬件·学习
点灯小铭10 小时前
基于单片机的夹具压力控制系统设计
单片机·嵌入式硬件·mongodb·毕业设计·课程设计
雾削木15 小时前
stm32解锁芯片
javascript·stm32·单片机·嵌入式硬件·gitee
热爱编程的小刘17 小时前
STM32学习路线开启篇:外部中断
stm32