文章目录
- 1. 什么是NVIC
- 1.1 NVIC结构体定义
- 1.2 相应固件库函数
- 1.2.1 NVIC_EnableIRQ 函数
- 1.2.2 NVIC_DisableIRQ 函数
- 1.2.3 NVIC_GetPendingIRQ 函数
- 1.2.4 NVIC_SetPendingIRQ 函数
- 1.2.5 NVIC_ClearPendingIRQ 函数
- 1.2.6 NVIC_GetActive 函数
- 1.2.7 NVIC_SetPriority 函数
- 1.2.8 NVIC_GetPriority 函数
- 1.2.9 NVIC_SystemReset 函数
- 1.2.10 NVIC_PriorityGroupConfig 函数
1. 什么是NVIC
NVIC :Nested Vectored Interrupt Controller,全称嵌套向量中断控制器,
1.1 NVIC结构体定义
注:常用 ISER、ICER 和 IP 这三个寄存器,ISER 用来使能中断,ICER 用来失能中断,IP 用来设置中断优先级。
/** @addtogroup CMSIS_CM3_NVIC CMSIS CM3 NVIC
memory mapped structure for Nested Vectored Interrupt Controller (NVIC)
嵌套向量中断控制器(NVIC)的内存映射结构体
@{
*/
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) */ // 中断优先级寄存器(8位宽)
uint32_t RESERVED5[644];
__O uint32_t STIR; /*!< Offset: 0xE00 Software Trigger Interrupt Register */ // 软件触发中断寄存器
} NVIC_Type;
/*@}*/ /* end of group CMSIS_CM3_NVIC */
1.2 相应固件库函数
1.2.1 NVIC_EnableIRQ 函数
在NVIC中断控制器中启用中断(使能)
/**
* @brief Enable Interrupt in NVIC Interrupt Controller
* 简介: 在NVIC中断控制器中启用中断
* @param IRQn The positive number of the external interrupt to enable
* 参数 : IRQn 要启用的外部中断的正数( IRQn_Type结构体中定义有 )
* Enable a device specific interupt in the NVIC interrupt controller.
在NVIC中断控制器中启用特定于设备的中断。
* The interrupt number cannot be a negative value.
中断号不能是负值。
*/
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 函数
禁用指定的外部中断
/**
* @brief Disable the interrupt line for external interrupt specified
* 简介: 禁用指定的外部中断
* @param IRQn The positive number of the external interrupt to disable
* 参数 : IRQn 要禁用的外部中断的正数( IRQn_Type结构体中定义有 )
* 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 函数
读取特定于设备的中断源的中断挂起位
/**
* @brief Read the interrupt pending bit for a device specific interrupt source
* 简介: 读取特定于设备的中断源的中断挂起位
* @param IRQn The number of the device specifc interrupt
参数: IRQn 设备中断的特定编号( IRQn_Type结构体中定义有 )
* @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 函数
设置外部中断的挂起位
/**
* @brief Set the pending bit for an external interrupt
* 简介: 设置外部中断的挂起位
* @param IRQn The number of the interrupt for set pending
* 参数 : IRQn 设置挂起的中断的序号
* Set the pending bit for the specified interrupt.
为指定的中断设置挂起位。
* 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 函数
清除外部中断的挂起位
/**
* @brief Clear the pending bit for an external interrupt
* 简介: 清除外部中断的挂起位
* @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 函数
读取外部中断的有效位
/**
* @brief Read the active bit for an external interrupt
* 简介: 读取外部中断的有效位
* @param IRQn The number of the interrupt for read active bit
* 参数 : IRQn 读取有效位的中断的序号
* @return 1 = interrupt active, 0 = interrupt not active
* 读取NVIC中的活动寄存器,如果其状态为活动,则返回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 函数
设置中断的优先级
/**
* @brief Set the priority for an interrupt
* 简介: 设置中断的优先级
* @param IRQn The number of the interrupt for set priority
* @param priority The priority to set
* 参数2 :priority 设定的优先值
* 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.
* 设置指定中断的优先级。中断号可以是正数以指定外部(设备特定)中断,
也可以是负数以指定内部(核心)中断。
* Note: The priority cannot be set for every core interrupt.
注意:不能为每个核心中断设置优先级。
*/
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 函数
读取中断的优先级
/**
* @brief Read the priority for an interrupt
* 简介: 读取中断的优先级
* @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.
* 读取指定中断的优先级。中断号可以是正数以指定外部(设备特定)中断,也可以是负数以指定内部(核心)中断。
* The returned priority value is automatically aligned to the implemented
* priority bits of the microcontroller.
* 返回的优先级值自动与微控制器实现的优先级位对齐。
* 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 函数
启动系统重置请求
/* ################################## Reset function ############################################ */
/**
* @brief Initiate a system reset request.
* 简介: 启动系统重置请求。
* Initiate a system reset request to reset the MCU
启动系统重置请求以重置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 函数
配置优先级分组:抢占优先级和子优先级。
/** @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.
简介: 配置优先级分组:抢占优先级和子优先级。
* @param NVIC_PriorityGroup: specifies the priority grouping bits length.
参数: NVIC_PriorityGroup: 指定优先级分组位长度。
* This parameter can be one of the following values:
* @arg NVIC_PriorityGroup_0: 0 bits for pre-emption priority :0位 用于抢占优先级
* 4 bits for subpriority :4位 表示次优先级
* @arg NVIC_PriorityGroup_1: 1 bits for pre-emption priority :1位 用于抢占优先级
* 3 bits for subpriority :3位 表示次优先级
* @arg NVIC_PriorityGroup_2: 2 bits for pre-emption priority :2位 用于抢占优先级
* 2 bits for subpriority :2位 表示次优先级
* @arg NVIC_PriorityGroup_3: 3 bits for pre-emption priority :3位 用于抢占优先级
* 1 bits for subpriority :1位 表示次优先级
* @arg NVIC_PriorityGroup_4: 4 bits for pre-emption priority :4位 用于抢占优先级
* 0 bits for subpriority :0位 表示次优先级
* @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;
}