2021/10/14 智能家具 嵌入式实训 第四天 中断 NVIC中断(1)

1.NVIC中断优先级分组

 

 

 

 

 可见中文参考手册 9.1.2

几十个中断,怎样管理?

 

抢占优先级&响应优先级区别:

 

 

 

 

 

中断优先级:中断同时到来,谁先执行(数字越小,优先级越高)

抢占优先级/剥夺:抢占优先级高的中断可以打断低抢占优先级的任务执行;

响应/次级优先级:抢占优先级相等,同时到来,响应优先级谁高谁执行;

 

 

 

 

 

 

 

中断优先级分组函数

 

 

 

 

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;
}

 

在misc.c文件中

 

然后再定义分组函数时候

//3. 配置NVIC
        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);               //配置NVIC中断优先级组(一般写在主函数main开始处)
        NVIC_InitTypeDef NVIC_InitStructure;            
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;       //占先优先级 0
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;              //次级优先级 0
        NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;                //中断通道(中断服务函数,MDK有定义,不能随便取名)
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                 //中断通道使能
        NVIC_Init(&NVIC_InitStructure);

 

 

MDK中 NVIC 寄存器

中断设置相关寄存器

 

 

 

 

 

 

 

 

在core_cm3.h中找

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

 

 

对于每个中断怎么设置优先级?

 

 

 

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);
  }
}
View Code

 

 

结构体

typedef struct
{
  uint8_t NVIC_IRQChannel;                    /*!< Specifies the IRQ channel to be enabled or disabled.
                                                   This parameter can be a value of @ref IRQn_Type 
                                                   (For the complete STM32 Devices IRQ Channels list, please
                                                    refer to stm32f10x.h file) */

  uint8_t NVIC_IRQChannelPreemptionPriority;  /*!< Specifies the pre-emption priority for the IRQ channel
                                                   specified in NVIC_IRQChannel. This parameter can be a value
                                                   between 0 and 15 as described in the table @ref NVIC_Priority_Table */

  uint8_t NVIC_IRQChannelSubPriority;         /*!< Specifies the subpriority level for the IRQ channel specified
                                                   in NVIC_IRQChannel. This parameter can be a value
                                                   between 0 and 15 as described in the table @ref NVIC_Priority_Table */

  FunctionalState NVIC_IRQChannelCmd;         /*!< Specifies whether the IRQ channel defined in NVIC_IRQChannel
                                                   will be enabled or disabled. 
                                                   This parameter can be set either to ENABLE or DISABLE */   
} NVIC_InitTypeDef;
View Code

 

 

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

 

 

 

 

 

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

 

 

中断挂起 、解挂寄存器组 :ISOR[8] ICPR[8]

 

 

 

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

 

 

 

中断参数初始化函数

 

 

总结:

 

posted @ 2021-10-15 22:07  halfup  阅读(180)  评论(0编辑  收藏  举报