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中断 引用地址:STM32学习笔记--NVIC中断

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

推荐阅读最新更新时间:2024-11-11 14:49

STM32学习笔记(三) STM32的GPIO的深入学习
STM32的开发学习主要涉及软硬件两个部分的实现,包含众多外设和总线的理解配置。STM32的整个学习曲线并不陡峭,但入门却相当困难,因此在学习之初,多动手实验和测试相当重要,GPIO作为整个STM32与外部连接的端口,难度不高,却十分重要。从深入解析GPIO外设开始,一步步熟悉掌握STM32各个模块,就是STM32的整个学习流程。 GPIO模块回顾 在嵌入式软件开发中,几乎所有功能的实现都需要GPIO端口输出才能发挥作用。GPIO端口的操作包括时钟使能,寄存器配置,端口信息修改。这些基础的东西上一章已经讲过,我这里就不在细说,我这里主要讲GPIO涉及到的其它库函数。 1. 读取GPIO端口数据函数 GPIO_ReadInp
[单片机]
<font color='red'>STM32</font><font color='red'>学习</font><font color='red'>笔记</font>(三) <font color='red'>STM32</font>的GPIO的深入<font color='red'>学习</font>
基于STM32设计的遥控小车(手机APP+GPS+温湿度+ESP8266)
一、环境介绍 小车主控MCU: STM32F103ZET6 STM32程序开发IDE: keil5 STM32程序风格: 采用寄存器方式开发,注释齐全,执行效率高,方便移植 手机APP: 采用QT设计,程序支持跨平台编译运行(Android、IOS、Windows、Linux都可以编译运行,对应平台上QT的环境搭建,之前博客已经发了文章讲解) 硬件包含: 淘宝购买的完整一套4轮遥控小车(采用STM32F103ZET6作为主控板)、DHT11温湿度传感器、中科微GPS模块、ESP8266 小车完整源码下载地址: https://download.csdn.net/download/xiaolong11266264
[单片机]
基于<font color='red'>STM32</font>设计的遥控小车(手机APP+GPS+温湿度+ESP8266)
STM32独立看门狗和窗口看门狗的使用
看门狗(watch dog)是一个定时器,可以设置一个定时时间,计时到时会把MCU复位,所以MCU必须要在定时时间到之前将计数值重置(这个动作通常称为喂狗)。 在嵌入式系统中加入看门狗,可以监测MCU是否还在正常运行,如果软件跑进死循环、或者出现其他错误,导致不能及时重置看门狗计时器,则时间一到MCU就会被复位,重新回到初始状态,以此跳出错误状态。 Stm32内部带有独立看门狗、窗口看门狗。独立看门狗使用时,只要喂狗时间不大于设定的时间就可以,是最常用的看门狗用法;而窗口看门狗,需要喂狗时间在一个上下限范围内,才能重置看门狗计时器。 下面我们就分别学习一下这两种看门狗的使用。 1)stm32的独立看门狗(IWDG) 我们在之前
[单片机]
<font color='red'>STM32</font>独立看门狗和窗口看门狗的使用
stm32 can通信发送解释
uint8_t CAN_Transmit(CAN_TypeDef* CANx, CanTxMsg* TxMessage) { uint8_t transmit_mailbox = 0; /* Check the parameters */ assert_param(IS_CAN_ALL_PERIPH(CANx)); assert_param(IS_CAN_IDTYPE(TxMessage- IDE)); assert_param(IS_CAN_RTR(TxMessage- RTR)); assert_param(IS_CAN_DLC(TxMessage- DLC)); /* Select one empty tr
[单片机]
STM32中较为常见的C语言基础知识
C语言是单片机开发中的必备基础知识,本文列举了部分 STM32 学习中比较常见的一些C语言基础知识。 1位操作 下面我们先讲解几种位操作符,然后讲解位操作使用技巧。C语言支持以下六种位操作: 下面,重点讲解一下位操作在单片机开发中的一些实用技巧。 在不改变其他位的值的状况下,对某几个位进行设值 这个场景在单片机开发中经常使用,方法就是我们先对需要设置的位用&操作符进行清零操作,然后用 | 操作符设值。 比如,我要改变 GPIOA 的状态,可以先对寄存器的值进行&清零操作: GPIOA- CRL&=0xFFFFFF0F;/*将第4~7位清零*/ 然后再与需要设置的值进行 |
[单片机]
<font color='red'>STM32</font>中较为常见的C语言基础知识
STM32标准库和HAL库的区别
大体看了下,标准库移植起来没有HAL库方便。 用HAL库移植起来不需要改动,怪不得ST推HAL库 好像标准库后面的芯片就不支持了 怪不得华清现在讲课,STM32的课还有freertos的课都是用的STM32CUBE https://blog.csdn.net/ice_masters/article/details/105644704 https://blog.csdn.net/bornpride/article/details/94601754 怪不得这里说没有可移植性,我最开始看到这句的时候很吃惊,标准库怎么没有可移植性了。
[单片机]
<font color='red'>STM32</font>标准库和HAL库的区别
STM32单片机-低功耗设置
STM32F103R8和RC的停机模式的休眠电流还不一样,R8停机模式实测为11uA,RC停机模式实测为30uA,还以为又是我的程序哪里没做好呢,仔细看了PDF,这两个芯片PDF上标的值的确有区别,和我测的值差不多,那我就没有再深究的意义了! 结合下文的高手经验,反复摸索, standby模式1.9uA,PWR_EnterSTOPMode(PWR_Regulator_LowPower, PWR_STOPEntry_WFI); stop模式:11uA, PWR_EnterSTANDBYMode(); 实验证明,将IO端口设成IPU/IPD/AIN/PPOUT=1/PPOUT=0/ODOUT=0,电流是基本
[单片机]
<font color='red'>STM32</font>单片机-低功耗设置
STM32让printf通过串口打印及自定义printf函数
在嵌入式系统中,通过串口打印log是非常重要的调试手段,但是直接调用底层驱动打印信息非常不方便,在c语言中一般使用printf打印基本的显示信息,而默认printf的结果不会通过串口发送,所以需要对printf的输出进行重定向。 有时候需要同时从多个串口输出信息,如果仍然想通过printf函数输出信息,就需要自己写printf的实现。 一. 初始化端口和配置 对串口用到的GPIO进行配置,并对串口的参数进行初始化。 二. 宏定义并实现具体的发送函数 代码在编译时首先判断__GNUC__有无定义,之后将PUTCHAR_PROTOTYPE替换成具体的定义。在keil5中,使用fputc函数,所以其实
[单片机]
<font color='red'>STM32</font>让printf通过串口打印及自定义printf函数
小广播
设计资源 培训 开发板 精华推荐

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

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

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

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