当前位置:   article > 正文

stm32-NVIC中断优先级管理(以古代官职角度分析)

stm32-NVIC中断优先级管理(以古代官职角度分析)

讲在前面的话:

博主在学习正点原子这一章节的时候很是懵,感觉摸不到门路,于是在网上找了一些相关的视频讲解,将他们的内容整合了一下,并尽量用易懂的话讲解。(本文基于stm32f103ZET6)

一、预备知识 

  • CM3 内核支持256个中断,其中包含了 16 个内核中断和 240 个外部中断,并且具有 256 级的可编程中断设置。
  •  STM32 并没有使用 CM3 内核的全部东西,而是只用了它的一部分。
  • STM32 有84个中断,包括 16 个内核中断和 68 个可屏蔽中断,具有 16 级可编程的中断优先级。
  • 我们常用这68 个可屏蔽中断,在 STM32F103 系列上面,又只有 60 个(在 107 系列才有 68 个)。

所以在此我们就只针对 STM32F103 系列这 60 个可屏蔽中断进行介绍。

 学过51单片机的我们都知道他只有定时器中断、外部中断、串口中断,一般只有五个基本中断源。

而stm32里面有60个中断,这么多的中断我们如何管理呢?

所以这里就需要NVIC中断优先级分组。

 二、NVIC中断优先级分组

NVIC(Nested vectoredinterrupt controller):嵌套向量中断控制器。

那它是如何管理中断的呢?

首先你想想看,你手底下有60号人,如果是你你打算怎么管理?

那当然是分而治之啊!拉拢一帮人给予高地位(官职),让他们帮你遏制另一些人。

换到stm32里面分配地位的就是IP[240]。

IP[240](Interrupt Priority Registers)是一个中断优先级控制的寄存器组。这个寄存器组相当重要!毕竟是分配地位的,STM32 的中断分组就与这个寄存器组有关。

IP 寄存器组由 240 个 8bit 的寄存器组成,每个可屏蔽中断占用 8bit,这样总共可以表示 240 个可屏蔽中断,而本文 STM32 只用到 了其中的前 60 个。

IP[59]~IP[0]分别对应中断 59~0。而每个可屏蔽中断占用的 8bit 并没有全部使用,而是只用了高 4 位,这高4位是给予中断地位的关键。

好,现在这 4 位开始设置官职,它把中断分为不同品级(抢占优先级),同一品级又划分了不同品阶(子优先级)。看官职先看你的品级(抢占优先级在前),品级一样看你的品阶(子优先级在后)。

好了,现在官职倒是定好了,那么如何分配呢?

前面说了高四位是给予官职的关键,所以这两个优先级各占几个位又要根据 SCB->AIRCR 中的中断分组设置来决定。

STM32 将中断分为 5 个组,组 0~4。该分组的设置是由SCB->AIRCR 寄存器的 bit10~8 来定义的。至于这个寄存器到底如何操作,目前我们先不用关心。

这个响应优先级就是子优先级。

抢占优先级和子优先级有什么区别呢? 

前面我们提到过,我们把抢占优先级称为官职的品级,响应优先级称为品阶。

官职品级和品阶的概念不用我多说了吧。

抢占优先级和响应优先级有0~4, 在官职里面对于抢占优先级,我们称它有零品~四品,在官职里面数字越小地位越高,所以有一品大员的称呼。当然实际上是没有零品的,这是我造的,这里0最小,所以它地位最高,零品大员!

对于响应优先级,我们称它有零品阶~四品阶,也是数字越小地位越高。

高优先级的抢占优先级可以打断正在进行的低抢占优先级中断;

(因为我品级高,地位高,可以打断你,先做我的事)

抢占优先级相同的中断,高响应优先级不可以打断低响应优先级的中断;

(咱俩品级一样,虽然你的品阶比我高,但是咱俩的级别一样,你好歹不能直接打断我做事,这不是不给我面子吗?我做完后你才能做事) 

