1、基本理解
ARM Cortex_m3内核支持256个中断(16个内核和240个外部)和可编程256级中断优先级的设置。然而,STM32并没有全部使用M3内核东西,STM32目前支持的中断为84个,16个内核加上68个外部以及16级可编程中断优先级的设置。
由于STM32只能管理16级中断的优先级,所以只是使用到中断优先级寄存器的高四位。
有两种优先级:
(1)抢占式优先级,库函数设置为NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=x(x为0~15,具体要看下面的优先级组别的选择);
(2)响应优先级,库函数设置为NVIC_InitStructure.NVIC_IRQChannelSubPriority =x(x为0~15,具体要看下面的优先级组别的选择);
当两个中断相遇时,谁先执行呢?先比较抢占式优先级,谁的抢占式优先级编号小就可以先执行,编号大的等着;如果抢占式优先级相同才去比较响应优先级,同理,优先级号谁小,谁先执行 。
注意:(1)其优先级编号越小,其优先级别越高。不是越大越高级!!
(2)只要抢占优先级高才可以抢占当前中断,如抢占优先级编号相同,则先到达的先执行,迟到达的即使响应优先级高也只能等着。只有同时到达,才是高响应优先级的中断先执行。要区分清楚。
2、嵌套向量中断控制器NVIC
STM32的中断还是相当多的, 那么需要专门的一个寄存器来管理他们,于是NVIC 出现了。
分为5个优先级组,分别以NVIC_PriorityGroup_0 依次到NVIC_PriorityGroup_4来表示;
NVIC_PriorityGroup_0 => 选择第0组
NVIC_PriorityGroup_1 => 选择第1组
NVIC_PriorityGroup_2 => 选择第2组
NVIC_PriorityGroup_3 => 选择第3组
NVIC_PriorityGroup_4 => 选择第4组
组别0时:所有4位用于响应优先级;
组别1时:最高1位用于抢占优先级,低3位用于响应优先级;
组别2时:最高2位用于抢占优先级,低2位用于响应优先级;
组别3时:最高3位用于抢占优先级,低1位用于响应优先级;
组别4时:最高4位用于抢占优先级,无响应优先级;
理解:假如选择了第三组,那么抢占式优先级就有000~111这8个中选择,你在程序当中可以给不同的中断不同的抢占式优先级,号码是从0~7 ; 而响应优先级只有1位,所以即使你要设置3、4个甚至最多的16个中断,在响应优先级这一项你只能赋予0或1。
所以,抢占式8个* 响应2个=16种优先级,这与上文所述的"STM32只能管理16级中断的优先级"是相符的。
应用举例
void NVIC_Configuration(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
//选择优先级分组第1组 ,抢占2种,响应8种
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQn ;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = EXT0_IRQn ;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority =0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority =1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority =1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority =1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority =1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority =2;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority =1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority =3;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
上述有5个中断,两个外部,三个定时器,那么优先级由高到低应该是:
外部中断9_5(暂不知是哪条中断线),外部中断0,定时器2,定时器3,定时器4。
其中外部中断可以随时打断定时器中断,定时器则不行。