NVIC简介
1. 什么是NVIC
NVIC :Nested Vectored Interrupt Controller,全稱嵌套向量中斷控制器,
1.1 相關(guān)結(jié)構(gòu)體定義
1.1.1 NVIC 類型結(jié)構(gòu)體定義
注:常用 ISER、ICER 和 IP 這三個(gè)寄存器,ISER 用來(lái)使能中斷,ICER 用來(lái)失能中斷,IP 用來(lái)設(shè)置中斷優(yōu)先級(jí)。
/** @addtogroup CMSIS_CM3_NVIC CMSIS CM3 NVIC memory mapped structure for Nested Vectored Interrupt Controller (NVIC) 嵌套向量中斷控制器(NVIC)的內(nèi)存映射結(jié)構(gòu)體 @{ */
typedef struct
{
__IO uint32_t ISER[8]; /*!< Offset: 0x000 Interrupt Set Enable Register */ // 中斷設(shè)置使能寄存器
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 */ // 中斷設(shè)置掛起寄存器
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) */ // 中斷優(yōu)先級(jí)寄存器(8位寬)
uint32_t RESERVED5[644];
__O uint32_t STIR; /*!< Offset: 0xE00 Software Trigger Interrupt Register */ // 軟件觸發(fā)中斷寄存器
} NVIC_Type;
/*@}*/ /* end of group CMSIS_CM3_NVIC */
1.1.2 NVIC 初始化結(jié)構(gòu)體
用于初始化NVIC,指定中斷源、優(yōu)先級(jí)及使能或失能。
/** * @brief NVIC Init Structure definition 簡(jiǎn)介: NVIC 初始化結(jié)構(gòu)體定義 */
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) */
/* 指定要啟用或禁用的IRQ通道。此參數(shù)可以是@ref IRQn_Type的值(有關(guān)完整的STM32設(shè)備IRQ通道列表,請(qǐng)參閱stm32f10x.h文件) */
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 */
/* 指定NVIC_IRQChannel中指定的IRQ通道的搶占優(yōu)先級(jí)。如@ref NVIC_Priority_表所述,該參數(shù)可以是介于0和15之間的值 */
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 */
/* 指定NVIC_IRQChannel中指定的IRQ通道的子優(yōu)先級(jí)。如@ref NVIC_Priority_表所述,該參數(shù)可以是介于0和15之間的值。 */
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_IRQChannel中定義的IRQ通道。此參數(shù)可以設(shè)置為啟用或禁用 */
} NVIC_InitTypeDef;
注:
1.2 相應(yīng)固件庫(kù)函數(shù)
1.2.1 NVIC_EnableIRQ 函數(shù)
在NVIC中斷控制器中啟用中斷(使能)
/** * @brief Enable Interrupt in NVIC Interrupt Controller * 簡(jiǎn)介: 在NVIC中斷控制器中啟用中斷 * @param IRQn The positive number of the external interrupt to enable * 參數(shù) : IRQn 要啟用的外部中斷的正數(shù)( IRQn_Type結(jié)構(gòu)體中定義有 ) * Enable a device specific interupt in the NVIC interrupt controller. 在NVIC中斷控制器中啟用特定于設(shè)備的中斷。 * The interrupt number cannot be a negative value. 中斷號(hào)不能是負(fù)值。 */
static __INLINE void NVIC_EnableIRQ(IRQn_Type IRQn)
{
NVIC->ISER[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* enable interrupt */
}
1.2.2 NVIC_DisableIRQ 函數(shù)
禁用指定的外部中斷
/** * @brief Disable the interrupt line for external interrupt specified * 簡(jiǎn)介: 禁用指定的外部中斷 * @param IRQn The positive number of the external interrupt to disable * 參數(shù) : IRQn 要禁用的外部中斷的正數(shù)( IRQn_Type結(jié)構(gòu)體中定義有 ) * Disable a device specific interupt in the NVIC interrupt controller. * The interrupt number cannot be a negative value. */
static __INLINE void NVIC_DisableIRQ(IRQn_Type IRQn)
{
NVIC->ICER[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* disable interrupt */
}
1.2.3 NVIC_GetPendingIRQ 函數(shù)
讀取特定于設(shè)備的中斷源的中斷掛起位
/** * @brief Read the interrupt pending bit for a device specific interrupt source * 簡(jiǎn)介: 讀取特定于設(shè)備的中斷源的中斷掛起位 * @param IRQn The number of the device specifc interrupt 參數(shù): IRQn 設(shè)備中斷的特定編號(hào)( IRQn_Type結(jié)構(gòu)體中定義有 ) * @return 1 = interrupt pending, 0 = interrupt not pending * 返回值: 1 = 中斷掛起 0 = 中斷未掛起 * Read the pending register in NVIC and return 1 if its status is pending, * otherwise it returns 0 */
static __INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn)
{
return((uint32_t) ((NVIC->ISPR[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0)); /* Return 1 if pending else 0 */
}
1.2.4 NVIC_SetPendingIRQ 函數(shù)
設(shè)置外部中斷的掛起位
/** * @brief Set the pending bit for an external interrupt * 簡(jiǎn)介: 設(shè)置外部中斷的掛起位 * @param IRQn The number of the interrupt for set pending * 參數(shù) : IRQn 設(shè)置掛起的中斷的序號(hào) * Set the pending bit for the specified interrupt. 為指定的中斷設(shè)置掛起位。 * The interrupt number cannot be a negative value. */
static __INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn)
{
NVIC->ISPR[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* set interrupt pending */
}
1.2.5 NVIC_ClearPendingIRQ 函數(shù)
清除外部中斷的掛起位
/** * @brief Clear the pending bit for an external interrupt * 簡(jiǎn)介: 清除外部中斷的掛起位 * @param IRQn The number of the interrupt for clear pending * * Clear the pending bit for the specified interrupt. * The interrupt number cannot be a negative value. */
static __INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn)
{
NVIC->ICPR[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* Clear pending interrupt */
}
1.2.6 NVIC_GetActive 函數(shù)
讀取外部中斷的有效位
/** * @brief Read the active bit for an external interrupt * 簡(jiǎn)介: 讀取外部中斷的有效位 * @param IRQn The number of the interrupt for read active bit * 參數(shù) : IRQn 讀取有效位的中斷的序號(hào) * @return 1 = interrupt active, 0 = interrupt not active * 讀取NVIC中的活動(dòng)寄存器,如果其狀態(tài)為活動(dòng),則返回1,反之返回0 * Read the active register in NVIC and returns 1 if its status is active, * otherwise it returns 0. */
static __INLINE uint32_t NVIC_GetActive(IRQn_Type IRQn)
{
return((uint32_t)((NVIC->IABR[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0)); /* Return 1 if active else 0 */
}
1.2.7 NVIC_SetPriority 函數(shù)
設(shè)置中斷的優(yōu)先級(jí)
/** * @brief Set the priority for an interrupt * 簡(jiǎn)介: 設(shè)置中斷的優(yōu)先級(jí) * @param IRQn The number of the interrupt for set priority * @param priority The priority to set * 參數(shù)2 :priority 設(shè)定的優(yōu)先值 * Set the priority for the specified interrupt. The interrupt * number can be positive to specify an external (device specific) * interrupt, or negative to specify an internal (core) interrupt. * 設(shè)置指定中斷的優(yōu)先級(jí)。中斷號(hào)可以是正數(shù)以指定外部(設(shè)備特定)中斷, 也可以是負(fù)數(shù)以指定內(nèi)部(核心)中斷。 * Note: The priority cannot be set for every core interrupt. 注意:不能為每個(gè)核心中斷設(shè)置優(yōu)先級(jí)。 */
static __INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)
{
if(IRQn < 0) {
SCB->SHP[((uint32_t)(IRQn) & 0xF)-4] = ((priority << (8 - __NVIC_PRIO_BITS)) & 0xff); } /* set Priority for Cortex-M3 System Interrupts */
else {
NVIC->IP[(uint32_t)(IRQn)] = ((priority << (8 - __NVIC_PRIO_BITS)) & 0xff); } /* set Priority for device specific Interrupts */
}
1.2.8 NVIC_GetPriority 函數(shù)
讀取中斷的優(yōu)先級(jí)
/** * @brief Read the priority for an interrupt * 簡(jiǎn)介: 讀取中斷的優(yōu)先級(jí) * @param IRQn The number of the interrupt for get priority * @return The priority for the interrupt * * Read the priority for the specified interrupt. The interrupt * number can be positive to specify an external (device specific) * interrupt, or negative to specify an internal (core) interrupt. * 讀取指定中斷的優(yōu)先級(jí)。中斷號(hào)可以是正數(shù)以指定外部(設(shè)備特定)中斷,也可以是負(fù)數(shù)以指定內(nèi)部(核心)中斷。 * The returned priority value is automatically aligned to the implemented * priority bits of the microcontroller. * 返回的優(yōu)先級(jí)值自動(dòng)與微控制器實(shí)現(xiàn)的優(yōu)先級(jí)位對(duì)齊。 * Note: The priority cannot be set for every core interrupt. */
static __INLINE uint32_t NVIC_GetPriority(IRQn_Type IRQn)
{
if(IRQn < 0) {
return((uint32_t)(SCB->SHP[((uint32_t)(IRQn) & 0xF)-4] >> (8 - __NVIC_PRIO_BITS))); } /* get priority for Cortex-M3 system interrupts */
else {
return((uint32_t)(NVIC->IP[(uint32_t)(IRQn)] >> (8 - __NVIC_PRIO_BITS))); } /* get priority for device specific interrupts */
}
1.2.9 NVIC_SystemReset 函數(shù)
啟動(dòng)系統(tǒng)重置請(qǐng)求
/* ################################## Reset function ############################################ */
/** * @brief Initiate a system reset request. * 簡(jiǎn)介: 啟動(dòng)系統(tǒng)重置請(qǐng)求。 * Initiate a system reset request to reset the MCU 啟動(dòng)系統(tǒng)重置請(qǐng)求以重置MCU */
static __INLINE void NVIC_SystemReset(void)
{
SCB->AIRCR = ((0x5FA << SCB_AIRCR_VECTKEY_Pos) |
(SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) |
SCB_AIRCR_SYSRESETREQ_Msk); /* Keep priority group unchanged */
__DSB(); /* Ensure completion of memory access */
while(1); /* wait until reset */
}
/*@}*/ /* end of group CMSIS_CM3_Core_FunctionInterface */
1.2.10 NVIC_PriorityGroupConfig 函數(shù)
配置優(yōu)先級(jí)分組:搶占優(yōu)先級(jí)和子優(yōu)先級(jí)。
/** @defgroup Preemption_Priority_Group * @{ */
#define NVIC_PriorityGroup_0 ((uint32_t)0x700) /*!< 0 bits for pre-emption priority 4 bits for subpriority */
#define NVIC_PriorityGroup_1 ((uint32_t)0x600) /*!< 1 bits for pre-emption priority 3 bits for subpriority */
#define NVIC_PriorityGroup_2 ((uint32_t)0x500) /*!< 2 bits for pre-emption priority 2 bits for subpriority */
#define NVIC_PriorityGroup_3 ((uint32_t)0x400) /*!< 3 bits for pre-emption priority 1 bits for subpriority */
#define NVIC_PriorityGroup_4 ((uint32_t)0x300) /*!< 4 bits for pre-emption priority 0 bits for subpriority */
/** * @brief Configures the priority grouping: pre-emption priority and subpriority. 簡(jiǎn)介: 配置優(yōu)先級(jí)分組:搶占優(yōu)先級(jí)和子優(yōu)先級(jí)。 * @param NVIC_PriorityGroup: specifies the priority grouping bits length. 參數(shù): NVIC_PriorityGroup: 指定優(yōu)先級(jí)分組位長(zhǎng)度。 * This parameter can be one of the following values: * @arg NVIC_PriorityGroup_0: 0 bits for pre-emption priority :0位 用于搶占優(yōu)先級(jí) * 4 bits for subpriority :4位 表示次優(yōu)先級(jí) * @arg NVIC_PriorityGroup_1: 1 bits for pre-emption priority :1位 用于搶占優(yōu)先級(jí) * 3 bits for subpriority :3位 表示次優(yōu)先級(jí) * @arg NVIC_PriorityGroup_2: 2 bits for pre-emption priority :2位 用于搶占優(yōu)先級(jí) * 2 bits for subpriority :2位 表示次優(yōu)先級(jí) * @arg NVIC_PriorityGroup_3: 3 bits for pre-emption priority :3位 用于搶占優(yōu)先級(jí) * 1 bits for subpriority :1位 表示次優(yōu)先級(jí) * @arg NVIC_PriorityGroup_4: 4 bits for pre-emption priority :4位 用于搶占優(yōu)先級(jí) * 0 bits for subpriority :0位 表示次優(yōu)先級(jí) * @retval None */
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;
}
總結(jié)
- 上一篇: 讲讲Bootstrap是在干啥?
- 下一篇: 独一无二的微信网名大全 适合长期不换的网