抢占优先级相同的中断,当两个中断同时发生的情况下,哪个响应优先级高,哪个先执行;

 (咱们品级一样,级别相同,现在咱俩同时要做一件事,你的品阶高,地位也就比我高了一点,不是我怂,只是客气还是你先做吧,你做完我再做)

 如果两个中断的抢占优先级和响应优先级都是一样的话,则看哪个中断先发生就先执行。

 (品级一样,品阶一样,你先接手,那你先做事)

 好,现在分析图中的意思。组 0~4意思就是这高四位中有几位可以设置抢占优先级。比如:

组0:这四位全部只能设置响应优先级;

组1:这四位的高一位可以设置抢占优先级,剩下三位可以设置响应优先级。

组2:这四位高两位可以设置抢占优先级,剩下两位可以设置响应优先级。

组4:这四位全部用来设置抢占优先级。

看个例子:

假定设置中断优先级组为2(高两位设置抢占优先级,后两位设置响应优先级),然后设置
中断3(RTC中断)的抢占优先级为2(高两位设置为1 0),响应优先级为1(低两位设置为0 1);
中断6(外部中断0)的抢占优先级为3(高两位设置为1 1),响应优先级为0(低两位设置为0 0);
中断7(外部中断1)的抢占优先级为2(高两位设置为1 0),响应优先级为0(低两位设置为0  0)。
结合前面所学 ,这3个中断的优先级顺序为:中断7>中断3>中断6。

请注意: 

一般情况下,系统代码执行过程中,只设置一次中断优先级分组,比如分组2,设置好分组之后一般不会再改变分组。随意改变分组会导致中断管理混乱,程序出现意想不到的执行结果。 

三、相关配置函数

3.1 中断优先级分组函数

 中断优先级分组函数:

void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup);

看其命名NVIC Priority(优先级) Group(组) Config(配置)

转入他的释义看:

  1. void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup)
  2. {
  3. assert_param(IS_NVIC_PRIORITY_GROUP(NVIC_PriorityGroup));
  4. SCB->AIRCR = AIRCR_VECTKEY_MASK | NVIC_PriorityGroup;
  5. }

可以看到有配置SCB->AIRCR 寄存器的语句。

这个中断优先级分组函数括号里面可以填上自己想要的中断分组,比如组2

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);

分组设置好之后如何设置单个中断的抢占优先级和响应优先级呢?

这其中涉及很多寄存器,先一起看看吧。

3.2相关寄存器

中断设置相关寄存器:

  1. typedef struct
  2. {
  3. __IO uint32_t ISER[8];
  4. uint32_t RESERVED0[24];
  5. __IO uint32_t ICER[8];
  6. uint32_t RSERVED1[24];
  7. __IO uint32_t ISPR[8];
  8. uint32_t RESERVED2[24];
  9. __IO uint32_t ICPR[8];
  10. uint32_t RESERVED3[24];
  11. __IO uint32_t IABR[8];
  12. uint32_t RESERVED4[56];
  13. __IO uint8_t IP[240];
  14. uint32_t RESERVED5[644];
  15. __O uint32_t STIR;
  16. } NVIC_Type;

__IO uint8_t  IP[240]; //中断优先级控制的寄存器组

__IO uint32_t ISER[8]; //中断使能寄存器组

__IO uint32_t ICER[8]; //中断失能寄存器组

__IO uint32_t ISPR[8]; //中断挂起寄存器组

__IO uint32_t ICPR[8]; //中断解挂寄存器组

__IO uint32_t IABR[8]; //中断激活标志位寄存器组

先眼熟一下这些寄存器,然后我们再来说怎么设置。

其实在目录二中已经提到过,就是IP[240] (Interrupt Priority Registers)

中断优先级控制的寄存器组:IP[240]

 他有240个8位寄存器,每个中断使用一个寄存器来确定优先级。STM32F10x系列一共60个可屏蔽中断,所以只使用IP[59]~IP[0]。IP[59]~IP[0]分别对应中断 59~0,而每个可屏蔽中断占用的 8bit 并没有全部使用,而是只用了高 4 位

忘记的小伙伴可以往前翻一下。

在库函数中设置抢占和响应优先级是用这个函数:

void NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct);

这个函数有一个指针类型成员变量,现在去看看NVIC_InitTypeDef*的释义:

  1. typedef struct
  2. {
  3. uint8_t NVIC_IRQChannel;
  4. uint8_t NVIC_IRQChannelPreemptionPriority;
  5. uint8_t NVIC_IRQChannelSubPriority;
  6. FunctionalState NVIC_IRQChannelCmd;
  7. } NVIC_InitTypeDef;

这里面有4个成员变量:

NVIC_IRQChannel:定义初始化的是哪个中断,这个我们可以在 stm32f10x.h 中找到 每个中断对应的名字。例如 USART1_IRQn。

NVIC_IRQChannelPreemptionPriority:定义这个中断的抢占优先级别。

NVIC_IRQChannelSubPriority:定义这个中断的响应优先级别。

NVIC_IRQChannelCmd:该中断是否使能。

比如我们要使能串口 1 的中断,同时设置抢占优先级为 1,子优先级位 2,初始化的方法是:

  1. NVIC_InitTypeDef NVIC_InitStructure;
  2. NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;//串口 1 中断
  3. NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1 ;// 抢占优先级为 1
  4. NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;// 子优先级位 2
  5. NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ 通道使能
  6. NVIC_Init(&NVIC_InitStructure); //根据上面指定的参数初始化 NVIC 寄存器

中断使能寄存器组:ISER[8]

ISER[8]: 中断使能寄存器组

它是32位寄存器,每个位控制一个中断的使能。STM32F10x只有60个可屏蔽中断,所以只使用了

其中的ISER[0]和ISER[1]。ISER[0]的bit0~bit31分别对应中断0~31,ISER[1]的bit0~27对应中断32~59。

他的作用是使能中断,哎,这个作用是不是在哪里听过?

再看看他用的函数也是:

void NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct);

所以它对应的是指针类型成员变量的第四个成员变量使能:

FunctionalState NVIC_IRQChannelCmd

 所以配置这个成员变量就相当于配置这个寄存器

对应的还有中断失能寄存器组。

中断失能寄存器组:ICER[8]

ICER[8]:中断失能寄存器组

他的作用是用来失能中断。

他也是32位寄存器,每个位控制一个中断的失能。STM32F10x只有60个可屏蔽中断,所以只使用

了其中的ICER[0]和ICER[1]。ICER[0]的bit0~bit31分别对应中断0~31。ICER[1]的bit0~27对应中断

32~59,配置方法跟ISER一样。也使用函数:

void NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct);

配置第四个成员变量失能,就是配置这个寄存器。 

下面几个寄存器用的少,混个眼熟先:
中断挂起控制寄存器组:ISPR[8]

作用:用来挂起中断 

 中断解挂控制寄存器组:ICPR[8]

作用:用来解挂中断 

中断激活标志位寄存器组:IABR [8]

作用:只读,通过它可以知道当前在执行的中断是哪一个,如果对应位为1,说明该中断正在执行。 

3.3总结步骤

先设置中断优先级分组,比如设置为组2:

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);

注意:整个系统执行过程中,只能设置一次,不要用着用着突然改了 

然后针对每个中断,设置对应的抢占优先级和响应优先级,例如:

  1. NVIC_InitTypeDef NVIC_InitStructure;
  2. NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;//串口 1 中断
  3. NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1 ;// 抢占优先级为 1
  4. NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;// 子优先级位 2
  5. NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ 通道使能
  6. NVIC_Init(&NVIC_InitStructure); //根据上面指定的参数初始化 NVIC 寄存器

最后如果需要挂起/解挂,查看中断当前激活状态,分别调用相关函数即可。

这个我们先不做探究。

待补充,待更新...

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/很楠不爱3/article/detail/149139
推荐阅读
相关标签
  

闽ICP备14008679号