NVIC中断

本周学习NVIC中断,总结起来主要是三个方面:中断优先级分组,中断优先级设置和总结

概述

STM32F40xx/STM32F41xx总共有92个中断。
STM32F42xx/STM32F43xx则总共有96个中断。
我所用的是STM32F407ZGT6,共92个中断,92个中断里面,包括10个内核中断和82个可屏蔽中断,具有16级可编程的中断优先级,而常用的就是这82个可屏蔽中断。
内核中断
NVIC中断82个可屏蔽中断
NVIC中断

NVIC中断优先级分组

首先,对STM32中断进行分组,组0~4。同时,对每个中断设置一个抢占优先级和一个响应优先级值。
NVIC中断AIRCR是寄存器有3位, 4-0组,依次为011,100,101,110,111. IP共4位用于抢占优先级和响应优先级的分配。
抢占优先级 & 响应优先级区别:
高优先级的抢占优先级是可以打断正在进行的低抢占优先级中断的。
抢占优先级相同的中断,高响应优先级不可以打断低响应优先级的中断。
抢占优先级相同的中断,当两个中断同时发生的情况下,哪个响应优先级高,哪个先执行。
如果两个中断的抢占优先级和响应优先级都是一样的话,则看哪个中断先发生就先执行;

举例:假定设置中断优先级组为2,然后设置
中断3(RTC中断)的抢占优先级为2,响应优先级为1。 中断6(外部中断0)的抢占优先级为3,响应优先级为0。中断7(外部中断1)的抢占优先级为2,响应优先级为0。

那么这3个中断的优先级顺序为:中断7>中断3>中断6
需加注意的是系统代码执行过程中,只设置一次中断优先级分组,以后不会再改变
具体函数:void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup);

中断优先级设置

中断设置相关寄存器
__IO uint8_t IP[240]; //中断优先级控制的寄存器组
__IO uint32_t ISER[8]; //中断使能寄存器组
__IO uint32_t ICER[8]; //中断失能寄存器组
__IO uint32_t ISPR[8]; //中断挂起寄存器组
__IO uint32_t ICPR[8]; //中断解挂寄存器组
__IO uint32_t IABR[8]; //中断**标志位寄存器组
MDK中NVIC寄存器结构体
typedef struct
{
__IO uint32_t ISER[8];
uint32_t RESERVED0[24];
__IO uint32_t ICER[8];
uint32_t RSERVED1[24];
__IO uint32_t ISPR[8];
uint32_t RESERVED2[24];
__IO uint32_t ICPR[8];
uint32_t RESERVED3[24];
__IO uint32_t IABR[8];
uint32_t RESERVED4[56];
__IO uint8_t IP[240];
uint32_t RESERVED5[644];
__O uint32_t STIR;
} NVIC_Type;
中断优先级控制的寄存器组:IP[240] 全称是:Interrupt Priority Registers
240个8位寄存器,每个中断使用一个寄存器来确定优先级。STM32F40x系列一共82个可屏蔽中断,使用IP[81]~IP[0]。
每个IP寄存器的高4位用来设置抢占和响应优先级(根据分组),低4位没有用到。

总结

中断优先级设置步骤

  1. 系统运行后先设置中断优先级分组。调用函数: void NVIC_PriorityGroupConfig(uint32_tNVIC_PriorityGroup);

  2. 整个系统执行过程中,只设置一次中断分组。 针对每个中断,设置对应的抢占优先级和响应优先级:
    void NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct);

  3. 如果需要挂起/解挂,查看中断当前**状态,分别调用相关函数即可。