STM32之NVIC的深入详解

STM32之NVIC的深入详解STM32NVIC中断嵌套

大家好,又见面了,我是你们的朋友全栈君。

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

  特性:

  60个可屏蔽中断通道(不包含16Cortex-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对这个表重新进行了编排,把编号从-36的中断向量定义为系统异常,编号为负的内核异常不能被设置优先级,如复位(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个级别,可以设置为01,而响应优先级则占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。这就是抢占优先级和响应优先级的区别。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/140230.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • Activiti工作流的详细介绍[通俗易懂]

    Activiti工作流的详细介绍[通俗易懂]一、了解工作流1、工作流(Workflow),就是“业务过程的部分或整体在计算机应用环境下的自动化”,它主要解决的是“使在多个参与者之间按照某种预定义的规则传递文档、信息或任务的过程自动进行,从而实现某个预期的业务目标,或者促使此目标的实现。2、工作流管理系统(WorkflowManagementSystem,WfMS)是一个软件系统,它完成工作量的定义和管理,并按照在系统中预先定义好的工作流逻辑进行工作流实例的执行。工作流管理系统不是企业的业务系统,而是为企业的业务系统的运行提供了一个软件的

  • 外贸进出口贸易海关报关管理_进口报关单贸易国怎么填

    外贸进出口贸易海关报关管理_进口报关单贸易国怎么填附加费分摊?发票张数?发票号码???分摊原则单?项?摊□确定选择子项分摊???单张同类摊□确定?执行。。。。。。??单项分摊附加费即直接选择子项将费用加入,修改数据。单项分摊附加费即直接选择子项将费用加入,修

  • NAND FLASH_NAND器件

    NAND FLASH_NAND器件概要:本文介绍了DM368NANDFlash启动的原理,并且以DM368IPNC参考设计软件为例,介绍软件是如何配合硬件实现启动的.芯片上电后是如何启动实现应用功能的?这是许多工程师在看到处理器运行的时候,通常都会问的一个问题.下面我们就以德州仪器的多媒体处理芯片TMS320DM368为例,介绍它的NANDFlash启动原理以及实现.1.NANDFlash启动原理德州…

  • Django(57)Generic类视图[通俗易懂]

    Django(57)Generic类视图[通俗易懂]前言上篇我们通过mixin可以非常方便的实现一些CURD操作。实际上针对这些mixin,DRF还进一步的进行了封装,放到generics下。有以下generic类视图:generics.ListA

  • 2023年北京理工大学理论力学考研上岸前辈备考经验指导

    2023年北京理工大学理论力学考研上岸前辈备考经验指导2021年我400分+考研成功上岸北京理工大学,回顾2020一年的辛苦蹒跚,觉得值得。一、考研择校及报考因素考量关于考研择校方面,我主要考虑到未来从事行业、地域、学校实力和名气这几个方面,排列顺序按照重要度先后。首先是最为关键的未来从事行业方面,考研之前其实就应该大体思考一下未来的发展方向,这相当于给自己以后好几年定一个基调。比如我本科是航空航天类,这个专业看似和其它工科脱节了,成了大国工酱,实际上万物可转航空航天方面,我去年拿到过北京航天科工某所的offer,基本上不管是工科什么专业都招的。航空航

  • 人生就是一场康波「建议收藏」

    人生就是一场康波「建议收藏」理论创建人–周金涛2016年3月16日,中信建投首席经济学家周金涛先生参加由上海清算所等举办的第30期清算所沙龙——“2016年债务融资工具专题”活动。在沙龙活动中,周期天王周金涛先生阐述了康波经济周期理论对宏观经济走势的研判,以下是演讲实录。60年的经济周期:人生有三次财富机会重要经济周期理论开创者是两个,第一个康波周期,实际上它是全球经济运动的决定力量,也是在座各…

    2022年10月22日

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号