NVIC:嵌套向量中断控制器
在了解中断之前,我们先了解抢占优先级和响应优先级
抢占优先级和响应优先级
- 抢占优先级决定能不能打断,高优先级的抢占可以中断低优先级的抢占
- 响应优先级在抢占优先级相同时,高响应优先级先执行,响应优先级不能打断
注:数字越小,抢占和响应的优先级越大
比如说设置中断优先级组为2,然后设置中断3的抢占优先级为2,响应优先级为1,中断6的抢占优先级为3,响应优先级为0,中断7的抢占优先级为2,响应优先级为0,这三个中断的优先级顺序是:中断7>中断3>中断6
中断优先级分组
中断优先级分组可以分成0~4组,每个组可以分成16种情况,因为一共有4位来设置抢占和响应优先级
中断优先级分组在代码执行过程中,尽量只设置一次,不然会导致中断管理混乱,因为对于不同的分组,抢占和响应的优先级个数都是不同的。
中断优先级设置步骤
- 设置中断优先级分组
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2)
- 针对每个中断,设置对应的抢占优先级和响应优先级
使用的函数是:
void NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct);
NVIC_InitTypeDef是一个结构体:
typedef struct
{uint8_t NVIC_IRQChannel; //设置中断通道uint8_t NVIC_IRQChannelPreemptionPriority;//设置抢占优先级uint8_t NVIC_IRQChannelSubPriority; //设置响应优先级FunctionalState NVIC_IRQChannelCmd; //使能
} NVIC_InitTypeDef;
设置一个中断
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;//串口1中断
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1 ;// 抢占优先级为1
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;// 子优先级位2
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//IRQ通道使能
NVIC_Init(&NVIC_InitStructure); //根据上面指定的参数初始化NVIC寄存器
设置两个中断:
NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn; //使能按键WK_UP所在的外部中断通道NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02; //抢占优先级2, NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x03; //子优先级3NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能外部中断通道NVIC_Init(&NVIC_InitStructure); NVIC_InitStructure.NVIC_IRQChannel = EXTI2_IRQn; //使能按键KEY2所在的外部中断通道NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02; //抢占优先级2, NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x02; //子优先级2NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能外部中断通道NVIC_Init(&NVIC_InitStructure);
总结
当我们需要中断的时候,我们首先要设置中断优先级分组,然后对每个中断进行设置。