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); } }
结构体
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;
中断使能寄存器组:ISER[8]
中断失能寄存器组:ICER[8]
中断挂起 、解挂寄存器组 :ISOR[8] ICPR[8]
中断激活标志位寄存器组:IABR[8]
中断参数初始化函数
总结: