datasheet

STM32学习笔记--NVIC中断

2019-04-22来源: eefocus关键字:STM32  学习笔记  NVIC中断

朋友们,如果你需要在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。这就是抢占优先级和响应优先级的区别。


关键字:STM32  学习笔记  NVIC中断

编辑:什么鱼 引用地址:http://news.eeworld.com.cn/mcu/ic459400.html
本网站转载的所有的文章、图片、音频视频文件等资料的版权归版权所有人所有,本站采用的非本站原创文章及图片等内容无法一一联系确认版权者。如果本网所选内容的文章作者及编辑认为其作品不宜公开自由传播,或不应无偿使用,请及时通过电子邮件或电话通知我们,以迅速采取适当措施,避免给双方造成不必要的经济损失。

上一篇:stm32f103学习笔记——NVIC初始化
下一篇:STM32 的优先级NVIC配置

关注eeworld公众号 快捷获取更多信息
关注eeworld公众号
快捷获取更多信息
关注eeworld服务号 享受更多官方福利
关注eeworld服务号
享受更多官方福利

推荐阅读

基于stm32f103的矩阵键盘

我现在的任务是做一个8*8的矩阵键盘,制PCB版之前,我用电路板搭了一个3*3的矩阵键盘来模拟一下,设置PA0、PA1、PA2为PP输出,设置P3、P4、P5下拉输入。大多数的芯片内部上拉或下拉电阻都是弱上拉或弱下拉,stm32f103的内部也一样,内部上拉或下拉的电阻阻值约为40K,这样可以方便外部调整,但是,在作为一些通讯引脚时,可能会出现上电时数据不稳定的问题,如I2C通讯,解决的办法是在外部在加上一个较强的上拉或下拉即可。具体程序如下:#include <stm32f10x.h>#include "usart.h"void KeyBoard_Init(void)//按键初始化
发表于 2019-08-16

基于 STM32F407 使用 4*4 矩阵键盘

写在前面:这是我第一次开始写博客,可能写的不是很好,也请大家谅解。本人现在大三,以前在学习过程中遇到过各种各样的问题,关于51单片机,STM32单片机,最近在学习ARM11的Tiny6410以后还会更新一些C/C++/Qt等等方面的东西关于写博客这件事,其实 一直想写博客记录下来,但是因为某些原因(懒),so , 没有写。现在开始,以后遇到单片机上或者编程上遇到的问题,并且自己很好地解决了,我就会在这里记录下来。希望通过博客记录我的学习历程并希望我所解决问题的过程能够帮到需要的人,一起加油吧!!!我是在STM32F407开发板上使用的4*4 矩阵键盘下面是我所使用的开发板1、首先介绍一下4*4矩阵键盘扫描原理 
发表于 2019-08-16
基于 STM32F407 使用 4*4 矩阵键盘

基于STM32F407最小系统板三种矩阵键盘实现方法

0xe0:return 0xe7; case 0xd0:return 0xd7; case 0xb0:return 0xb7; case 0x70:return 0x77; } } if(mode) key =1; if((GPIO_ReadInputData(GPIOA)&0xF0)==0xF0) key =1; return 0;}比较:三种方案其实,第二种方案比较通用,第一种比较简单易懂,前两种都比较好,因为按键按下不松开,并不会影响CPU一直停留在while()循环里啥都不干。最后的实验效果:之前用的板子是STM32F107,数据手册中的GPIO口一些输出输入方式的配置与STM32
发表于 2019-08-16
基于STM32F407最小系统板三种矩阵键盘实现方法

STM32笔记(二)(寄存器)——矩阵键盘

      矩阵键盘是我第一个需要动手焊接东西的实验,是3*3的键盘,焊了一个下午。因为是第一次焊东西,有多处不足,但最后也勉强能用。键盘的电路是组长设计的,希望下一次我能自己独立设计电路。键盘外观正面背面  外观略显粗糙。。。。主要代码       矩阵键盘最主要的一部分代码就是按键扫描部分,通过一个扫描函数对高低电平进行判断,从而确定按键的位置。用过串口输出案件编号1~9。key.c代码void KEY_Init1(void){ RCC->APB2ENR|=1<<3;      JTAG_S
发表于 2019-08-16
STM32笔记(二)(寄存器)——矩阵键盘

STM32 学习笔记 一.矩阵键盘

刚刚接触STM32,感觉和arduino完全是两个难度,如果说arduino是乐高积木,那我感觉STM32就跟盖楼一样,哈哈,是真的难,真的极具挑战性,可能是我刚开始学觉得难,到后面熟练了应该会好一些,言归正传,就讲一讲我们学长给我们下的任务矩阵键盘。学长学姐们做的是九键的矩阵键盘,我们做的是四键的,难度其实相差不大,换汤不换药的类型,原理就是一二号线通高电平,三四号线低电平,然后交换,让一二号低电平,三四号高电平这样就可以确定是哪个按键被按下。OK上代码key.c函数#include "key.h"#include "delay.h"#include "usart.h"v
发表于 2019-08-16
STM32 学习笔记 一.矩阵键盘

STM32 矩阵键盘通过串口输出

STM32F103C8T6 4*4矩阵键盘 通过串口输出,可以用来写密码锁程序的思路如下:1、首先需要配置的是矩阵键盘:配置两个函数:  KEY44_Init(矩阵键盘初始化)和key44_Scan(扫描并获取值)   。2、其次,设置串口(本文设置为STM32F103C8T6的串口三): 我们需要对USART进行初始化设置,详细请见下文。3、然后就开始写我们的主函数:主函数比较简单。因为程序已经分装了。4、最后我们要实现按下一个键,串口打出一个字符(按下1键,打出1)——————————————————————————————————————————————————-下边为程序:所用芯片
发表于 2019-08-16

小广播

何立民专栏

单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号 电信业务审批[2006]字第258号函 京公海网安备110108001534 Copyright © 2005-2019 EEWORLD.com.cn, Inc. All rights reserved