STM32中断及NVIC概述

发布者:EnchantedMagic最新更新时间:2019-02-18 来源: eefocus关键字:STM32  中断  NVIC概述 手机看文章 扫描二维码
随时随地手机看文章

参考资料《STM32F4xx 中文参考手册》第十章-中断和事件、《 ARM Cortex™-M4F 技术参考手册》-4.3 章节:NVIC 和 4.4章节:SCB—4.4.5的 AIRCR。


对51单片机有一定了解的都知道51单片机有5个中断源,2个优先级,通过对IP这个寄存器赋值来进行中断优先级的处理而STM32的中断非常强大,每个外设都可以产生中断,那么STM32如何进行中断优先级的分配呢,这时就用到了NVIC(嵌套向量中断控制器), 支持为数众多的系统异常和外部中断。


下表即为STM32F42系列的中断向量表(了解即可),即中断类型



灰色部分即为内核的系统异常,灰色以外的其他部分即为片上所有外设可以产生的中断。priority值越小,优先级越高。


NVIC(Nested Vectored interrupt  controller)嵌套向量中断控制器,控制着整个芯片中断相关的功能,通过对NVIC寄存器进行配置可以实现对内核和片上外设的中断的控制。但是各个芯片厂商在设计芯片的时候会对 Cortex-M4内核里面的 NVIC进行裁剪,把不需要的部分去掉,所以说 STM32的 NVIC 是 Cortex-M4的 NVIC 的一个子集,只是用到了NVIC的一部分功能,其余的保留以后备用。


 NVIC 结构体定义,来自固件库头文件:core_cm4.h


typedef struct {

   __IO uint32_t ISER[8]; // 中断使能寄存器

   uint32_t RESERVED0[24];

   __IO uint32_t ICER[8]; // 中断清除寄存器

   uint32_t RSERVED1[24];

   __IO uint32_t ISPR[8]; // 中断使能悬起寄存器

   uint32_t RESERVED2[24];

   __IO uint32_t ICPR[8]; // 中断清除悬起寄存器

   uint32_t RESERVED3[24];

   __IO uint32_t IABR[8]; // 中断有效位寄存器

   uint32_t RESERVED4[56];

   __IO uint8_t IP[240]; // 中断优先级寄存器(8Bit wide)

   uint32_t RESERVED5[644];

   __O uint32_t STIR; // 软件触发中断寄存器

 } NVIC_Type;


 挂起:当置位中断挂起寄存器的时候,相应的中断将会被挂起,这是这个中断将不会立即执行,而是等待可执行的时候再执行;


比如高低级别的中断同时产生,就先挂起低级别的中断,等高级别的中断执行完毕,解除并执行低级中断


在配置中断的时候我们一般只用 ISER、ICER 和 IP 这三个寄存器,ISER用来使能中断,ICER用来失能中断,IP 用来设置中断


优先级。


优先级定义


在 NVIC 有一个专门的寄存器:中断优先级寄存器 NVIC_IPRx(在 F429 中,x=0...90)用来配置外部中断的优先级,IPR宽度为8bit,原则上每个外部中断可配置的优先级为0~255,数值越小,优先级越高。但是绝大多数 CM4芯片都会精简设计,以致实际上支持的优先级数减少,在 F429中,只使用了高 4bit,如下所示:



用于表达优先级的这 4bit,又被分组成抢占优先级和子优先级。如果有多个中断同时响应,抢占优先级高的就会 抢占 抢占优先级低的优先得到执行,如果抢占优先级相同,就比较子优先级。如果抢占优先级和子优先级都相同的话,就比较他们的硬件中断编号(position),编号越小,优先级越高。


优先级的分组由内核外设 SCB的应用程序中断及复位控制寄存器 AIRCR的PRIGROUP[10:8]位决定,F429分为了 5组,具体如下:主优先级=抢占优先级,x代表主优先级位数,y代表子优先级位数。



设置优先级分组可调用库函数 NVIC_PriorityGroupConfig() 实现,有关 NVIC 中断相关的库函数都在库文件 misc.c 和 misc.h中。


中断优先级分组库函数


/**

* 配置中断优先级分组:抢占优先级和子优先级

* 形参如下:

* @arg NVIC_PriorityGroup_0: 0bit for 抢占优先级

*                            4 bits for 子优先级

* @arg NVIC_PriorityGroup_1: 1 bit for 抢占优先级

*                            3 bits for 子优先级

* @arg NVIC_PriorityGroup_2: 2 bit for 抢占优先级

*                            2 bits for 子优先级

* @arg NVIC_PriorityGroup_3: 3 bit for 抢占优先级

*                            1 bits for 子优先级

* @arg NVIC_PriorityGroup_4: 4 bit for 抢占优先级

*                            0 bits for 子优先级

* @注意 如果优先级分组为 0,则抢占优先级就不存在,优先级就全部由子优先级控制

*/

void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup)

{

 // 设置优先级分组

 SCB->AIRCR = AIRCR_VECTKEY_MASK | NVIC_PriorityGroup;

 }

优先级分组真值表

中断编程


在配置每个中断的时候一般有 3个编程要点:


1、使能外设某个中断,这个具体由每个外设的相关中断使能位控制。比如串口有发送完成中断,接收完成中断,这两个中断都


由串口控制寄存器的相关中断使能位控制。


2、初始化 NVIC_InitTypeDef结构体,配置中断优先级分组,设置抢占优先级和子优先级,使能中断请求。


NVIC 初始化结构体


typedef struct

 {

  uint8_t NVIC_IRQChannel; // 中断源

  uint8_t NVIC_IRQChannelPreemptionPriority; // 抢占优先级

  uint8_t NVIC_IRQChannelSubPriority; // 子优先级

  FunctionalState NVIC_IRQChannelCmd; // 中断使能或者失能

 } NVIC_InitTypeDef;

1)NVIC_IROChannel:用来设置中断源,不同的中断中断源不一样,且不可写错,即使写错了程序不会报错,只会导致不想要中断。具体的成员配置可参考 stm32f4xx.h头文件里面的 IRQn_Type 结构体定义,这个结构体包含了所有的中断源。


2)NVIC_IRQChannelPreemptionPriority:抢占优先级,具体的值要根据优先级分组来确定,具体参考表格 优先级分组真值表


3)NVIC_IRQChannelSubPriority:子优先级,具体的值要根据优先级分组来确定,具体参考表格优先级分组真值表 。


4)NVIC_IRQChannelCmd:中断使能(ENABLE)或者失能(DISABLE)。操作的是 NVIC_ISER 和 NVIC_ICER 这两个寄存器。


3、编写中断服务函数


在启动文件 startup_stm32f429_439xx.s 中我们预先为每个中断都写了一个中断服务函数,只是这些中断函数都是为空,为的只是初始化中断向量表。实际的中断服务函数都需要我们重新编写,中断服务函数我们统一写在 stm32f4xx_it.c这个库文件中。关于中断服务函数的函数名必须跟启动文件里面预先设置的一样,如果写错,系统就在中断向量表中找不到中断服务函数的入口直接跳转到启动文件里面预先写好的空函数,并且在里面无限循环,实现不了中断。


关键字:STM32  中断  NVIC概述 引用地址:STM32中断及NVIC概述

上一篇:STM32_EXTI外部中断学习笔记
下一篇:STM32系统时钟配置及时钟树

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

STM32自带GB2312字库显示汉字
  本文介绍如何把字库文件写入单片机的flash中,然后无需再提取字模,即可实现单片机显示中文字符的功能。 下载字库到单片机flash中的指定位置   在上一篇博客中,最后留了一个想法,让单片机自带字库。现在就来实现这个想法。 我把用到的编译过的字符放在这里   我们借助J-Flash软件把bin文件放在单片机flash中的指定位置。   首先要新建工程,然后根据自己的板子选择型号   然后打开数据文件,找到刚刚下载的bin文件   根据自己单片机的flash大小输入地址,注意这个地址要与代码中的“基地址”一致   设置好以后按下快捷键F7   成功烧录以后,代码不可以在使用此区域。——一般情况下,你的
