欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

STM32之NVIC中断优先级的介绍

程序员文章站 2024-02-25 14:51:51
...

2018/4/9

STM32

1.说在前面

1.中断:中断就是CPU在处理一件事的时候,遇到紧急情况,所以就去响应而处理另外一件事(粗略介绍)

2.对于51而言,只有5个中断源,所以难度不算太大,但是,对于CM3内核支持256个中断(16个内核中断加240个内部中断)

stm32F103而言,有着60会让可屏蔽中断,所以相对来说比较复杂

2.对于中断的部分寄存器的简单介绍

typedef struct
{
  __IO uint32_t ISER[8];                      /*!< Offset: 0x000  Interrupt Set Enable Register           */
       uint32_t RESERVED0[24];                                   
  __IO uint32_t ICER[8];                      /*!< Offset: 0x080  Interrupt Clear Enable Register         */
       uint32_t RSERVED1[24];                                    
  __IO uint32_t ISPR[8];                      /*!< Offset: 0x100  Interrupt Set Pending Register          */
       uint32_t RESERVED2[24];                                   
  __IO uint32_t ICPR[8];                      /*!< Offset: 0x180  Interrupt Clear Pending Register        */
       uint32_t RESERVED3[24];                                   
  __IO uint32_t IABR[8];                      /*!< Offset: 0x200  Interrupt Active bit Register           */
       uint32_t RESERVED4[56];                                   
  __IO uint8_t  IP[240];                      /*!< Offset: 0x300  Interrupt Priority Register (8Bit wide) */
       uint32_t RESERVED5[644];                                  
  __O  uint32_t STIR;                         /*!< Offset: 0xE00  Software Trigger Interrupt Register     */
}  NVIC_Type;                          

ISER[8]:中断使能寄存器,在stm32F103中使用了ISER[0](bit0-bit31对应着中断0到31),ISER[1](bit0到bit27 对应着中断32到59)

ICER[8]:设置ICER来实现除能操作

ISPR[8]:中断挂起寄存器,每个位和ISER[8]一致,将寄存器置于1则中断挂起,然后实现更高级或同级的中断,写0无效

ICPR[8]:中断解挂控制寄存器,和ISPR[8]进行对应,对相应寄存器进行解挂

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

3.STM32的中断分组

1.通过配置SCB->AIRCR来处理

STM32之NVIC中断优先级的介绍

2.关于抢占优先级和响应优先级的介绍

1.对于抢占优先级和响应优先级,相对设置的数值越低,则相对更高

2.对于抢占优先级不同而言,优先级越高,可以在抢占优先级低的位置进行中断、

3.对于抢占优先级相同,但是响应优先级不同而言,响应优先级不能实现嵌套的中断,但是可以实现中断的先后顺序,在响应优先级高的位置则先进行中断

3.关于中断分组的库函数设置方法

void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup)//ÖжÏÓÅÏȼ¶ÉèÖÃ
{
  /* Check the parameters */
  assert_param(IS_NVIC_PRIORITY_GROUP(NVIC_PriorityGroup));
  
  /* Set the PRIGROUP[10:8] bits according to NVIC_PriorityGroup value */
  SCB->AIRCR = AIRCR_VECTKEY_MASK | NVIC_PriorityGroup;
}

4.中断函数初始化的库函数设置

void NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct)
{
  uint32_t tmppriority = 0x00, tmppre = 0x00, tmpsub = 0x0F;
  
  /* Check the parameters */
  assert_param(IS_FUNCTIONAL_STATE(NVIC_InitStruct->NVIC_IRQChannelCmd));
  assert_param(IS_NVIC_PREEMPTION_PRIORITY(NVIC_InitStruct->NVIC_IRQChannelPreemptionPriority));  
  assert_param(IS_NVIC_SUB_PRIORITY(NVIC_InitStruct->NVIC_IRQChannelSubPriority));
    
  if (NVIC_InitStruct->NVIC_IRQChannelCmd != DISABLE)
  {
    /* Compute the Corresponding IRQ Priority --------------------------------*/    
    tmppriority = (0x700 - ((SCB->AIRCR) & (uint32_t)0x700))>> 0x08;
    tmppre = (0x4 - tmppriority);
    tmpsub = tmpsub >> tmppriority;

    tmppriority = (uint32_t)NVIC_InitStruct->NVIC_IRQChannelPreemptionPriority << tmppre;
    tmppriority |=  NVIC_InitStruct->NVIC_IRQChannelSubPriority & tmpsub;
    tmppriority = tmppriority << 0x04;
        
    NVIC->IP[NVIC_InitStruct->NVIC_IRQChannel] = tmppriority;
    
    /* Enable the Selected IRQ Channels --------------------------------------*/
    NVIC->ISER[NVIC_InitStruct->NVIC_IRQChannel >> 0x05] =
      (uint32_t)0x01 << (NVIC_InitStruct->NVIC_IRQChannel & (uint8_t)0x1F);
  }
  else
  {
    /* Disable the Selected IRQ Channels -------------------------------------*/
    NVIC->ICER[NVIC_InitStruct->NVIC_IRQChannel >> 0x05] =
      (uint32_t)0x01 << (NVIC_InitStruct->NVIC_IRQChannel & (uint8_t)0x1F);
  }
}

就像设置GPIO口一样,以设置结构体的方法来实现初始化

5.明天准备学习一下外部中断函数,用上今天的知识