stm32之NVIC

发布者:柳絮轻风最新更新时间:2016-07-27 来源: eefocus关键字:stm32  NVIC 手机看文章 扫描二维码
随时随地手机看文章

STM32的NVIC理解  (绿色和紫色分别为其他优秀网友成果,真诚的感谢。现拷贝过来汇总方便大家学习,如若构成侵权请及时联系)

例程:  /* Configure one bit for preemption priority */
  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
  
  /* Enable the WAKEUP_BUTTON_EXTI_IRQn Interrupt */
  NVIC_InitStructure.NVIC_IRQChannel = WAKEUP_BUTTON_EXTI_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = PreemptionPriorityValue;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);
  
  /* Enable the KEY_BUTTON_EXTI_IRQn Interrupt */
  NVIC_InitStructure.NVIC_IRQChannel = KEY_BUTTON_EXTI_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);
  
  /* Configure the SysTick Handler Priority: Preemption priority and subpriority */
  NVIC_SetPriority(SysTick_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), !PreemptionPriorityValue, 0));

这两日被些许琐事所牵,身心俱累,本无心记录,但回想前几天的点滴收获,无录甚是可惜,于是身倚椅,旁敲键盘记之,唯慰藉自己及共享同道仁友。废言不再多,就此入题。

 

        NVIC,中文名嵌套中断向量控制器,是Cortex-M3系列控制器内部独有集成单元,与CPU结合紧密,降低中断延迟时间并且能更加高效处理后续中断。举个例子,比如火车站买票,那些火车站的规章制度就是NVIC,规定学生和军人有比一般人更高优先级,它们则给你单独安排个窗口,同学与同学之间也有区别,那就是你也得排队,也就是你的组别(抢断优先级)和你的排队序号(响应优先级)决定你何时能买到票。

       抢断优先级,顾名思义,能再别人中断是抢占别人中断,实现中断嵌套。响应优先级则只能排队,不能抢在前面插别人的对,即不能嵌套。

STM32中指定优先级的寄存器为4位,其定义如下:

第0组:所有4位用于指定响应优先级
第1组:最高1位用于指定抢占式优先级,最低3位用于指定响应优先级
第2组:最高2位用于指定抢占式优先级,最低2位用于指定响应优先级
第3组:最高3位用于指定抢占式优先级,最低1位用于指定响应优先级
第4组:所有4位用于指定抢占式优先级

以上定义也称作中断优先级分组,相关内容在STM32固件库的misc.h文件中有详细定义。

基础了解了就可以对中断进行操作了。

第一步:使用void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup)函数对优先级分组配置。NVIC_PriorityGroup可以配置为

NVIC_PriorityGroup_0 => 选择第0组
NVIC_PriorityGroup_1 => 选择第1组
NVIC_PriorityGroup_2 => 选择第2组
NVIC_PriorityGroup_3 => 选择第3组
NVIC_PriorityGroup_4 => 选择第4组

例如:NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0)配置为0组。

第二步:中断初始化结构体配置,结构体类型定义如下:

typedef struct

{

  uint8_t NVIC_IRQChannel;                 

  uint8_t NVIC_IRQChannelPreemptionPriority;  //抢断优先级

  uint8_t NVIC_IRQChannelSubPriority;  //响应优先级      

  FunctionalState NVIC_IRQChannelCmd;      

} NVIC_InitTypeDef;

 

例如:STM32外部中断0配置如下

    EXTI_NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;

         EXTI_NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;  //抢占优先级别(0~1)

         EXTI_NVIC_InitStructure.NVIC_IRQChannelSubPriority = 7;  //响应优先级别(0~7)

         EXTI_NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

 

第三步:中断初始化结构体初始化操作如下

         NVIC_Init(&EXTI_NVIC_InitStructure);

 

第四步:开关总中断操作。在STM32中是通过改变CPU优先级来允许和禁止中断的。

(1)   下面两个函数等效关闭总中断

void NVIC_SETPRIMASK(void); 
void NVIC_SETFAULTMASK(void);

(2)   下面两个函数等效开放总中断

void NVIC_RESETPRIMASK(void); 
void NVIC_RESETFAULTMASK(void);

(3)   常用操作是先关后开中断

NVIC_SETPRIMASK();     // Disable Interrupts 
NVIC_RESETPRIMASK(); // Enable Interrupts

两种类型函数要成对使用。

STM32有43个channel的settable的中断源;AIRC(Application Interrupt and Reset Register)寄存器中有用于指定优先级的4 bits。这4个bits用于分配preemption优先级和sub优先级,在STM32的固件库中定义如下

#define NVIC_PriorityGroup_0 ((u32)0x700)
#define NVIC_PriorityGroup_1 ((u32)0x600)
#define NVIC_PriorityGroup_2 ((u32)0x500)
#define NVIC_PriorityGroup_3 ((u32)0x400)
#define NVIC_PriorityGroup_4 ((u32)0x300)

形象化的理解是:

你是上帝,
造了43个人,这么多人要分社会阶级和社会阶层了;
因为“阶级”的词性比较重;"阶层"比较中性,
所以preemption优先级->阶级;每个阶级内部,有一些阶层,sub优先级->阶层;

如果按照NVIC_PriorityGroup_4这么分,就分为了16个阶级(1个阶层就是1个preemption优先级),0个阶层;高阶级的人,可以打断低阶级的正在做事的人(嵌套),最多可以完成1个中断和15级嵌套。
每个阶级(每个preemption优先级),你来指定这43人中,谁进入该阶级;一个人叫EXTI0_IRQChannel,你指定他进入“阶级8”,则
NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQChannel;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 8; // 指定抢占式优先级别1,可取0-15

另外,在同一阶级内部,一个人在做事的时候,另外一个人不能打断他;(preemption优先级别相同的中断源之间没有嵌套关系)
还有,如果他们两个同时想做事,因为没有阶层,那么就根据Vector table中的物理排序,让排名靠前的人去做;

又有1个人SPI1_IRQChannel,设定如下
NVIC_InitStructure.NVIC_IRQChannel = SPI1_IRQChannel;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; // 指定抢占式优先级别1,可取0-15

SPI1_IRQChannel的阶级高,EXTI0_IRQChannel做事的时候可以打断(嵌套)。



如果按照NVIC_PriorityGroup_3这么分,就分为了8个阶级(1个阶级是1个preemption优先级),每个阶级内有2个阶层(sub优先级);高阶级的人,可以打断低阶级的正在做事的人(嵌套),最多可以完成1个中断和7级嵌套。

每个阶级(每个preemption优先级),你来指定这43人中,谁进入该阶级;一个人叫EXTI0_IRQChannel,你指定他进入“阶级3”,则:
NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQChannel;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3; // 指定抢占式优先级别1,可取0-7
还需要指定他的阶层:
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; // 指定响应优先级别0,可取0-1

另有1个人叫EXTI9_5_IRQChannel,他的阶级和阶层设定如下
NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQChannel;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3; // 指定抢占式优先级别0,可取0-7
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; // 指定响应优先级别1

那么这两个人是同一阶级的兄弟,一个人在做事的时候,另外一个人不能打断他;(preemption优先级别相同的中断源之间没有嵌套关系)
如果他们两个同时想做事,因为前者的阶层高,所以前者优先。

还有一个人叫USART1_IRQChannel,他的阶级和阶层设定如下
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQChannel;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; // 指定抢占式优先级别0,可取0-7
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; // 指定响应优先级别1

USART1_IRQChannel的优先级最高,当前面两个人做事的时候,他都可以打断(嵌套)。

以下的类推。
关键字:stm32  NVIC 引用地址:stm32之NVIC

上一篇:stm32程序下载成功但是不运行
下一篇:ARM Linux中断机制之中断的申请

推荐阅读最新更新时间:2024-03-16 15:01

