简介
简单来说NVIC就是个嵌套向量中断控制器,控制着整个芯片中断相关的功能。NVIC相关结构体定义在文件:core_cm3.h中。
关于中断寄存器主要有:ISER(使能中断),ICER(失能中断),IP(用来设置中断优先级)
优先级的定义
GD32或者ST32使用4个bit来表示中断优先级,优先级又被分为抢占优先级和子优先级。数值越小,优先级越高。如果抢占优先级相同的话,就比较子优先级,如果抢占优先级和子优先级都相同的话,就比较硬件中断编号,编号越小,优先级越高。
代码详解
这里只拿GD32做举例,STM32也差不多。代码一般分为两部分,这里可能因为代码差异而造成顺序不一样,但是逻辑大多相同:
1. 配置分组
/*!
\brief 设置优先级分组
\param[in] nvic_prigroup: the NVIC priority group
\arg NVIC_PRIGROUP_PRE0_SUB4: 0 bit 抢占优先级 ,4 bit 子优先级
\arg NVIC_PRIGROUP_PRE1_SUB3: 1 bit 抢占优先级 ,3 bit 子优先级
\arg NVIC_PRIGROUP_PRE2_SUB2: 2 bit 抢占优先级 ,2 bit 子优先级
\arg NVIC_PRIGROUP_PRE3_SUB1: 3 bit 抢占优先级 ,1 bit 子优先级
\arg NVIC_PRIGROUP_PRE4_SUB0: 4 bit 抢占优先级 ,0 bit 子优先级
\param[out] none
\retval none
*/
void nvic_priority_group_set(uint32_t nvic_prigroup)
{
/* set the priority group value */
SCB->AIRCR = NVIC_AIRCR_VECTKEY_MASK | nvic_prigroup;
}
优先级分组 | 抢占优先级取值 | 子优先级取值 |
---|---|---|
NVIC_PRIGROUP_PRE0_SUB4 | 0 | 0-15 |
NVIC_PRIGROUP_PRE1_SUB3 | 0-1 | 0-7 |
NVIC_PRIGROUP_PRE2_SUB2 | 0-3 | 0-3 |
NVIC_PRIGROUP_PRE3_SUB1 | 0-7 | 0-1 |
NVIC_PRIGROUP_PRE4_SUB0 | 0-15 | 0 |
因为有抢占优先级和子优先级之分,所有每组都是2^4 = 16个优先级
2. 使能中断
/*!
\brief 使能中断
\param[in] nvic_irq: 中断源,如
\param[in] nvic_irq_pre_priority: 抢占优先级
\param[in] nvic_irq_sub_priority: 子优先级
\param[out] none
\retval none
*/
void nvic_irq_enable(uint8_t nvic_irq,
uint8_t nvic_irq_pre_priority,
uint8_t nvic_irq_sub_priority)
根据程序的需求选择合适的分组,不要出现多个分组,虽然没见过什么异常,抢占优先级和子优先级的范围也要在相应分组的取值范围内。