qditer的个人空间 https://bbs.21ic.com/?544816 [收藏] [复制] [RSS]

日志

stm32中断优先级(转载)

已有 768 次阅读2014-1-4 20:49 |个人分类:stm32|系统分类:单片机| stm32, 中断优先级

STM32中断优先级彻底讲解

一:综述

STM32 目前支持的中断共为 84 个(16 个内核+68 个外部), 16 级可编程中断优先级
的设置(仅使用中断优先级设置 8bit 中的高 4 位)和16个抢占优先级(因为抢占优先级最多可以有四位数)。

二:优先级判断

STM32(Cortex-M3)中有两个优先级的概念——抢占式优先级和响应优先级,有人把响应优先级称作'亚优先级''副优先级',每个中断源都需要被指定这两种优先级。

具有高抢占式优先级的中断可以在具有低抢占式优先级的中断处理过程中被响应,即中断嵌套,或者说高抢占式优先级的中断可以嵌套低抢占式优先级的中断。

当两个中断源的抢占式优先级相同时,这两个中断将没有嵌套关系,当一个中断到来后,如果正在处理另一个中断,这个后到来的中断就要等到前一个中断处理完之后才能被处理。如果这两个中断同时到达,则中断控制器根据他们的响应优先级高低来决定先处理哪一个;如果他们的抢占式优先级和响应优先级都相等,则根据他们在中断表中的排位顺序决定先处理哪一个。
三:优先级分组
既然每个中断源都需要被指定这两种优先级,就需要有相应的寄存器位记录每个中断的优先级;在Cortex-M3中定义了8个比特位用于设置中断源的优先级,这8个比特位在NVIC应用中断与复位控制寄丛器(AIRCR)的中断优先级分组域中,可以有8种分配方式,如下:

所有8位用于指定响应优先级
最高1位用于指定抢占式优先级,最低7位用于指定响应优先级
最高2位用于指定抢占式优先级,最低6位用于指定响应优先级
最高3位用于指定抢占式优先级,最低5位用于指定响应优先级
最高4位用于指定抢占式优先级,最低4位用于指定响应优先级
最高5位用于指定抢占式优先级,最低3位用于指定响应优先级
最高6位用于指定抢占式优先级,最低2位用于指定响应优先级
最高7位用于指定抢占式优先级,最低1位用于指定响应优先级

这就是优先级分组的概念。

Cortex-M3允许具有较少中断源时使用较少的寄存器位指定中断源的优先级,因此STM32把指定中断优先级的寄存器位减少到4位(AIRCR高四位),这4个寄存器位的分组方式如下:

0组:所有4位用于指定响应优先级
1组:最高1位用于指定抢占式优先级,最低3位用于指定响应优先级
2组:最高2位用于指定抢占式优先级,最低2位用于指定响应优先级
3组:最高3位用于指定抢占式优先级,最低1位用于指定响应优先级
4组:所有4位用于指定抢占式优先级

可以通过调用STM32的固件库中的函数NVIC_PriorityGroupConfig()选择使用哪种优先级分组方式,这个函数的参数有下列5种:

NVIC_PriorityGroup_0 =>
选择第0
NVIC_PriorityGroup_1 =>
选择第1
NVIC_PriorityGroup_2 =>
选择第2
NVIC_PriorityGroup_3 =>
选择第3
NVIC_PriorityGroup_4 =>
选择第4

中断优先级分组是为了给抢占式优先级和响应优先级在中断优先级寄丛器的高四位分配各个优先级数字所占的位数在一个程序中只能设定一次

四:中断源的优先级

接下来就是指定中断源的优先级,中断源优先级是在中断优先级寄存器中设置的,只能设置及高四位,必须根据中断优先级分组中设置好的位数来在该寄存器中设置相应的数值。假如你选择中断优先级分组的第3组:最高3位用于指定抢占式优先级,最低1位用于指定响应优先级,那么抢占式优先级就有000-111共八种数据选择,也就是有八个中断嵌套,而响应优先级中有01两种,总共有8*2=16种优先级。

中断源优先级具体的设置了该中断源的优先级别

在一个程序中可以设定多个(最多16个)优先级,每个中断源只能设定的一个。

每写一个关于中断优先级的程序必须包含下列两个函数:

1void NVIC_PriorityGroupConfig(u32 NVIC_PriorityGroup)中断分组设置

2void NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct)中断优先级设置


Table 273. 先占优先级和从优先级值(1)(2)
NVIC_PriorityGroup
NVIC_IRQChannel的先占优先级
NVIC_IRQChannel的从优先级
描述
NVIC_PriorityGroup_0
0
0-15
先占优先级0位
从优先级4位
NVIC_PriorityGroup_1
0-1
0-7
先占优先级1位
从优先级3位
NVIC_PriorityGroup_2
0-3
0-3
先占优先级2位
从优先级2位
NVIC_PriorityGroup_3
0-7
0-1
先占优先级3位
从优先级1位
NVIC_PriorityGroup_4
0-15
0
先占优先级4位
从优先级0位
1. 选中NVIC_PriorityGroup_0,则参数NVIC_IRQChannelPreemptionPriority对中断通道的设置不产生影响。
2. 选中NVIC_PriorityGroup_4,则参数NVIC_IRQChannelSubPriority对中断通道的设置不产生影响。
NVIC_IRQChannelCmd
该参数指定了在成员NVIC_IRQChannel中定义的IRQ通道被使能还是失能。这个参数取值为ENABLE或者DISABLE。
例:
NVIC_InitTypeDef NVIC_InitStructure;
/* Configure the Priority Grouping with 1 bit */
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
/* Enable TIM3 global interrupt with Preemption Priority 0 and Sub
Priority as 2 */
NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQChannel;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC
168/368
译文英文原版为 UM0427 Oct. 2007 Rev 2, 译文仅供参考,与英文版冲突的,以英文版为准
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_InitStructure(&NVIC_InitStructure);
/* Enable USART1 global interrupt with Preemption Priority 1 and Sub
Priority as 5 */
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQChannel;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 5;
NVIC_InitStructure(&NVIC_InitStructure);
/* Enable RTC global interrupt with Preemption Priority 1 and Sub
Priority as 7 */
NVIC_InitStructure.NVIC_IRQChannel = RTC_IRQChannel;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 7;
NVIC_InitStructure(&NVIC_InitStructure);
/* Enable EXTI4 interrupt with Preemption Priority 1 and Sub
Priority as 7 */
NVIC_InitStructure.NVIC_IRQChannel = EXTI4_IRQChannel;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 7;
NVIC_InitStructure(&NVIC_InitStructure);
/* TIM3 interrupt priority is higher than USART1, RTC and EXTI4
interrupts priorities. USART1 interrupt priority is higher than RTC
and EXTI4 interrupts priorities. RTC interrupt priority is higher
than EXTI4 interrupt prioriy. */


路过

鸡蛋

鲜花

握手

雷人

评论 (0 个评论)