NVIC简介
NVIC(Nested Vectored Interrupt Controller),中断嵌套向量控制器,是 Cortex‐M3 不可分离的一部分,它与 CM3 内核共同完成对中断的响应。在了解NVIC之前最好简单了解一下CM3内核的中断系统,传送。
NVIC 共支持 1 至 240 个外部中断输入(通常外部中断写作 IRQn),每个中断有最高256(最低8)级的优先级,具体的中断数和优先级级数由芯片厂商在设计芯片时决定(STM32F1支持60个外部中断,16级优先级)。此外,NVIC 还支持一个“永垂不朽”的不可屏蔽中断(NMI)输入。NMI 的实际功能亦由芯片制造商决定。在某些情况下,NMI 无法由外部中断源控制。
NVIC相关寄存器
在内核文件core_cm3.h中定义了NVIC相关的寄存器,
/** @addtogroup CMSIS_CM3_NVIC CMSIS CM3 NVIC
memory mapped structure for Nested Vectored Interrupt Controller (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) */
uint32_t RESERVED5[644];
__O uint32_t STIR; /*!< Offset: 0xE00 Software Trigger Interrupt Register */
} NVIC_Type;
/*@}*/ /* end of group CMSIS_CM3_NVIC */
中断使能寄存器 ISER[8] (Interrupt Set-Enable Registers),前面提到CM3 内核支持 256 个中断,这里用 8 个 32 位寄存器来控制,每个位控制一个中断。写1使能该位中断,写0无效。
中断除能寄存器 ICER[8] (Interrupt Clear-Enable Registers),该寄存器组与 ISER 的作用恰好相反,是用来清除某个中断的使能的。写1清除相应位中断,写0无效。
中断挂起寄存器 ISPR[8] (Interrupt Set-Pending Registers),每个位对应的中断和 ISER 是一样的。通过置 1,可以将正在进行的中断挂起,而执行同级或更高级别的中断。写0无效。
中断解挂寄存器 ICPR[8] (Interrupt Clear-Pending Registers),其作用与 ISPR 相反,对应位也和 ISER 是一样的。写1解挂,写0无效。
中断激活标志位寄存器 IABR[8] (Interrupt Active Bit Registers),只读寄存器,对应位所代表的中断和 ISER 一样,如果为 1,表示该位所对应的中断正在被执行,中断执行完由硬件自动清零。
中断优先级控制的寄存器 IP[240] (Interrupt Priority Registers),与中断分组密切相关,由 240 个 8bit 的寄存器组成,每个可屏蔽中断占用 8bit,最多共可表示 240 个可屏蔽中断(STM32 只用到了其中的前 60 个,IP[59]~IP[0]分别对应中断 59~0)。每个可屏蔽中断占用的 8bit 并没有全部使用,STM32只用了 4位(高四位[7:4],MSB),这 4 位又分为抢占优先级和子优先级,而这两个优先级各占几个位又要根据 SCB->AIRCR 中的中断分组设置来决定。
应用中断和复位控制寄存器 SCB_AIRCR
[10:8]位就是中断优先级分组的设置位。
这里再啰嗦一遍
中断优先级配置
中断优先级分组相关函数在misc.c/h文件中
void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup)//设置中断优先级分组
void NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct) //针对每个特定的中断设置抢占优先级和响应优先级
配置步骤
1.在主函数使用NVIC_PriorityGroupConfig()函数初始化的部分设置中断优先级分组,没有特殊情况的话,一般为分组2,即2位抢占优先级,2位响应优先级。
可选参数
NVIC_PriorityGroup_0 // 0位抢占优先级,4位响应优先级
NVIC_PriorityGroup_1 // 1位抢占优先级,4位响应优先级
NVIC_PriorityGroup_2
NVIC_PriorityGroup_3
NVIC_PriorityGroup_4 // 4位抢占优先级,1位响应优先级
2. 针对每个中断,使用NVIC_Init() 函数设置对应的抢占优先级和响应优先级。
参数为NVIC初始化结构体,其定义如下,包含的参数为:中断请求通道NVIC_IRQChannel、抢占优先级NVIC_IRQChannelPreemptionPriority、响应优先级(亚优先级)NVIC_IRQChannelSubPriority、中断通道使能控制NVIC_IRQChannelCmd。
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;
设置定时器3的抢占优先级举例如下:
主函数中;
int main(void)
{
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2: 2位抢占优先级,2位响应优先级
//×××_Int_Init(); 代码:外设中断配置函数
while(1)
{
//...
}
}
中断配置函数×××_Int_Init() 中:
×××_Int_Init()
{
NVIC_InitTypeDef NVIC_InitStructure;
//Device Init 代码:外设的初始化配置
NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn; //TIM3中断
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //先占优先级0级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //从优先级3级
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
NVIC_Init(&NVIC_InitStructure); //初始化NVIC寄存器
//Enable Device 代码:使能外设
}
上一篇:STM32-USART串口通信【USART和UART的区别】
下一篇:STM32-异常与中断
推荐阅读最新更新时间:2024-11-11 11:21
推荐帖子
- 底层丝印层这样的字打出来是正常的还是翻转的?
- 底层丝印层这样的字打出来是正常的,现在在底层丝印层,还是翻转的?没打过背面放丝印的板.求助底层丝印层这样的字打出来是正常的还是翻转的?这样打出来是反的。反了+1我一般都是分顶层和底层分别打印,顶层布线和丝印加上机械层或者禁止布线层,底层布线和底层丝印加机械层或禁止布线层,打印底层的时候在选项里选上mirror,打出来的字就是正的了底层放字要镜像设置astwyg发表于2014-2-1821:45反了+1 好,谢谢,改一改就可以去打了.如果用AD软件,可以按
- cl17726 PCB设计
- DDR3总线信号完整性测试需要关注4点
- 某工程师写的4点DDR测试注意事项DDR3总线信号完整性测试需要关注4点DDR3总线信号的测试是不是对示波器的带宽要求比较高,,至少1G?
- wstt PCB设计
- 相当急,快又要搞通宵了。WIN CE上的串口编程问题
- 我写了个程序。在WINDOWCE上跑的,我用VS2008建立了个MFC智能程序。我用串口调试助手测试,助手不停的发送数据。发现助手上能接收CE上发来的消息,可是CE上的程序却一直阻塞(或者我把线程里面的代码改成一直在读的时候。都是没读到任何东西。)第一次写CE,希望哪位大大指点具体代码如下: //按钮事件 OnBnClickedreaddata() { if(!OpenCom()) { Messa
- cooler1981 嵌入式系统
- TXBUF1这个是啥
- 单片机里的一个变量好像跟串口通讯有关.用声明吗表示啥意思怎么用有没有相关介绍提供点资料啥的谢TXBUF1这个是啥
- linjingui 单片机
- 以TI的一个SimpliciTI(点对点简单无线数传协议)例程为例,说一下重构
- 重构,用最简单的说法就是:在不改变代码现有功能的前提下,优化和改善代码。对代码而言,它的优化和改善是多方面的,为了避免这个话题过于庞杂,并且超出我们的能力范围。我们只着重考虑我们所关心的部分代码质量问题。这里说的“代码质量”,是楼主临时想到的一个提法,如字面意思。现阶段,楼主所考虑的代码质量比较简单,只包含:1.代码以功能为单位,尽可能地模块化,子函数化,更低耦合性,更独立——你可以理解成,一旦达成这样的目的,你可以很轻易地把在某个在PC上使用的代码直接放到51程序里而甚至无
- 辛昕 编程基础
- 利德华富 东方日立 明阳龙源
- 小弟对这个行业非常感兴趣,毕竟现在国家大力提倡环保,最近去明阳龙源发现该企业真的不错,技术产品全而广,设计、服务到位,增长速度可观。有志者可多交流交流利德华富东方日立明阳龙源
- beh 工控电子
设计资源 培训 开发板 精华推荐
- ESP8266遥控器
- LT6656AIDC-5 的典型应用,用于基本连接的 5V 电压基准
- DC895A-D,使用 LT3485EDD-3、750mA 输入电流、2.8 至 4.2Vin、1.8 至 4.2VBat、最大 5V 闪光灯充电器的演示板
- 使用 OP497 的 OP497GSZ-REEL 简易桥式调理放大器的典型应用电路
- 使用 Richtek Technology Corporation 的 RT8231BGQW 的参考设计
- KIT912J637EVME,MM912J637 评估套件,12V 铅酸电池传感器
- 智能家居控制器
- FRDM-PF1510EVM: PF1510 Evaluation Board for low power application processors
- MIC5317 典型应用:高性能单路 150mA LDO
- CM6631A USB界面卡