STM32之NVIC中断优先级的介绍

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来处理


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.明天准备学习一下外部中断函数,用上今天的知识


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值