1. 什么是NVIC
NVIC :Nested Vectored Interrupt Controller,全称嵌套向量中断控制器,
1.1 相关结构体定义
1.1.1 NVIC 类型结构体定义
注:常用 ISER、ICER 和 IP 这三个寄存器,ISER 用来使能中断,ICER 用来失能中断,IP 用来设置中断优先级。
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;
1.1.2 NVIC 初始化结构体
用于初始化NVIC,指定中断源、优先级及使能或失能。
typedef struct
{
uint8_t NVIC_IRQChannel;
uint8_t NVIC_IRQChannelPreemptionPriority;
uint8_t NVIC_IRQChannelSubPriority;
FunctionalState NVIC_IRQChannelCmd;
} NVIC_InitTypeDef;
注:
1.2 相应固件库函数
1.2.1 NVIC_EnableIRQ 函数
在NVIC中断控制器中启用中断(使能)
static __INLINE void NVIC_EnableIRQ(IRQn_Type IRQn)
{
NVIC->ISER[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F));
}
1.2.2 NVIC_DisableIRQ 函数
禁用指定的外部中断
static __INLINE void NVIC_DisableIRQ(IRQn_Type IRQn)
{
NVIC->ICER[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F));
}
1.2.3 NVIC_GetPendingIRQ 函数
读取特定于设备的中断源的中断挂起位
static __INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn)
{
return((uint32_t) ((NVIC->ISPR[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0));
}
1.2.4 NVIC_SetPendingIRQ 函数
设置外部中断的挂起位
static __INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn)
{
NVIC->ISPR[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F));
}
1.2.5 NVIC_ClearPendingIRQ 函数
清除外部中断的挂起位
static __INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn)
{
NVIC->ICPR[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F));
}
1.2.6 NVIC_GetActive 函数
读取外部中断的有效位
static __INLINE uint32_t NVIC_GetActive(IRQn_Type IRQn)
{
return((uint32_t)((NVIC->IABR[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0));
}
1.2.7 NVIC_SetPriority 函数
设置中断的优先级
static __INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)
{
if(IRQn < 0) {
SCB->SHP[((uint32_t)(IRQn) & 0xF)-4] = ((priority << (8 - __NVIC_PRIO_BITS)) & 0xff); }
else {
NVIC->IP[(uint32_t)(IRQn)] = ((priority << (8 - __NVIC_PRIO_BITS)) & 0xff); }
}
1.2.8 NVIC_GetPriority 函数
读取中断的优先级
static __INLINE uint32_t NVIC_GetPriority(IRQn_Type IRQn)
{
if(IRQn < 0) {
return((uint32_t)(SCB->SHP[((uint32_t)(IRQn) & 0xF)-4] >> (8 - __NVIC_PRIO_BITS))); }
else {
return((uint32_t)(NVIC->IP[(uint32_t)(IRQn)] >> (8 - __NVIC_PRIO_BITS))); }
}
1.2.9 NVIC_SystemReset 函数
启动系统重置请求
static __INLINE void NVIC_SystemReset(void)
{
SCB->AIRCR = ((0x5FA << SCB_AIRCR_VECTKEY_Pos) |
(SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) |
SCB_AIRCR_SYSRESETREQ_Msk);
__DSB();
while(1);
}
1.2.10 NVIC_PriorityGroupConfig 函数
配置优先级分组:抢占优先级和子优先级。
#define NVIC_PriorityGroup_0 ((uint32_t)0x700)
#define NVIC_PriorityGroup_1 ((uint32_t)0x600)
#define NVIC_PriorityGroup_2 ((uint32_t)0x500)
#define NVIC_PriorityGroup_3 ((uint32_t)0x400)
#define NVIC_PriorityGroup_4 ((uint32_t)0x300)
void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup)
{
assert_param(IS_NVIC_PRIORITY_GROUP(NVIC_PriorityGroup));
SCB->AIRCR = AIRCR_VECTKEY_MASK | NVIC_PriorityGroup;
}
|