(1)NVIC
    全称为Next Vector Interrupt Controoler,嵌套中断向量控制器,是ARM Cortex M3的内部设备之一,任何一款基于ARM Cortex M3的内核都带有NVIC。
(2)中断响应
    当某个中断来临,会将相应的中断标志位置位。当CPU查询到这个置位的标志位时,会响应此中断,并执行相应的中断服务函数,中断标志位要手动清除,否则会不断产生中断。
(3)中断优先级——抢占式优先级和响应优先级
    在ARM Cortex M3中,每个中断源都要指定两种优先级,分别为抢占式优先级和响应优先级。
    所谓抢占式优先级和响应优先级,他们之间的关系是:
1. 具有高抢占式优先级的中断可以在具有低抢占式优先级的中断处理过程中被响应,即中断嵌套。
2. 当两个中断源的抢占式优先级相同时,这两个中断将没有嵌套关系,当一个中断到来后,如果正在处理另一个中断,这个后到来的中断就要等到前一个中断处理完之后才能被处理,即后到的中断进入挂起状态(中断挂起),等待执行
3. 如果这两个中断同时到达,则中断控制器根据他们的响应优先级高低来决定先处理哪一个;
4. 如果他们的抢占式优先级和响应优先级都相等,则根据他们在中断表中的排位顺序决定先处理哪一个。每一个中断源都必须定义2个优先级。
注意:
1. 如果指定的抢占式优先级别或响应优先级别超出了选定的优先级分组所限定的范围,将可能得到意想不到的结果;
2. 抢占式优先级别相同的中断源之间没有嵌套关系;
3. 如果某个中断源被指定为某个抢占式优先级别,又没有其它中断源处于同一个抢占式优先级别,则可以为这个中断源指定任意有效的响应优先级别。
4. 中断嵌套完全由抢占式优先级决定的。
(5)中断优先级分组
    ARM Cortex M3的每个中断通道都具备自己的中断优先级控制字节PRI_n(8位,但是STM32中只使用4位,高4位有效),每4个通道的8位中断优先级控制字构成一个32位的优先级寄存器。68个通道的优先级控制字至少构成17个32位的优先级寄存器。4bit的中断优先级可以分成2组,从高位看,前面定义的是抢占式优先级,后面是响应优先级。按照这种分组,4bit一共可以分成5组
第0组:所有4bit用于指定响应优先级;
第1组:最高1位用于指定抢占式优先级,后面3位用于指定响应优先级;
第2组:最高2位用于指定抢占式优先级,后面2位用于指定响应优先级;
第3组:最高3位用于指定抢占式优先级,后面1位用于指定响应优先级;
第4组:所有4位用于指定抢占式优先级。
    从上面可以看出,第几组,抢占优先级则最高为几位。
(6)GPIO外部中断EXTI
    STM32中,每一个GPIO都可以触发一个外部中断,每个输入通道都可以独立配置输入类型(脉冲或挂起?)和对应的触发事件(上升沿或下降沿或双边沿都触发),每个输入通道都可以独立被屏蔽,挂起寄存器会保持着某个通道的中断请求。
    STM32一共为GPIO配置了19个中断通道,其中16个由用户自由支配,分别EXTI0-15,而EXTI16-18通道分配给了RTC,PVD,USB使用,可以检测脉冲宽度低于APB2时钟宽度的外部信号。
    但是,GPIO的中断是以组位一个单位的,同组间的外部中断同一时间只能使用一个。比如说,PA0,PB0,PC0,PD0,PE0,PF0,PG0这些为1组,如果我们使用PA0作为外部中断源,那么别的就不能够再使用了,在此情况下,我们只能使用类似于PB1,PC2这种末端序号不同的外部中断源。每一组使用一个中断标志EXTIx。EXTI0 – EXTI4这5个外部中断有着自己的单独的中断响应函数,EXTI5-9共用一个中断响应函数,EXTI10-15共用一个中断响应函数。
    简而言之,就是相同末端序号的GPIO口共用一个中断通道,一个或多个中断通道共用一个中断函数。
(7)STM32中断函数特性
    当中断发生后,ARM处理器会处理当前指令后,跳转到中断函数执行,执行完会回到原来的地方继续执行。发生中断时,寄存器R0-R3,R12,LR,PSR,PC会自动入栈,中断返回时会自动出栈,无需汇编代码支持,由硬件完成。中断函数地址存储于中断向量表里。中断向量表一旦初始化完成,该段内容便不可以修改。
(8)中断向量表及其相关的三个变量
    中断函数地址存储于中断向量表里。中断向量表一旦初始化完成,该段内容便不可以修改。_Vectors_Size、_Vectors_End、_Vectors三个常量分别指定了中断向量表的大小、结束地址、起始地址,在中断向量表重映射是需要使用这三个常量。
(9)外部中断的基本步骤:
1. 设置时钟
2. 设置中断
3. IO口初始化
4. 在设置外部中断前,把相应的IO口设置为中断线路,并初始化
5. 中断函数
 

中断使用步骤及注意事项

1 设置相应GPIO时钟

GPIO时钟的设置涉及到了两个方面:

(1)被控制的GPIO

(2)用于中断的GPIO

上述两种GPIO都要设置时钟,如果该IO口为复用IO口,则要顺便开启RCC_APB2Periph_AFIO时钟,如下:

/* config the extiline(PC13) clock and AFIO clock */

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC | RCC_APB2Periph_AFIO,ENABLE);

1.1 RCC_APB2PeriphClockCmd函数

2 设置中断分组和通道优先级

/**

* @brief  配置嵌套向量中断控制器NVIC

* @param  无

* @retval 无

*/

static void NVIC_Configuration(void)

{

NVIC_InitTypeDef NVIC_InitStructure;

/* Configure one bit for preemption priority */

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);

/* 配置P[A|B|C|D|E]13为中断源 */

NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn;

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;

NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;

NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

NVIC_Init(&NVIC_InitStructure);

}

2.1 设置中断优先级分组,共有5个

2.1.1 NVIC_PriorityGroupConfig函数

2.2 设置各个中断通道的抢占式优先级和响应式优先级

2.2.1 NVIC_InitTypeDef结构体

2.2.2 NVIC_Init函数

3 IO口初始化

3.1 GPIO_InitTypeDef结构体

3.2 GPIO_Init函数

4 把相应的IO口设置为中断线路

由于GPIO并不是专用的中断引脚,因此在用GPIO来触发外部中断的时候需要设置将GPIO相应的引脚和中断线连接起来

/**

* @brief  配置 PC13 为线中断口,并设置中断优先级

* @param  无

* @retval 无

*/

void EXTI_PC13_Config(void)

{

GPIO_InitTypeDef GPIO_InitStructure;

EXTI_InitTypeDef EXTI_InitStructure;

/* config the extiline(PC13) clock and AFIO clock */

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC | RCC_APB2Periph_AFIO,ENABLE);

/* config the NVIC(PC13) */

NVIC_Configuration();

/* EXTI line gpio config(PC13) */

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;    // 上拉输入

GPIO_Init(GPIOC, &GPIO_InitStructure);

/* EXTI line(PC13) mode config */

GPIO_EXTILineConfig(GPIO_PortSourceGPIOC, GPIO_PinSource13);

EXTI_InitStructure.EXTI_Line = EXTI_Line13;

EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;

EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; //下降沿中断

EXTI_InitStructure.EXTI_LineCmd = ENABLE;

EXTI_Init(&EXTI_InitStructure);

}

4.1  EXTI_InitTypeDef结构体

4.2 函数

4.2.1 GPIO_EXTILineConfig

4.2.2 EXTI_ClearITPendingBit

4.2.3  EXTI_Init

5 写中断响应函数

相对应的中断函数名一定要和startup_stm32f10x_hd.s相同

 
参考资料:
 

【原创】NVIC中断的更多相关文章

  1. cortex m0 lpc1114的NVIC中断如何使用

    LPC1114单片机的NVIC中断函数,有开中断.关中断.设置优先级.挂起等操作函数.这些函数位于core_cm0.h文件里面.比如开中断的函数如下: /** \brief Enable Extern ...

  2. 【STM32H7教程】第21章 STM32H7的NVIC中断分组和配置(重要)

    完整教程下载地址:http://www.armbbs.cn/forum.php?mod=viewthread&tid=86980 第21章       STM32H7的NVIC中断分组和配置( ...

  3. STM32学习笔记-NVIC中断知识点

    STM32学习笔记-NVIC中断知识点总结 中断优先级设置步骤 1. 系统运行后先设置中断优先级分组 函数:void NVIC_PriorityGroupConfig(uint32_tNVIC_Pri ...

  4. 【原创】中断子系统-ARM GPIO中断处理流程

    目录 第一部分 GIC中断控制器的注册 1. GIC驱动分析 2.GIC驱动流程分析 第二部分 device node转化为platform_device 第三部分:platform_device注册 ...

  5. 嵌入式02 STM32 实验11 NVIC和中断总结

    一.基础知识 1.cortex-m3支持256个中断,其中包含了16个内核中断,240个外部中断 2.STM32只有84个中断,包括16个内核中断和68个可屏蔽中断 3.STM32F103上只有60个 ...

  6. stm32学习笔记——外部中断的使用

    stm32学习笔记——外部中断的使用 基本概念 stm32中,每一个GPIO都可以触发一个外部中断,但是,GPIO的中断是以组为一个单位的,同组间的外部中断同一时间只能使用一个.比如说,PA0,PB0 ...

  7. STM32 NVIC

    在stm32中是要配置nvic的.何为nvic,对于我这样的初学者来说,直观感受就是在设置为中断后 还需要配置 中断的优先级nvic就是搞这个的. 那么具体的需要配置些什么那? void NVIC_C ...

  8. (二)stm32之中断配置

    一.stm32的中断和异常 Cortex拥有强大的异常响应系统,它能够打断当前代码执行流程事件分为异常和中断,它们用一个表管理起来,编号为0~15为内核异常,16以上的为外部中断,这个表就是中断向量表 ...

  9. LPC1768之中断

    一外中断:只有特定的4个外中断引脚, 1 在特定的引脚上,引脚功能要选对应的外中断功能 2设定的触发条件(高低电平.上升/下降沿) 3 NVIC设定,特定的通道. 二GPIO中断: 1只有GPIO0和 ...

随机推荐

  1. Spring 出现Could not resolve placeholder问题的解决方法

    项目开发中,使用@value注解获取不到配置文件里面的属性字段. 检查配置文件,在spring的配置文件中有配置读取,如下: <!-- 使用spring自带的占位符替换功能 --> < ...

  2. python 方法

    1.首先运行python交互模式 输入 python 2.定义一个有序的集合 相当于js中的数组它里面有一些增删改查的方法 1. 定义一个数组 >>> ww = ['1','2',' ...

  3. 学以致用三十一-----IPAddressField has been removed

    python 和 django版本 在进行makemigrations的时候报错 设置的字段 class Servers(models.Model): '''服务器信息''' hostname = m ...

  4. 注入Shellcode并运行攻击

    注入Shellcode并运行攻击 一.实验步骤 1.安装execstack并修改设置 安装execstack apt-get install execstack 设置堆栈可执行 execstack - ...

  5. 【Android开源库】 PagerSlidingTabStrip从头到脚

    简介 PagerSlidingTabStrip,是我个人经常使用到的一个和ViewPager配合的页面指示器,可以满足开发过程中常用的需求,如类似于今日头条的首页新闻内容导航栏等等,之前自己开发的Ju ...

  6. c++中的const与指针

    const修饰符 使用const修饰变量时,该变量的值不可修改,因此需要初始化. 例如 const int s = 0: 此时s为值不可变的变量. 那么基于此,当const修饰指针时的情况有三种: ( ...

  7. Memcached未授权访问

    概念 memcached是一个内存中的键值存储区,用于存储来自数据库调用.API调用或页面呈现结果的任意小数据块(字符串.对象).memcached简单但功能强大.其简单的设计促进了快速部署.易于开发 ...

  8. Postgresql 数据库错误修复v0.1

    PS. 查询\nebula_boh\logs\BOHInterfaceLog.log 日志, 一般数据库文件损坏的日志 有 “UncategorizedSQLException” 或 “zero pa ...

  9. Java中main方法参数String[ ] args的使用。

    我们刚开始学习java时都会被要求记住主方法(main)的写法,就像这样: public static void main(String[] args){ } public static void m ...

  10. OO第一次博客总结

    虽然早在开学之前就已耳闻过OO这门课的威力,也在寒假自学了一些java的语法,但在真正面对OO这样的工程训练时才发现寒假所学的那点语法简直不值一提,也深刻的感受到在这个过程中自己的提升确实很快,毕竟d ...