学习STM32,你不得不了解的五大嵌入式操作系统
基于STM平台且满足实时控制要求操作系统,有以下5种可供移植选择。分别为μClinux、μC/OS-II、eCos、FreeRTOS和rt-thread。下面分别介绍这五种嵌入式操作系统的特点及不足,通过对比,读者可以根据自己的应用需求选择合适的平台。 TOP1:μClinux μClinux是一种优秀的嵌入式Linux版本,其全称为micro-control Linux,从字面意思看是指微控制Linux。同标准的Linux相比,μClinux的内核非常小,但是它仍然继承了Linux操作系统的主要特性,包括良好的稳定性和移植性、强大的网络功能、出色的文件系统支持、标准丰富的API,以及TCP/IP网络协议等。因为没有MMU
[嵌入式]
STM32串口打印printf发送中文乱码问题
1、首先要确保使用keil程序正确编译,并且程序经过调试,已经可以正常发送英文字符,但是发送中文字符时乱码。 2、使用记事本打开main.c文件(或其他主程序),点击另存为,在右下方选择编码方式为ANSI,替换原文件即可
[单片机]
STM32之DMA实例
DMA简介: DMA(Direct Memory Access,直接存储器存取),是一种可以减轻CPU工作量的数据存取方式,如今被广泛的使用。它在传输数据的同时,CPU可以做其他事,比如数据运算或者响应中断等,DMA就给CPU分担了不少的工作量! DMA工作分析: 如图,我们可以看到STM32内核,存储器,外设及DMA的连接,这些硬件最终通过各种各样的线连接到总线矩阵中,硬件结构之间的数据转移都经过总线矩阵的协调,使各个外设和谐的使用总线来传输数据。 下面看有与没有DMA的情况下,ADC采集的数据是怎样存放到SRAM中的? 1.如果没有DMA,CPU传
[单片机]
<font color='red'>STM32</font>之DMA实例
基于STM32的无线飞鼠(二)
在前一篇博客中讲了下一些题外话,从本篇开始讲讲重点的知识,说说无线飞鼠过程用到的模块 细说MPU6050 一、 MPU6050简介 二、 细节问题 三、 相关技术 四、 操作步骤 五、 实现代码 一、 MPU6050简介 MPU6050集成了3轴加速度和3轴陀螺仪,是一款不错的传感器模块,可以用在很多方面,比如:四轴飞控、空中鼠标、两轮平衡车、GPS定位方面、游戏机、3D遥控器、平板设备等等,此模块给我们提供了强大的数据供应,由于将加速度和陀螺仪集成到了一起,免去了组合这两个模块时之间的轴差问题,减少了包装问题,这两年很火,成了DIY制作者的最爱。 二、 细节问题 在淘宝上买MPU6050时,要注意一下几点
[单片机]
基于<font color='red'>STM32</font>的无线飞鼠(二)
STM32 GPIO BRR和BSRR寄存器
使用BRR和BSRR寄存器可以方便地快速地实现对端口某些特定位的操作,而不影响其它位的状态。 比如希望快速地对GPIOE的位7进行翻转,则可以: GPIOE- BSRR = 0x80; // 置'1' GPIOE- BRR = 0x80; // 置'0' 如果使用常规'读-改-写'的方法: GPIOE- ODR = GPIOE- ODR | 0x80; // 置'1' GPIOE- ODR = GPIOE- ODR & 0xFF7F; // 置'0' 有人问是否BSRR的高16位是多余的,请看下面这个例子: 假如你想在一个操作中对GPIOE的位
[单片机]
STM32 的加密实现
目的:对运行于STM32的嵌入式代码程序进行加密 编译环境:IAR Embedded System for ARM5.5 一.STM32Flash组织 STM32的Flash包括主存储器(HD版本,512KB)+信息块。信息块包括2KB的系统存储器(用于系统自举启动代码)和16字节的选项字节(8个字节数据+8个字节数据的反码)。 二、STM32读保护 STM32读保护是通过设置RDP选项字节,然后在系统重新复位加载了新的RDP选项字节后启动的。当保护字节被写入相应的值以后: ●通过从内置SRAM或FSMC执行代码访问主闪存存储器的操作,通过DMA1、DMA2、JTAG、SWV(串行线观察器)、SWD(串行线调试)、ETM和边
[单片机]
<font color='red'>STM32</font> 的加密实现
STM32笔记(一)---串口ISP模式下载原理
-------------------------- –串口ISP模式下载原理– -------------------------- 先放几张火哥的教程截图: 图1 图2 图3 图4 通过图1可以了解到,不同的下载方式中所需要的不同启动模式: 在项目实际应用中的Boot设置: 默认使用程序代码存储在主闪存存储器,配置方式:BOOT0=0,BOOT1=0,但是要预留boot0上拉电阻工位,便于将其电平拉高,实现串口烧录。 如图3所示,只需要通过改变RTS电位使S8550是否导通,导通时实现图2的电路效果将Boot0拉高,否则Boot0为低电位。 一旦完成Boot0与Boot1的10设置后,需要
[单片机]
<font color='red'>STM32</font>笔记(一)---串口ISP模式下载原理
ucgui汉字库存放到外部的flash(控件可用)及写外部FLASH软件
最近项目中用到几种字体,stm32的内部flash以经入不敷出。没办法!只好找度娘及求助群里的高手,这里对 Eric2013 , 洋洋kan世界 等高手表示感谢。学习了他们的一些思想。 下面是找到的相关链接: http://blog.chinaunix.net/uid-361890-id-2953183.html http://www.openedv.com/posts/list/9736.htm;jsessionid=6B5FA51FE6BBC280B752D9B6 3BA57895 这里我主要用的是 crazytyt 文章的方法,在他的基础上进行一定的改进。解决控件用汉字居中等问题。 其实我的方法很简单,增加了每
[单片机]
ucgui汉字库存放到外部的flash(控件可用)及写外部FLASH软件
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

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

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved