STM32中断优先级谁更高 主要根据两个方面来判断Word格式文档下载.docx
《STM32中断优先级谁更高 主要根据两个方面来判断Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《STM32中断优先级谁更高 主要根据两个方面来判断Word格式文档下载.docx(9页珍藏版)》请在冰豆网上搜索。
![STM32中断优先级谁更高 主要根据两个方面来判断Word格式文档下载.docx](https://file1.bdocx.com/fileroot1/2022-11/24/54d6443e-c685-4a3b-87eb-81ae7b5b5d09/54d6443e-c685-4a3b-87eb-81ae7b5b5d091.gif)
第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共八种数据选择,也就是有八个中断嵌套,而响应优先级中有0和1两种,总共有8*2=16种优先级。
中断源优先级具体的设置了该中断源的优先级别
在一个程序中可以设定多个(最多16个)优先级,每个中断源只能设定的一个。
每写一个关于中断优先级的程序必须包含下列两个函数:
(1)voidNVIC_PriorityGroupConfig(u32NVIC_PriorityGroup)中断分组设置
(2)voidNVIC_Init(NVIC_InitTypeDef*NVIC_InitStruct)中断优先级设置
具体设置:
五:
举例接下来就是指定中断源的优先级,下面以一个简单的例子说明如何指定中断源的抢占式优先级和响应优先级:
//选择使用优先级分组第1组
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
//使能EXTI0中断
NVIC_InitStructure.NVIC_IRQChannel=EXTI0_IRQChannel;
NVIC_InitStructure.NVIC_IRQChannelPreempTIonPriority=1;
//指定抢占式优先级别1
NVIC_InitStructure.NVIC_IRQChannelSubPriority=0;
//指定响应优先级别0
NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
NVIC_Init(NVIC_InitStructure);
//使能EXTI9_5中断
NVIC_InitStructure.NVIC_IRQChannel=EXTI9_5_IRQChannel;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0;
//指定抢占式优先级别0
NVIC_InitStructure.NVIC_IRQChannelSubPriority=1;
//指定响应优先级别1
六:
注意事项1)如果指定的抢占式优先级别或响应优先级别超出了选定的优先级分组所限定的范围,将可能得到意想不到的结果;
2)抢占式优先级别相同的中断源之间没有嵌套关系;
3)如果某个中断源被指定为某个抢占式优先级别,又没有其它中断源处于同一个抢占式优先级别,则可以为这个中断源指定任意有效的响应优先级别。
七:
开关总中断在STM32/Cortex-M3中是通过改变CPU的当前优先级来允许或禁止中断。
PRIMASK位:
只允许NMI和hardfault异常,其他中断/异常都被屏蔽(当前CPU优先级=0)。
FAULTMASK位:
只允许NMI,其他所有中断/异常都被屏蔽(当前CPU优先级=-1)。
在STM32固件库中(stm32f10x_nvic.c和stm32f10x_nvic.h)定义了四个函数操作PRIMASK位和FAULTMASK位,改变CPU的当前优先级,从而达到控制所有中断的目的。
下面两个函数等效于关闭总中断:
voidNVIC_SETPRIMASK(void);
voidNVIC_SETFAULTMASK(void);
下面两个函数等效于开放总中断:
voidNVIC_RESETPRIMASK(void);
voidNVIC_RESETFAULTMASK(void);
上面两组函数要成对使用,不能交叉使用。
例如:
第一种方法:
NVIC_SETPRIMASK();
//关闭总中断
NVIC_RESETPRIMASK();
//开放总中断
第二种方法:
NVIC_SETFAULTMASK();
NVIC_RESETFAULTMASK();
常常使用
//DisableInterrupts
//EnableInterrupts
补充可以用
#defineCLI()__set_PRIMASK
(1)
#defineSEI()__set_PRIMASK(0)
stm32优先级
1.优先级等级:
STM32用户能分配的优先级有16级,也就是用优先级寄存器NVIC-IP[x]的高四位来表示莫个中断的优先级。
2.优先级组:
在STM32中将一个中断的优先级分为:
抢占优先级和子优先级。
在进行优先级判断的时候先是比较抢占优先级然后比较子优先级。
在固件库中用变量分别表示抢占优先级和子优先级:
NVIC_InitTypeDef.NVIC_IRQChannelPreemptionPriority;
(抢占优先级)
NVIC_InitTypeDef.NVIC_IRQChannelSubPriority;
(子优先级)
优先级组就是对抢占优先级和子优先级进行的分界:
例如设置优先级组为0x05,那么表示的是莫个中断的优先级从第5位开始为界限,高两位[6:
7]是抢占优先
级。
第两位是[5:
4]表示的是子优先级。
举例说明:
//调用优先级组设置函数,设置优先级是0x05.
.....
NVIC_SetPriorityGrouping(5);
//这里说明了一个优先级寄存器的(NVIC-IP[x])的7,6位表示的是抢占优先级。
5,4表示的是优先级。
......
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0;
.......
//这里进行优先级的设置:
通过上面的设置可以知道抢占优先级和子优先级的范围都是3~0;
//那么这样就设置好了一个中断的优先级
//====================================================
//
STM32中断与嵌套NVIC快速入门。
//netjob2008-8-1
我也是靠看这本书才弄懂的:
Cortex-M3权威指南
JosephYiu著
宋岩译
其实很简单。
//CM3有最多240个中断(通常外部中断写作IRQs),就是软件上说的IRQ_CHANAELx(中断通道号x)
每个中断有自己的可编程的中断优先级【有唯一对应的中断优先级寄存器】。
由于CM3支持硬件中断嵌套,所以可以有256级的可编程优先级和256级中断嵌套【书上称:
抢占(preempt)优先级】
所以大家可以设:
IRQCHANAEL0通道=2中断优先级
WWDG窗口定时器中断
IRQCHANAEL1通道=0中断优先级
PVD
联到EXTI的电源电压检测(PVD)中断
IRQCHANAEL3通道=255中断优先级
RTC实时时钟(RTC)全局中断
IRQCHANAEL6通道=10中断优先级
EXTI0EXTI线0中断.....
IRQCHANAEL239通道=(0
这个实在是太恐怖了!
是的,其实CM3并没有这样做。
实在的芯片例如STM32等就只有设计来可用才64级可编程优先级和8级中断嵌套。
对64级中断就是说:
(INT0到INT63)这个大家比较好理解,其它的64239就不用了。
IRQCHANAEL0。
。
IRQCHANAEL63
而8级中断嵌套这又是何解呢?
是这样的,上面说一个【中断】对应一个【中断优先级寄存器】,而这个寄存器是8位的。
当然就是256级了。
而现在就用了它其中的BIT7,IT6,BIT5
三位来表示,而且是MSB对齐的。
用了3个位来表达优先级(MSB对齐的我们能够使用的8个优先级为:
0x00(最高),0x20,0x40,0x60,0x80,0xA0,0xC0以及0xE0。
)
这样我们在【中断优先级寄存器】就不能按理论的填0到255之间的数了,而只能填0x00(最高),0x20,0x40,0x60,0x80,0xA0,0xC0以及0xE0。
IRQCHANAEL0通道=0x20中断优先级
IRQCHANAEL1通道=0x40中断优先级
IRQCHANAEL3通道=0x20中断优先级
IRQCHANAEL6通道=0xA0中断优先级
EXTI0EXTI线0中断
IRQCHANAEL63通道=【0x00(最高),0x20,0x40,0x60,0x80,0xA0,0xC0
以及0xE0。
)】
大家注意到了,上面通道0和通道3的优先级都是0X20,这怎么办?
如果优先级完全相同的多个异常同时悬起,则先响应异常编号最小的那一个。
如IRQ#0会比IRQ#3先得到响应,而且文中还讲了【优先级分组】,这又是什么回事?
其实我回头看来,这个【优先级分组】和【抢占优先级】【亚优先级】都毫无意义的。
如果当时用256级即是把【中断优先级寄存器】的8位都全用上,就没这个必要了。
还什么优先级分组呢!
就是因为厂家现在【偷工减料】,才搞出这个明堂来的。
是这样的,在应用程序中断及复位控制寄存器(AIRCR)中的10:
8位【3位】是表示【优先级分组】它作用主要是用于对【中断优先级寄存器】『我们现在中用了BIT7,BIT6,BIT5三位』的功能的说明。
有一个表,在《Cortex-M3权威指南》的110页,例如我们把AIRCR的10:
8位设为【5】,查表可得【抢占优先级】=【7:
6】,【亚优先级】=【5:
0】,对于【中断优先级寄存器】只用了BIT7,6,5,因此我们可以看作是【7:
6】,【5】。
那4-0可以不管。
现在我们的IRQ0=0X20,IRQ3=0X20,也就是【0010】『bit7=0,bit6=0,bit5=1,bit4=0』因为大家(IRQ0/IRQ3)的【抢占优先级】=【7:
6】都是0,说明它们的中断相应级别是一样的。
再继续判断它们哪个更优先的责任就要看【5】,结果连【5】都是一样的!
那就按默认:
//如果优先级完全相同的多个异常同时悬起,则先响应异常编号最小的那一个。
如IRQ#0会比IRQ#3先得到响应,由于CM3没有进中断【关全局中断相应】这事,只要是中断通道打开了,就会存在通道间的嵌套,即是会发生【抢占】的情况了。
上面就简短的说明,如果要详细理解,可以看《Cortex-M3权威指南》。
有任何理解不当,请各位多多指教!
补充注意:
IRQCHANAEL0通道=0x20中断优先级WWDG窗口定时器中断
IRQCHANAEL1通道=0x40中断优先级PVD
IRQCHANAEL3通道=0x20中断优先级RTC实时时钟(RTC)全局中断
IRQCHANAEL6通道=0xA0中断优先级EXTI0EXTI线0中断
这样0通道和3通道就不会有嵌套情况,而是0通道按默认比3通道优先高些。
而0通道与1通道就会有嵌套情况。
芯片复位后,默认的优先级分组是0,就是【7:
1】表示抢占式优先级,【0】表示亚优先级,这样对于MSB对齐的8个优先级为:
使用就很方便了,建议大家就用默认的默认的优先级分组是0,也就是复位后的值,哈哈!
例如下面的两个按键,都使用外中断方式,使用了PD.3,和PD.4两个引脚。
这两个中断的优先级都是0X20,按默认的优先级分组,它们之间不会发生中断嵌套。
STM32_Nvic_Regs-Priority[9].all=0x20;
//中断的优先级是0X20
STM32_Nvic_Regs-Enable[0].bit.INT9=1;
//开INT9中断IRQ9
STM32_Nvic_Regs-Priority[10].all=0x20;
STM32_Nvic_Regs-Enable[0].bit.INT10=1;
//开INT10中断IRQ10
物联网嵌入式系统设计之STM32实战开发点击此处立即开始学习!