2021/10/14 智慧傢俱 嵌入式實訓 第四天 中斷 NVIC中斷(1)
阿新 • • 發佈:2021-10-15
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