您的位置 首页 解答

STM32 NVIC 中止优先级办理

CM3内核支持256个中断,其中包含了16个内核中断和240个外部中断,并且具有256级的可编程中断设置。但STM32并没有使用CM3内核的全部东西,而…

CM3内核支撑256个中止,其间包含了16个内核中止和240个外部中止,而且具有256级的可编程中止设置。但STM32并没有运用CM3内核的悉数东西,而是只用了它的一部分。STM32有84个中止,包含16个内核中止和68个可屏蔽中止,具有16级可编程的中止优先级。而咱们常用的便是这68个可屏蔽中止,可是STM32的68个可屏蔽中止,在STM32F103系列上面,又只要60个(在107系列才有68个)。

在MDK内,与NVIC相关的寄存器,MDK为其界说了如下的结构体:

  1.   typedefstruct
  2.   {
  3.   vu32 ISER[2];
  4.   u32 RESERVED0[30];
  5.   vu32 ICER[2];
  6.   u32 RSERVED1[30];
  7.   vu32 ISPR[2];
  8.   u32 RESERVED2[30];
  9.   vu32 ICPR[2];
  10.   u32 RESERVED3[30];
  11.   vu32 IABR[2];
  12.   u32 RESERVED4[62];
  13.   vu32 IPR[15];
  14.   }NVIC_TypeDef;

STM32的中止在这些寄存器的操控下有序的履行的。只要了解这些中止寄存器,才干了解STM32的中止。下面扼要介绍这几个寄存器:

ISER[2]:ISER全称是:InterruptSet-EnableRegisters,这是一个中止使能寄存器组。上面说了STM32F103的可屏蔽中止只要60个,这儿用了2个32位的寄存器,一共能够表明64个中止。而STM32F103只用了其间的前60位。ISER[0]的bit0~bit31别离对应中止0~31。ISER[1]的bit0~27对应中止32~59;这样一共60个中止就别离对应上了。你要使能某个中止,有必要设置相应的ISER位为1,使该中止被使能(这儿仅仅是使能,还要合作中止分组、屏蔽、IO口映射等设置才算是一个完好的中止设置)。详细每一位对应哪个中止,请参阅stm32f10x_nvic..h里边的第36行处。

ICER[2]:全称是:InterruptClear-EnableRegisters,是一个中止除能寄存器组。该寄存器组与ISER的效果恰好相反,是用来铲除某个中止的使能的。其对应位的功用,也和ICER相同。这儿要专门设置一个ICER来铲除中止位,而不是向ISER写0来铲除,是由于NVIC的这些寄存器都是写1有用的,写0是无效的。

ISPR[2]:全称是:InterruptSet-PendingRegisters,是一个中止挂起操控寄存器组。每个位对应的中止和ISER是相同的。经过置1,能够将正在进行的中止挂起,而履行同级或更高等级的中止。写0是无效的。

ICPR[2]:全称是:InterruptClear-PendingRegisters,是一个中止解挂操控寄存器组。其效果与ISPR相反,对应位也和ISER是相同的。经过设置1,能够将挂起的中止接挂。写0无效。

IABR[2]:全称是:InterruptActiveBitRegisters,是一个中止激活标志位寄存器组。这是一个只读寄存器,经过它能够知道当时在履行的中止是哪一个。在中止履行完了由硬件主动清零。对应位所代表的中止和ISER相同,假如为1,则表明该位所对应的中止正在被履行。

IPR[15]:全称是:InterruptPriorityRegisters,是一个中止优先级操控的寄存器组。这个寄存器组适当重要!STM32的中止分组与这个寄存器组密切相关。由于STM32的中止多达60多个,所以STM32选用中止分组的办法来确认中止的优先级。IPR寄存器组由15个32bit的寄存器组成,每个可屏蔽中止占用8bit,这样一共能够表明15*4=60个可屏蔽中止。刚好和STM32的可屏蔽中止数持平。IPR[0]的[31~24],[23~16],[15~8],[7~0]别离对应中止3~0,顺次类推,一共对应60个外部中止。而每个可屏蔽中止占用的8bit并没有悉数运用,而是只用了高4位。这4位,又分为抢占优先级和子优先级。抢占优先级在前,子优先级在后。而这两个优先级各占几个位又要依据SCB->AIRCR中的中止断分组设置来决议。

这儿简略介绍一下STM32的中止分组:STM32将中止分为5个组,组0~4。该分组的设置是由SCB->AIRCR寄存器的bit10~8来界说的。详细的分配联系如表

经过这个表,咱们就能够清楚的看到组0~4对应的装备联系,例如组设置为3,那么此刻一切的60个中止,每个中止的中止优先寄存器的高四位中的最高3位是抢占优先级,低1位是呼应优先级。每个中止,你能够设置抢占优先级为0~7,呼应优先级为1或0。抢占优先级的等级高于呼应优先级。而数值越小所代表的优先级就越高。

这儿需求留意两点:榜首,假如两个中止的抢占优先级和呼应优先级都是相同的话,则看哪个中止先发生就先履行;第二,高优先级的抢占优先级是能够打断正在进行的低抢占优先级中止的。而抢占优先级相同的中止,高优先级的呼应优先级不能够打断低呼应优先级的中止。

运用库函数完成以上中止分组设置以及中止优先级办理,使得咱们今后的中止设置简略化。NVIC中止办理函数主要在misc.c文件里边。

首先是中止优先级分组函数NVIC_PriorityGroupConfig,这个函数的效果是对中止的优先级进行分组,这个函数在体系中只能被调用一次,一旦分组确认就最好不要更改。

比方咱们设置整个体系的中止优先级分组值为2(2位抢占优先级,2位呼应优先级”),那么办法是:NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);

设置好了体系中止分组,那么关于每个中止又怎样确认他的抢占优先级和呼应优先级呢?下面看一个重要的函数为中止初始化函数NVIC_Init,其函数申明为:

voidNVIC_Init(NVIC_InitTypeDef*NVIC_InitStruct)

其间NVIC_InitTypeDef是一个结构体,能够看看结构体的成员变量:

  1.    typedefstruct
  2.    {
  3.      uint8_t NVIC_IRQChannel;//界说初始化的是哪个中止,这个咱们能够在 stm32f10x.h 中找到每个中止对应的姓名。例如 USART1_IRQn。
  4.      uint8_t NVIC_IRQChannelPreemptionPriority;//界说这个中止的抢占优先等级。
  5.      uint8_t NVIC_IRQChannelSubPriority;//界说这个中止的子优先等级。
  6.      FunctionalState NVIC_IRQChannelCmd;//该中止是否使能。
  7.    }NVIC_InitTypeDef;

比方咱们要使能串口1的中止,一起设置抢占优先级为1,子优先级位2,初始化的办法是:

  1.    USART_InitTypeDef USART_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(&NV%&&&&&%_InitStructure);

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/changshang/jieda/275296.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部