[单片机]
<font color='red'>STM32</font>自带GB2312字库显示汉字
stm32编译出问题解决
.FWlibincstm32f10x_conf.h(33): warning: #14-D: extra text after expected end of preprocessing directive 额外的文本在在预处理命令后面出现 #include stm32f10x_dma.h */ 出问题的地方就是这个 */ 仿照原子自己建立工程的时候出现的问题修改: 问题及修改: 1)..SYSTEMdelaydelay.c(27): error: #20: identifier SysTick_CLKSource_HCLK_Div8 is undefined 解决方法:在delay.c中添加
[单片机]
#51单片机# 用中断实现蜂鸣器
蜂鸣器常作为提示音,用于计算机、打印机、万用表等设备中。提示音一般很简单,能响就行。 某单片机的蜂鸣器原理图: 该单片机的CPU原理图: 下面这段程序用到了中断的算法,实现了蜂鸣器在4kHz和1kHz频率下的发声。 #include reg52.h sbit Buzz = P0^7;//蜂鸣器控制引脚 unsigned char T0RH = 0;//T0重载值的高字节 unsigned char T0RL = 0;//T0重载值的低字节 void StartBuzz(unsigned int frequ); void StopBuzz(); void main() { unsigned int
[单片机]
#51单片机# 用<font color='red'>中断</font>实现蜂鸣器
STM32模拟IIC读写24CXX
文件(iic.h): #define SDA_IN() {GPIOB- CRL&=0X0FFFFFFF;GPIOB- CRL|=0X80000000;} #define SDA_OUT() {GPIOB- CRL&=0X0FFFFFFF;GPIOB- CRL|=0X30000000;} #define IIC_SCL PBout(6) #define IIC_SDA PBout(7) #define READ_SDA PBin(7) void bsp_iic_init(void); void bsp_iic_start(void); void bsp_iic_st
[单片机]
STM8串口接收中断无法进入问题(STM8L051/101F3)
前言 最近弄了一块STM8L051/101F3开发板,打算简单玩一玩。在我IO和定时器都没问题后我开始配置串口UART时发现接收中断始终无法进入,发送中断都是没问题的,之后我就开始了为期两天的问题排查,几乎排查所有可能的问题点。 STM8L051/101F3开发板 代码 我这里的MCU是STM8L051F3,使用的STM8库开发,代码如下仅供参考: main.c #include stm8l15x.h void Clock_Config(void) { CLK_SYSCLKDivConfig(CLK_SYSCLKDiv_1); //系统时钟分频器 CLK_SYSCLKSourceSwitchCmd(
[单片机]
STM8串口接收<font color='red'>中断</font>无法进入问题(STM8L051/101F3)
利用STM32外部中断驱动四路数字触摸感应传感器模块
首先先介绍一下STM32的外部中断,当然这也不是我总结的,这是在那么多博客里找到的一篇个人认为总结不错的学习文档。先学到手再说吧! STM32中,每一个GPIO都可以触发一个外部中断,但是,GPIO的中断是以组位一个单位的,同组间的外部中断同一时间只能使用一个。比如说,PA0,PB0,PC0,PD0,PE0,PF0,PG0这些为1组,如果我们使用PA0作为外部中断源,那么别的就不能够再使用了,在此情况下,我们智能使用类似于PB1,PC2这种末端序号不同的外部中断源。每一组使用一个中断标志EXTIx。EXTI0 – EXTI4这5个外部中断有着自己的单独的中断响应函数,EXTI5-9共用一个中断响应函数,EXTI10-15共用一
[单片机]
利用<font color='red'>STM32</font>外部<font color='red'>中断</font>驱动四路数字触摸感应传感器模块
STM32低功耗设置
前两个月在公司做了一个低功耗项目,现在功耗最低10uA不到,平均功耗40uA左右,算是达标了。因为是公司产品,就不方便贴代码、原理图了,该产品是一个小模块,可以方便的嵌入到各种系统里面。跟原子哥他们卖的NRF2401类似,是一个读卡器。 做这个项目中间也请了技术支持,因为外围电路芯片的功耗一直降不下来,经过与对方的反复交流,对方提供了低功耗的测试结果、硬件方案、软件方案,经过修改测试,最终成为我们的产品,功耗比较满意。 硬件方案选择的是STM32,外加某公司的读卡芯片。前期完成了读卡等功能的开发,最后一项开发内容是最艰巨也是最困难的---低功耗。在开发过程中,从硬件设计上不断裁剪元器件,软件上不断精简代码,功耗最低
[单片机]
基于USB总线和89C51单片机的数据采集系统设计
在工业生产和科学技术研究过程的各行业中,常常要对各种数据进行采集,现在常用的采集方式是在PC机或工控机内安装数据采集卡,如A/D卡及RS-422卡、RS-485卡。采集卡不仅安装麻烦,易受机箱内环境的影响,而且由于受计算机插槽数量和地址、中断资源的限制,不可能挂接很多设备。而通用串行总线(Universal Serial Bus,简称USB)的出现能很好地解决以上这些冲突。我们利用89C51单片机设计了基于USB总线的数据采集设备,并可与MAX485结合起来实现数据的远程采集。 系统硬件设计 USB数据采集系统硬件模块主要由串行A/D转换器、89C51芯片、USB接口芯片和多路模拟开关等组成。硬件总体结构框图如图1所示。
[应用]
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

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

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

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