NVIC是stm32内核的中断,下面给出在cm3权威指南中关于nvic的描述:
8.2 中断配置基础 每个外部中断都在 NVIC 的下列寄存器中“挂号”:
使能与除能寄存器
悬起与“解悬”寄存器
优先级寄存器
活动状态寄存器
另外,下列寄存器也对中断处理有重大影响
异常掩蔽寄存器(PRIMASK, FAULTMASK 以及 BASEPRI)
向量表偏移量寄存器
软件触发中断寄存器
优先级分组位段
说明在nvic中有一张表(一连串的地址),记录了每一个中断的使能位,优先位
下面再来看看中断初始化的函数nvic的初始化结构体nvic_inittypedef和初始化函数nvic_init
typedef struct {
u8 NVIC_IRQChannel;//中断号
u8 NVIC_IRQChannelPreemptionPriority;//抢占优先级
u8 NVIC_IRQChannelSubPriority;//响应优先级
FunctionalState NVIC_IRQChannelCmd;//使能与否
} NVIC_InitTypeDef;
void NVIC_Init(NVIC_InitTypeDef* init_struct)
{
if (init_struct->NVIC_IRQChannelCmd != DISABLE) {
u32 pri = (SCB_AIRCR_PRIGROUP & ~(SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk)) >> SCB_AIRCR_PRIGROUP_Pos;
pri = (((u32)init_struct->NVIC_IRQChannelPreemptionPriority << (0x4 - pri)) |
(init_struct->NVIC_IRQChannelSubPriority & (0x0F >> pri)))
<< 0x04;
NVIC->IP[init_struct->NVIC_IRQChannel] = pri;
NVIC->ISER[init_struct->NVIC_IRQChannel >> 0x05] = 0x01 << (init_struct->NVIC_IRQChannel & 0x1F);
}
else {
NVIC->ICER[init_struct->NVIC_IRQChannel >> 0x05] = 0x01 << (init_struct->NVIC_IRQChannel & 0x1F);
}
}
typedef struct {
__IOM uint32_t ISER[8U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */
uint32_t RESERVED0[24U];
__IOM uint32_t ICER[8U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */
uint32_t RSERVED1[24U];
__IOM uint32_t ISPR[8U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */
uint32_t RESERVED2[24U];
__IOM uint32_t ICPR[8U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */
uint32_t RESERVED3[24U];
__IOM uint32_t IABR[8U]; /*!< Offset: 0x200 (R/W) Interrupt Active bit Register */
uint32_t RESERVED4[56U];
__IOM uint8_t IP[240U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register (8Bit wide) */
uint32_t RESERVED5[644U];
__OM uint32_t STIR; /*!< Offset: 0xE00 ( /W) Software Trigger Interrupt Register */
} NVIC_Type;
一个感性的认知,就不细究了,顺便一提,中断优先组最好设置为组4,无响应优先级,os里面可能会用到