IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> NVIC简介 -> 正文阅读

[嵌入式]NVIC简介

1. 什么是NVIC

NVIC :Nested Vectored Interrupt Controller,全称嵌套向量中断控制器,

1.1 相关结构体定义

1.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.1.2 NVIC 初始化结构体

用于初始化NVIC,指定中断源、优先级及使能或失能。

/** 
  * @brief  NVIC Init Structure definition  
		简介:  NVIC 初始化结构体定义
  */

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通道。此参数可以是@ref IRQn_Type的值(有关完整的STM32设备IRQ通道列表,请参阅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通道的抢占优先级。如@ref NVIC_Priority_表所述,该参数可以是介于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通道的子优先级。如@ref NVIC_Priority_表所述,该参数可以是介于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通道。此参数可以设置为启用或禁用 */	
} NVIC_InitTypeDef;

注:
在这里插入图片描述

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;
}
  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2022-02-06 13:59:12  更:2022-02-06 14:00:16 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2025年1日历 -2025/1/8 4:22:36-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码