NVIC, Nested Vectored Interrupt Controller

Frm:http://blog.csdn.net/tianjueyiyi/article/details/49127749

朋友们,如果你需要在STM32上移植RTOS,那么首先必须深入理解它的中断系统。什么是NVIC?即嵌套向量中断控制器(Nested Vectored Interrupt Controller)。STM32的中有一个强大而方便的NVIC,它是属于Cortex内核的器件,不可屏蔽中断 (NMI)和外部中断都由它来处理,而SYSTICK不是由 NVIC来控制的。

●  60个可屏蔽中断通道(不包含16个Cortex™-M3的中断线);

●  16个可编程的优先等级(使用了4位中断优先级);

●  低延迟的异常和中断处理;

●  电源管理控制;

●  系统控制寄存器的实现;

1.中断优先级分组

  STM32(Cortex-M3)中有两个优先级的概念--抢占式优先级和响应优先级,有人把响应优先级称作‘亚优先级‘或‘副优先级‘,每个中断源都需要被指定这两种优先级。

具有高抢占式优先级的中断可以在具有低抢占式优先级的中断处理过程中被响应,即中断嵌套,或者说高抢占式优先级的中断可以嵌套在低抢占式优先级的中断中。

当两个中断源的抢占式优先级相同时,这两个中断将没有嵌套关系,当一个中断到来后,如果正在处理另一个中断,这个后到来的中断就要等到前一个中断处理完之后才能被处理。如果这两个中断同时到达,则中断控制器根据他们的响应优先级高低来决定先处理哪一个;如果他们的抢占式优先级和响应优先级都相等,则根据他们在中断表中的排位顺序决定先处理哪一个。

Cortex内核具有强大的异常响应系统,它把能够打断当前代码执行流程的事件分为异常(exception)和中断(interrupt),并把它们用一个表管理起来,编号为0~15的称为内核异常,而16以上的则称为外部中断,这个表就称为中断向量表。

正是因为每个中断源都需要被指定这两种优先级,就需要有相应的寄存器位记录每个中断的优先级;在Cortex-M3中定义了8个比特位用于设置中断源的优先级,这8个比特位可以有8种分配方式,如下:

1. 所有8位用于指定响应优先级

2. 最高1位用于指定抢占式优先级,最低7位用于指定响应优先级

3. 最高2位用于指定抢占式优先级,最低6位用于指定响应优先级

4. 最高3位用于指定抢占式优先级,最低5位用于指定响应优先级

5. 最高4位用于指定抢占式优先级,最低4位用于指定响应优先级

6. 最高5位用于指定抢占式优先级,最低3位用于指定响应优先级

7. 最高6位用于指定抢占式优先级,最低2位用于指定响应优先级

8. 最高7位用于指定抢占式优先级,最低1位用于指定响应优先级

以上便是优先级分组的概念,但是Cortex-M3允许具有较少中断源时使用较少的寄存器位指定中断源的优先级。

而STM32对这个表重新进行了编排,把编号从-3至6的中断向量定义为系统异常,编号为负的内核异常不能被设置优先级,如复位(Reset)、不可屏蔽中断 (NMI)、硬错误(Hardfault)。从编号 7开始的为外部中断,这些中断的优先级都是可以用户更改的。详细的 STM32中断向量号可以在startup_stm32f10x_XX.s中查找。

因此STM32把指定中断优先级的寄存器位减少到4位,这4个寄存器位的分组方式如下:

第0组:所有4位用于指定响应优先级(16种)

第1组:最高1位用于指定抢占式优先级,最低3位用于指定响应优先级(8种)

第2组:最高2位用于指定抢占式优先级,最低2位用于指定响应优先级(4种)

第3组:最高3位用于指定抢占式优先级,最低1位用于指定响应优先级(2种)

第4组:所有4位用于指定抢占式优先级

  这里便对于于文章最前提到的固件库里相关的函数了——NVIC_PriorityGroupConfig(u32 NVIC_PriorityGroup),函数的参数共有5种:

这个函数的参数(NVIC_PriorityGroup值)有下列5种:

NVIC_PriorityGroup_0 => 选择第0组

NVIC_PriorityGroup_1 => 选择第1组

NVIC_PriorityGroup_2 => 选择第2组

NVIC_PriorityGroup_3 => 选择第3组

NVIC_PriorityGroup_4 => 选择第4组

这其实也很好理解,比如选择NVIC_PriorityGroup_1,那么抢占式优先级便占一位,也就是说可以有2^1个级别,可以设置为0和1,而响应优先级则占3位,也就是说可以有2^3个选择,可以设置为0~7;总共来说就可以区别>16种优先级了。

  //NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;

 //NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;

举个例子吧,假如现在有4个外部中断,还有一个EXTI9_5中断,那么如果选择优先级分组为第1组,那么抢占式优先级便只有两种,5个中断就至少有3个在抢占式优先级上是相同的优先级上,其他两个在令一优先级别。接着设置响应优先级可以有8种选择;假如现在同时有两个抢占式优先级别相同的中断发生,那么处理的顺序是谁的响应优先级高则谁优先进入中断,另外这点是需要注意的,如果此时进入这个中断之后又来了一个抢占式优先级相同但是响应优先级更高的中断,这时也是不会打断已有的中断的。

 void NVIC_Config(void)

{

    NVIC_InitTypeDef NVIC_InitStructure;

    #ifdef  VECT_TAB_RAM

    //Set the Vector Table base location at 0x20000000 

    NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0);

    #else

    //Set the Vector Table base location at 0x08000000 

    NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0); 

    #endif

    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);  //中断优先级组 :1组(整个系统为同一组)

    // 设置抢占优先级0~1,响应优先级0~7

    NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;             // TIM2 全局中断

    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;   // 抢占优先级 1

    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;          // 响应优先级 0

    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;             // IRQ通道被使能

    NVIC_Init(&NVIC_InitStructure);

    //* Enable the TIM3 Interrupt

    NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;             // TIM3 全局中断

    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;   // 抢占优先级 1

    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;          // 响应优先级 1

    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;             // IRQ通道被使能

    NVIC_Init(&NVIC_InitStructure);

    NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;           // USART1 全局中断

    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;   // 抢占优先级   0

    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;          // 响应优先级   0

    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;             // IRQ通道被使能

    NVIC_Init(&NVIC_InitStructure);

}

说明:假如TIM3是正在运行的中断,如果USART1中断也发生了,则优先处理,TIM3被嵌套并挂起;如果TIM2中断发生了,则需要等到TIM3处理完之后再处理TIM2。这就是抢占优先级和响应优先级的区别。

void NVIC_Config(void)

{

NVIC_InitTypeDef NVIC_InitStructure;

#ifdef  VECT_TAB_RAM

//Set the Vector Table base location at 0x20000000

NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0);

#else

//Set the Vector Table base location at 0x08000000

NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);

#endif

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);  //中断优先级组 :1组(整个系统为同一组)

// 设置抢占优先级0~1,响应优先级0~7

NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;             // TIM2 全局中断

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;   // 抢占优先级 1

NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;          // 响应优先级 0

NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;             // IRQ通道被使能

NVIC_Init(&NVIC_InitStructure);

//* Enable the TIM3 Interrupt

NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;             // TIM3 全局中断

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;   // 抢占优先级 1

NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;          // 响应优先级 1

NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;             // IRQ通道被使能

NVIC_Init(&NVIC_InitStructure);

NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;           // USART1 全局中断

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;   // 抢占优先级   0

NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;          // 响应优先级   0

NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;             // IRQ通道被使能

NVIC_Init(&NVIC_InitStructure);

}

原文地址:https://www.cnblogs.com/qiyuexin/p/8367618.html

时间: 2024-10-12 01:22:01

NVIC, Nested Vectored Interrupt Controller的相关文章

Input/output subsystem having an integrated advanced programmable interrupt controller for use in a personal computer

A computer system is described having one or more host processors, a host chipset and an input/output (I/O) subsystem. The host processors are connected to the host chipset by a host bus. The host chipset is connected to the input/output subsystem by

Interrupt Controller

