STM32中断优先级概述

发布者:MysticJourney最新更新时间:2021-05-07 来源: eefocus关键字:STM32  中断优先级 手机看文章 扫描二维码
随时随地手机看文章

一:综述


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


二:优先级判断


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共八种 数据选择,也就是有八个中断嵌套,而响应优先级中有0和1两种,总共有8*2=16种优先级。


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


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


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


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


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


注意:NVIC能配置的是16种中断向量,而不是16个,当工程中有超过16个中断向量时,必然有两个以上的中断向量是使用相同的中断种类,而具有相同中断种类的中断向量不能互相嵌套。


五:启动所需GPIOn_Pin及AFIO的RCC时钟


RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,RCC_APB2Periph_AFIO,ENABLE);


注意:千万别忘记启动RCC_APB2Periph_AFIO!否则管脚只能做普通高低电平来用。当把GPIO用作EXTI外部中断或使用重映射功能的时候,必须开启AFIO时钟,而在使用默认复用功能的时候,就不必开启AFIO时钟了。


六:实例


NVIC_InitTypeDef NVIC_InitStructure; //定义中断初始化类型结构体变量

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1); //配置优先级分组1 2个两个抢占优先级 8个亚优先级

NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn; //开口外部中断0

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;//配置0号抢占式优先级

NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;//亚优先级配置为0号

NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//使能通道

NVIC_Init(&NVIC_InitStructure); //对外部中断0进行初始化配置

NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQn; //开口外部中断5到9

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;//配置1号抢占式优先级

NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;//亚优先级配置为1号

NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//使能通道

NVIC_Init(&NVIC_InitStructure); //对外部中断0进行初始化配置

NVIC_InitStructure.NVIC_IRQChannel = ADC1_2_IRQn; //ADC1中断

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;//配置1号抢占式优先级

NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;//亚优先级配置为1号

NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//使能通道

NVIC_Init(&NVIC_InitStructure); //对外部中断0进行初始化配置


从上面的配置来看,外部中断0的优先级最高,可以打断ADC和外部5到9的中断,也就说可以嵌套发生,当ADC中断和外部5到 9中断同时发生时,它们的抢占优先级别相同,亚优先级别也相同,因为ADC1硬件排在更靠前,则先发生ADC中断,若是两者任何一个中断正在执行,则等此 中断执行完,再去执行另一个中断。


NVIC_InitStructure.NVIC_IRQChannel=EXTI9_5_IRQn表示要配置的为EXTI的第5~9线的中断向量,也就是说EXTI5~EXTI9线是使用同一个中断向量的。这些可写入的参数可以在stm32f10x.h文件中查找到。


关键字:STM32  中断优先级 引用地址:STM32中断优先级概述

上一篇:STM32的ADC输入通道配置
下一篇:关于STM32的GPIO的问题集锦

推荐阅读最新更新时间:2024-11-13 08:15

STM32低功耗进行总结
STM32F103R8和RC的停机模式的休眠电流还不一样,R8停机模式实测为11UA,RC停机模式实测为30uA,还以为又是我的程序哪里没做好呢,仔细看了PDF,这两个芯片PDF上标的值的确有区别,和我测的值差不多,那我就没有再深究的意义了! 结合下文的高手经验,反复摸索, standby模式1.9uA,PWR_EnterSTOPMode(PWR_Regulator_LowPower, PWR_STOPEntry_WFI); stop模式:11uA, PWR_EnterSTANDBYMode(); 实验证明,将IO端口设成IPU/IPD/AIN/PPOUT=1/PPOUT=0/ODOUT=0
[单片机]
stm32用ucos还是linux
  常见的嵌入式操作系统有两种:用MMU的和不用MMU的。 用MMU的是Windows、 MacOS 、Linux、 Android,不用MMU的是FreeRTOS VxWorks ucOS。 CPU有两种:带MMU的和不带MMU的,带MMU的有Cortex-A系列ARM9、 ARM11系列,不带MMU的有Cortex-M系列。 stm32用ucos还是linux STM32是M系列,不带MMU控制器,不可能运行Linux,当然, STM32能够跑μClinux,但是严格来说,μClinux是不算Linux的。所以对于很多网友有疑问的stm32用ucos还是linux这个问题,我们就知道答案了,stm32是用
[单片机]
stm32点亮LED灯一(库函数版)
学习51单片机的第一个控制IO口的操作就是流水灯,stm32的学习我也是从一个流水灯开始,是stm32是32位机,里面有很多的寄存器,操作stm32单片机也可以使用寄存器操作,使用寄存器操作的好处就是程序的执行速度快,程序的体积小,但是,问题也有很多,比如不方便移植,stm32不同型号的寄存器是有差别的,同时开发的效率低,因为操作寄存器需要频繁地查芯片手册。 权衡了一下,我选用库函数点亮LED。 第一步,建立环境,我选用的单片机是stm32f103c8,下载器是st-link,编译软件是keil5. 首先,我需要配一个库,因为库我只需要GPIO,所以我就只用GPIO库。开始说正事。 建立几个文件夹先(显得比较专业)
[单片机]
<font color='red'>stm32</font>点亮LED灯一(库函数版)
stm32学习笔记---计数器定时中断(1s)
#include tim_driver.h //tim2³õʼ»¯:1ÃëÖÓ¸üÐÂÊý¾Ý void tim2_init(void) { TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct; //ʹÄÜʱÖÓ RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV1; TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up;
[单片机]
<font color='red'>stm32</font>学习笔记---计数器定时中断(1s)
STM32通用定时器TIMx
STM32计数器时钟可由下列四种时钟源提供: (1)内部时钟(CK_INT) (2)外部时钟模式1:外部输入脚(TIx) (3)外部时钟模式2:外部触发输入(ETR) (4)内部触发输入(ITRx) 时钟源(CK_INT)经预分频(PSC)后得到定时时钟(CK_CNT),每个定时时钟计数寄存器计数(可设向上/向下/中央对齐模式),计数寄存器计数至捕获比较寄存器(CCR),则产生CC中断;计数寄存器计数至预装载值(ARR),则产生UPDATE中断,并重装预载值。 举个例子:(以向上计数为例,每40us中断一次)   例程: (省略RCC设置部分) void TIM2_Configuration(void) {
[单片机]
<font color='red'>STM32</font>通用定时器TIMx
STM32 I2C写入驱动数码管显示实验
实验环境 Matlab版本: 2021b 操作系统 :Win10专业版 硬件平台 :YF-STM32-ALPHA 1R4 实验内容 :I2C驱动数码管芯片显示‘0’~‘A’字符 模型与原理图 本次实验所用到的simulink模型如图5.2所示,电路原理图如图5.3所示,实验效果为数码管从‘0’~‘A’轮流显示,如图5.1所示。 图5.1 数码管驱动显示实验效果 图5.2 数码管显示I2C驱动模型 图5.3 CH422G共阴数码管电路连接 基础模型介绍与分析 1、数码管简介 数码管简单来说就是将多个LED有规律的排列在一起,实验中用到的数码管外观如图5.4所示,其型号为:FJ3461AH,三维尺寸:30.00mmx1
[单片机]
<font color='red'>STM32</font> I2C写入驱动数码管显示实验
stm32 通过串口控制led灯亮灭 并通过lcd显示led灯的亮灭状态
#include main.h #include stm32f0xx_hal.h /* USER CODE BEGIN Includes */ #include lcd.h /* USER CODE END Includes */ /* Private variables ---------------------------------------------------------*/ UART_HandleTypeDef huart1; /* USER CODE BEGIN PV */ /* Private variables ----------------------------------------
[单片机]
STM32 USB虚拟串口
串口调试在项目中被使用越来越多,串口资源的紧缺也变的尤为突出。很多本本人群,更是深有体会,不准备一个USB转串口工具就没办法进行开发。本章节来简单概述STM32低端芯片上的USB虚拟串口的移植。在官方DEMO中已经提供了现成的程序,这里对修改方法做简单说明。 首先打开官方demo我们开始进行移植,第一步复制我们可用的文件,操作如下: Projects\Virtual_COM_Port文件夹下,复制红线部分 图1 图2 我为了方便演示统放在usb/src文件夹下: 图3 现在复制USB的库文件,这些文件不需要我们修改: 图4 上图中的文件统一放在usb/lib文件夹下: 图5 好了现在所需要的文件我们以复制完
[单片机]
<font color='red'>STM32</font> USB虚拟串口
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
随便看看

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved