NVIC简介

NVIC简介文章目录1.什么是NVIC1.1NVIC结构体定义1.2相应固件库函数1.2.1NVIC_EnableIRQ函数1.2.2NVIC_DisableIRQ函数1.2.3NVIC_GetPendingIRQ函数1.2.4NVIC_SetPendingIRQ函数1.2.5NVIC_ClearPendingIRQ函数1.2.6NVIC_GetActive函数1.2.7NVIC_SetPriority函数1.2.8NVIC_GetPriority函数1.2.9NVIC_Syst

大家好,又见面了,我是你们的朋友全栈君。

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;
}
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/140204.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(1)
blank

相关推荐

  • 数据仓库常见建模方法与建模实例演示[通俗易懂]

    数据仓库常见建模方法与建模实例演示[通俗易懂]1.数据仓库建模的目的?为什么要进行数据仓库建模?大数据的数仓建模是通过建模的方法更好的组织、存储数据,以便在性能、成本、效率和数据质量之间找到最佳平衡点。一般主要从下面四点考虑访问性能:能够快速查询所需的数据,减少数据I/O 数据成本:减少不必要的数据冗余,实现计算结果数据复用,降低大数据系统中的存储成本和计算成本 使用效率:改善用户应用体验,提高使用数据的效率 数据质量…

  • 文件读取(FileInputStream 读取本地文件)

    文件读取(FileInputStream 读取本地文件)使用FileInputStream读取本地文件(图片、视频、音乐、文档资料)二进制文件、文本文件1.在物理存储上上没有什么区别,存在硬盘上都是以二进制方式存储2.解释数据的逻辑不同,程序读取文本文件,可以以字符方式读取,也可以以字节读取,将读取的数据解释为ASCII或者unicode编码;当程序读取二进制文件,以字节方式读取,对读取数据的解释由读取数据而定,如读取图片时,需要了解文件的结…

  • vue中使用animate css

    vue中使用animate cssvue2使用animatecss安装安装的方式有很多种1.在html文件中直接引用从github上下载的资源&lt;linkrel="stylesheet"href="vue2-animate.min.css"&gt;2.如果使用webpack并且用对了css-loader可以使用npm安装npm安装包依赖npminstall–savevue2-animate3…

  • DLL注入与安全

    DLL注入与安全伊始  安全与危险是共存的。如果我们了解危险的来源以及产生的过程,对于安全防护拥有很现实的意义。  本文主要介绍dll注入的方式,意在描述危险的来源,以及危险的执行的过程,以便于我们解决危险。主体这篇文章介绍2大类:序号方式1调用API2直接修改源码1.调用API  如果要实现注入,那么需要一个目标,一个DLL,一个注入程序。原理:  代码的执行…

  • phpstorm-2021.5.1激活码【在线注册码/序列号/破解码】「建议收藏」

    phpstorm-2021.5.1激活码【在线注册码/序列号/破解码】,https://javaforall.cn/100143.html。详细ieda激活码不妨到全栈程序员必看教程网一起来了解一下吧!

  • 倾斜摄影当中重叠度、传感器尺寸、焦距等参数问题梳理[通俗易懂]

    倾斜摄影当中重叠度、传感器尺寸、焦距等参数问题梳理[通俗易懂]1序随着无人机的快速发展,倾斜摄影行业迎来了一个新的浪潮,越来越多的人利用无人机从事测绘行业的相关数据采集工作。在数据采集过程当中遇到了各种各样的问题,导致飞出来的数据不达标,无法完成模型重建工作。这里根据自己的接触对倾斜摄影过程当中重叠度、传感器、焦距、飞行速度、拍照间隔等参数以及他们之间的相互关系做一个简单的梳理。如有不当或错误之处敬请指正。本文很多内容参考自【Sm

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号