1. 中断处理是程序执行流程(顺序执行,跳转执行,中断处理)之一,发生中断后,arm处理器在执行完当前指令后跳转到中断对应的中断处理程序处执行,中断处理程序执行完成后,又回到原来跳转处的下一条指令处开始接着执行. 2. 中断处理流程: (1)中断发生后,中断控制器给 cpu 发送中断请求.   (2)如果 cpu 能够响应中断,则将运行环境保存起来,跳到中断异常处进行执行中断处理.   (3)识别中断来源,跳到相应中断服务程序处执行.   (4)中断服务执行完成后,恢复之前的运行环境,返回到原来

STM32 之 NVIC(中断向量、优先级) 简述

一.背景 需要使用STM32的CAN进行通信,经过一系列配置后,已可正常收发,还剩下一个CAN通信的错误处理.可错 误中断使能寄存器已经配置使能了,出错后就是无法进入"CAN1_SCE_IRQHandler"中断.(让CAN通信出错的的 办法很简单,将"CAN_H"与"CAN_L"直接短接,然后让其发送数据,正常情况下,就会触发错误中断了,发送错 误寄存器会瞬间加至"128",如果继续发,每发一次,发送错误计数器会+8,直到2

STM32F4 SPI with DMA

STM32F4 SPI with DMA A few people have requested code, so I thought I’d post the code showing how I’ve configured my GPIO, timer, SPI, DMA and NVIC modules, along with some explanation of how the system works.Note that I’m using the STM32F4 Standard

STM32之中断

1.NVIC Nested vectored interrupt controller :可嵌套向量中断控制器 (NVIC) NVIC 特性 82个可屏蔽中断 ##不包括内核的16个中断 16个可编程优先级 ##适用于全部中断 低延迟异常和中断处理 电源管理控制 系统控制寄存器的实现 NVIC与处理器内核接口紧密耦合, 实现了高效快速的中断响应.所有的中断,包括内核异常都被 NVIC 所管理. 2.中断向量表 其实中断向量表在**STM32F4XX**启动文件里面就可以看出来,详情可看 :[ST

STM32经典概述(干货 )

首先,在学习Cortex-M3时,我们必须要知道必要的缩略语.  在网上看的,觉得挺好的,分享过来了 整理如下: AMBA:先进单片机总线架构   ADK:AMBA设计套件 , AHB:先进高性能总线    AHB-AP:AHB访问端口APB:先进外设总线    ARM ARM:ARM架构参考手册ASIC:行业领域专用集成电路    ATB :先进跟踪总线BE8:字节不变式大端模式    CPI:每条指令的周期数DAP:调试访问端口    DSP:数字信号处理(器)DWT:数据观察点及跟踪   

GPIO和外部中断/时间控制器(EXTI)

2.1          GPIO的8种工作模式 GPIO工作图如下: 4种输入模式 结构图的上半部分分为输入模式结构, 分为上拉模式,下拉模式,浮空模式和模拟输入模式. 上/下拉模式:通过设置配置寄存器(CRL,CRH)来控制1和2开关,于是得到GPIO的上拉输入模式(GPIO_Mode_IPU)和下拉输入模式(GPIO_Mode_IPD). 浮空输入模式(GPIO_Mode_IN_FLOATING):没有接上下拉电阻,经由TTL施密特触发器输入. 配置成这个模式直接用电压表测量其引脚电压为1

STM32F3, STM32F4编程手册

1. Cortex-M4的内核设备 NVIC, Nested vectored interrupt controller SCB, System control block SysTick, The system timer MPU, Memory protection unit FPU, Floating-point unit 2. 程序员模型 2.1 处理器模式 Thread mode, 用于执行软件程序(可由CONTROL寄存器控制是否享有特权),复位后自动进入. Handler mode

STM32_中断

为什么要用中断? 常用的现实生活中的例子是,如果你正在看电视,门铃响了你该咋整? 这里门铃响了就是一个中断(interrupt),我们放下电视去开门就是一个中断服务子程序(ISP) STM32的中断介绍 Cortex-M3 内核支持 256 个中断,包括 16 个内核中断和 240 个外部中断: STM32F10x 有 84 个中断通道,包括 16 个内核中断和 68 个可屏蔽中断,也就是只用了 Cortex-M3 中断的一部分: 中断可以分配优先级,有的是固定死的,有的可以自定义. 中断会分配