精华内容
下载资源
问答
  • NVIC中断优先级

    2021-08-13 23:59:44
    一、STM32 NVIC 中断优先级管理 1,中断: CM3 内核支持 256 个中断,其中包含了 16 个内核中断和 240 个外部中断,并且具有 256 级的可编程中断设置。 STM32 并没有使用 CM3 内核的全部东西,而是只用了它的一...

    一、STM32 NVIC 中断优先级管理

    1,中断:

    • CM3 内核支持 256 个中断,其中包含了 16 个内核中断和 240 个外部中断,并且具有 256 级的可编程中断设置。
    • STM32 并没有使用 CM3 内核的全部东西,而是只用了它的一部分。
    • STM32 有 84 个中断,包括 16 个内核中断和 68 个可屏蔽中断,具有 16 级可编程的中断优先级。
    • 在 STM32F103 系列 上面,又只有 60 个(在 107 系列才有 68 个)可屏蔽中断。如下:

      file

    2,中断管理方法:

    首先,对 STM32中断进行分组,组0~4。同时,对每个中断设置一个抢占优先级和一个响应优先级值。
    分组配置是在寄存器SCB->AIRCR以配置:(根据AIRCR的位来操作分组情况)

    file


    抢占优先级&响应优先级区别 :

    • 高优先级的抢占优先级是可以打断正在进行的低抢占优先级中断的。(值越小优先级越高)
    • 抢占优先级相同的中断,高响应优先级不可以打断低响应优先级的中断。
    • 抢古优先级相同的中断,当两个中断同时发生的情况下,哪个响应优先级高,哪个先执行。
    • 如果两个中断的抢占优先级和响应优先级都是一样的话,则看哪个中断先发生就先执行。

    举例:假定设置中断优先级组为2设置如下:

    • 中断3(RTC中断)的抢占优先级为2,响应优先级为1。
    • 中断6(外部中断0)的抢占优先级为3,响应优先级为0。
    • 中断7(外部中断1)的抢占优先级为2,响应优先级为0。
      那么这3个中断的优先级顺序为:中断7>中断3>中断6。

    特别说明:
    一般情况下,系统代码执行过程中,只设置一次中断优先级分组,比如分组2,设置好分组之后一般不会再改变分组。随意改变分组会导致中断管理混乱,程序出现意想不到的执行结果。

    3,中断优先级分组函数:

    void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup);
    这个函数的作用是对中断的优先级进行分组,这个函数在系统中只能被调用一次,一旦分 组确定就最好不要更改。这个函数我们可以找到其实现:(misc.c中)

    void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup) 
    { 
    assert_param(IS_NVIC_PRIORITY_GROUP(NVIC_PriorityGroup)); 
    SCB->AIRCR = AIRCR_VECTKEY_MASK | NVIC_PriorityGroup; 
    }COPY

    例如:设置某函数为分组2

    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);COPY

    二、中断优先级设置

    如何设置单个中断?

    MDK中NVIC中断相关寄存器结构体:

    typedef struct
    {
        //中断使能寄存器组
    _lO uint32_t ISER[8];
    uint32_t RESERVEDO[24];
    
    //中断失能寄存器组
    _IO uint32_t ICER[8];
    uint32_t RSERVED1[24];
    
    //中断挂起寄存器组
    _lO uint32_t ISPR[8];
    uint32_t RESERVED2[24];
    
    //中断解挂寄存器组
    _lOuint32_t ICPR[8];
    uint32tRESERVED3[24];
    
    //中断激活标志位寄存器组
    _lO uint32_t IABR[8];
    uint32_t RESERVED4[56];
    
    //中断优先级控制的寄存器组
    _IO uint8_t IP[240];
    uint32_t RESERVED5[644];
    
    _Ouint32_t STIR;
    }NVIC_Type;
    COPY

    对于每个中断怎么设置优先级?

    中断优先级控制的寄存器组:IP[240]

    全称是: Interrupt Priority Registers
    240个8位寄存器,每个中断使用一个寄存器来确定优先级。
    STM32>10x系列一共60个可屏蔽中断,使用IP[59]-IP[0]。
    每个IP寄存器的高4位用来设置抢占和响应优先级(根据分组),低4位没有用到。

    设置函数:void NVIC_Init(NVIC_InitTypeDefNVIC_InitStruct);
    其结构体:

    typedef struct 
    { 
    uint8_t NVIC_IRQChannel; //定义初始化的是哪个中断(可以在 stm32f10x.h 中找到 每个中断对应的名字)
    uint8_t NVIC_IRQChannelPreemptionPriority; //定义这个中断的抢占优先级别。 
    uint8_t NVIC_IRQChannelSubPriority; //定义这个中断的子(响应)优先级别。 
    FunctionalState NVIC_IRQChannelCmd;//该中断是否使能。
    } NVIC_InitTypeDef;
    COPY

    比如我们要使能串口 1 的中断,同时设置抢占优先级为 1,子优先级位 2,初始化的方法是:

    NVIC_InitTypeDef NVIC_InitStructure; 
    NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;//串口 1 中断 
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1 ;// 抢占优先级为 1 
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;// 子(响应)优先级位 2 
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ 通道使能 
    NVIC_Init(&NVIC_InitStructure); 
    //根据上面指定的参数初始化 NVIC 寄存器
    COPY

    三、NVIC总结:

    中断优先级设置步骤
    1,系统运行后先设置中断优先级分组。调用函数:void NVIC_PriorityGroupConfig(uint32_tNVIC_PriorityGroup);
    整个系统执行过程中,只设置一次中断分组

    2,针对每个中断,设置对应的抢占优先级和响应优先级:
    void NVIC_Init(NVIC_InitTypeDefNVIC_InitStruct);

    3,如果需要挂起/解挂,查看中断当前激活状态,分别调用相关函数即可。

    本文转载自:NVIC中断优先级 – 布尔博客

    展开全文
  • 文章目录 抢占优先级和响应优先级 抢占 响应 NVIC 的优先级组 中断寄存器 ISER[8] ICER[8] ISPR[8] ICPR[8] IABR[8] IP[240] 中断优先级设置步骤总结 Ref. 抢占优先级和响应优先级 STM32 的中断向量具有两个属性,一...

    抢占优先级和响应优先级

    STM32 的中断向量具有两个属性,一个为抢占属性,另一个为响应属性,其属性编号越小,表明它的优先级别越高。

    抢占

    抢占,是指打断其他中断的属性,即因为具有这个属性会出现嵌套中断(在执行中断服务函数A 的过程中被中断B 打断,执行完中断服务函数B 再继续执行中断服务函数A),抢占属性由NVIC_IRQChannelPreemptionPriority 的参数配置。

    响应

    响应属性则应用在抢占属性相同的情况下,当两个中断向量的抢占优先级相同时,如果两个中断同时到达, 则先处理响应优先级高的中断, 响应属性由NVIC_IRQChannelSubPriority 参数配置。

    例如,现在有三个中断向量,如下表
    在这里插入图片描述

    若内核正在执行C 的中断服务函数,则它能被抢占优先级更高的中断A 打断,由于B 和C 的抢占优先级相同,所以C 不能被B 打断。但如果B 和C 中断是同时到达的,内核就会首先响应响应优先级别更高的B 中断(高优先级的抢占优先级是可以打断正在进行的低抢占优先级中断的,而抢占优先级相同的中断,高优先级的响应优先级不可以打断低响应优先级的中断)。

    NVIC 的优先级组

    在配置优先级的时候,还要注意一个很重要的问题,即中断种类的数量。

    NVIC 只可以配置16 种中断向量的优先级,也就是说,抢占优先级和响应优先级的数量由一个4 位的数字来决定,把这个4 位数字的位数分配成抢占优先级部分和响应优先级部分。

    有5 组分配方式:

    1. 第 0 组: 所有4 位用来配置响应优先级。即16 种中断向量具有都不相同的响应优先级。
    2. 第 1 组:最高1 位用来配置抢占优先级,低3 位用来配置响应优先级。表示有2 种级别的抢占优先级(0 级,1 级),有8 种响应优先级,即在16 种中断向量之中,有 8 种中断,其抢占优先级都为0 级,而它们的响应优先级分别为0~7,其余8 种中断向量的抢占优先级则都为1 级,响应优先级别分别为0~7。
    3. 第 2 组:2 位用来配置抢占优先级,2 位用来配置响应优先级。即4 种抢占优先级,4 种响应优先级。
    4. 第 3 组:高3 位用来配置抢占优先级,最低1 位用来配置响应优先级。即有8 种抢占优先级,2 种响应2 优先级。
    5. 第 4 组:所有4 位用来配置抢占优先级,即NVIC 配置的16 种中断向量都是只有抢占属性,没有响应属性。

    要配置这些优先级组,可以采用库函数NVIC_PriorityGroupConfig(),可输入的参数为NVIC_PriorityGroup_0 ~ NVIC_PriorityGroup_4,分别为以上介绍的5 种分配组。

    于是,有读者觉得疑惑了,如此强大的STM32,所有GPIO都能够配置成外部中断,USART、ADC 等外设也有中断,而NVIC 只能配置16 种中断向量,那么在某个工程中使用超过16 个中断怎么办呢?注意NVIC 能配置的是16 种中断向量,而不是16 个,当工程中有超过16 个中断向量时,必然有两个以上的中断向量是使用相同的中断种类,而具有相同中断种类的中断向量不能互相嵌套。

    中断寄存器

    ISER[8]

    全称 Interrupt Set-Enable Registers,是一个中断使能寄存器组。

    CM3 内核支持 256 个中断,这里用 8 个 32 位寄存器来控制,每个位控制一个中断。

    但是 STM32F103 的可屏蔽中断只有 60 个,所以对我们来说,有用的就是两个(ISER[0]和 ISER[1]), 总共可以表示 64 个中断。

    而 STM32F103 只用了其中的前 60 位。ISER[0]的 bit0~bit31 分别对应中断 0~31。ISER[1]的 bit0~27 对应中断 32~59;这样总共 60 个中断就分别对应上了。

    你要使能某个中断,必须设置相应的 ISER 位为 1,使该中断被使能(这里仅仅是使能,还要配合中 断分组、屏蔽、IO 口映射等设置才算是一个完整的中断设置)。具体每一位对应哪个中断,请参考 stm32f10x.h 里面的第 140 行处(针对编译器 MDK5 来说)。

    ICER[8]

    全称 Interrupt Clear-Enable Registers,是一个中断除能寄存器组。

    该寄存器组与 ISER 的作用恰好相反,是用来清除某个中断的使能的。其对应位的功能,也和 ICRT 一样。

    这里要专门设置一个 ICER 来清除中断位,而不是向 ISER 写 0 来清除,是因为 NVIC 的这些寄 存器都是写 1 有效的,写 0 是无效的。具体为什么这么设计,请看《CM3 权威指南》第 125 页, NVIC 概览一章。

    ISPR[8]

    全称 Interrupt Set-Pending Registers,是一个中断挂起控制寄存器组。

    每个位对应的中断和 ISER 是一样的。

    通过置 1,可以将正在进行的中断挂起,而执行同级或更高级别 的中断。写 0 是无效的。

    ICPR[8]

    全称 Interrupt Clear-Pending Registers,是一个中断解挂控制寄存器组。

    其作用与 ISPR 相反,对应位也和 ISER 是一样的。

    通过设置 1,可以将挂起的中断接挂。写 0 无效。

    IABR[8]

    全称 Interrupt Active Bit Registers,是一个中断激活标志位寄存器组。

    对应位所代表的中断和 ISER 一样,如果为 1,则表示该位所对应的中断正在被执行。

    这是一个只读寄存器,通过它可以知道当前在执行的中断是哪一个。在中断执行完了由硬件自动清零。

    IP[240]

    全称 Interrupt Priority Registers,是一个中断优先级控制的寄存器组。

    这个寄存器组相当重要!STM32 的中断分组与这个寄存器组密切相关。

    IP 寄存器组由 240 个 8bit 的寄存器组成,每个可屏蔽中断占用 8bit,这样总共可以表示 240 个可屏蔽中断。

    而 STM32 只用到了其中的前 60 个。IP[59]~IP[0]分别对应中断 59~0。而每个可屏蔽中断占用的 8bit 并没有全部使用,而是只用了高 4 位。这 4 位,又分为抢占优先级和子优先级。抢占优先级在前,子优先级在后。而这两个优先级各占几个位又要根据 SCB->AIRCR 中的中断分组设置来决定。


    STM32 将中断分为 5 个组,组 0~4。该分组的设置是由 SCB->AIRCR 寄存器的 bit10~8 来定义的。具体分配关系如下表:

    AIRCR[10:8]bit[7:4]分配情况分配结果
    01110: 40 位抢占优先级,4 位响应优先级
    11101: 31 位抢占优先级,3 位响应优先级
    21012: 22 位抢占优先级,2 位响应优先级
    31003: 13 位抢占优先级,1 位响应优先级
    40114: 04 位抢占优先级,0 位响应优先级

    例如,组设置为 3,那么此时所有的 60 个中断,每个中断的中断优先寄存器的高四位中的最高 3 位是抢占优先级,低 1 位是响应优先级。这样每个中断,你就可以设置抢占优先级位 0~7(因为抢占优先级有 3 位,最高可表示为 000=0~111=7),响应优先级(只有 1 位因此)为 1 或 0。抢占优先级的级别高于响应优先级。而数值越小所代表的优先级就越高。

    这里需要注意两点:
    第一,如果两个中断的抢占优先级和响应优先级都是一样的话,则看哪个中断先发生就先执行;
    第二,高优先级的抢占优先级是可以打断正在进行的低抢占优先级中断的,而抢占优先级相同的中断,高优先级的响应优先级不可以打断低响应优先级的中断。

    结合实例说明一下:
    假定设置中断优先级组为 2,然后设置中断 3(RTC 中断)的抢占优先级为 2,响应优先级为 1。中断 6(外部中断 0)的抢占优先级为 3,响应优先级为 0。中断 7(外部中断 1)的抢占优先级为 2,响应优先级为 0。

    那么这 3 个中断的优先级顺序为:中断 7>中断 3>中断 6。

    上面例子中的中断 3 和中断 7 都可以打断中断 6 的中断。而中断 7 和中断 3 却不可以相互打断!


    接下来我们介绍如何使用库函数实现以上中断分组设置以及中断优先级管理,使得我们以后的中断设置简单化。NVIC 中断管理函数主要在 misc.c 文件里面。

    中断优先级分组函数

    void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup);	//中断优先级分组函数
    

    这个函数唯一目的就是通过设置 SCB->AIRCR 寄存器来设置中断优先级分组

    比如我们设置整个系统的中断优先级分组值为 2,那么方法是:

    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
    

    中断初始化函数

    void NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct);	//中断初始化函数
    

    其中 NVIC_InitTypeDef 是一个结构体,中间有三个成员变量,这三个成员变量的作用是:

    1. NVIC_IRQChannel:定义初始化的是哪个中断,这个我们可以在 stm32f10x.h 中找到每个中断对应的名字。例如 USART1_IRQn。
    2. NVIC_IRQChannelPreemptionPriority:定义这个中断的抢占优先级别。
    3. NVIC_IRQChannelSubPriority:定义这个中断的子优先级别。
    4. NVIC_IRQChannelCmd:该中断是否使能。

    比如我们要使能串口 1 的中断,同时设置抢占优先级为 1,子优先级位 2,初始化的方法是:

    NVIC_InitTypeDef NVIC_InitStructure; 
    NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;			// 串口 1 中断 
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1 ;	// 抢占优先级为 1 
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;			// 子优先级位 2 
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; 			// IRQ 通道使能 
    NVIC_Init(&NVIC_InitStructure); 							// 根据上面指定的参数初始化 NVIC 寄存器
    

    中断优先级设置步骤总结

    1. 系统运行开始的时候设置中断分组。确定组号,也就是确定抢占优先级和子优先级的 分配位数。调用函数为
    NVIC_PriorityGroupConfig();
    
    1. 设置所用到的中断的中断优先级别。对每个中断调用函数为
    NVIC_Init();
    

    Ref.

    1. STM32的抢占优先级和响应优先级
    展开全文
  • STM32----NVIC中断优先级 之前在学习和应用STM32时总是有疑惑,总是感觉优先级分组有点混乱,而且在排序中断优先级时没有一定的头绪,在疫情期间对这一方面的知识进行了深入的了解,下面将我学到的一些知识分享给...

    STM32----NVIC中断优先级
    之前在学习和应用STM32时总是有疑惑,总是感觉优先级分组有点混乱,而且在排序中断优先级时没有一定的头绪,在疫情期间对这一方面的知识进行了深入的了解,下面将我学到的一些知识分享给大家。

    中断

    :中断是指计算机运行过程中,出现某些意外情况需主机干预时,机器能自动停止正在运行的程序并转入处理新情况的程序,处理完毕后又返回原被暂停的程序继续运行。

    中断又分为硬件中断软件中断

    硬件中断分为以下四个方面:

    1 可屏蔽中断(maskable interrupt)。硬件中断的一类,可通过在中断屏蔽寄存器中设定位掩码来关闭。

    2 非可屏蔽中断(non-maskable interrupt,NMI)。硬件中断的一类,无法通过在中断屏蔽寄存器中设定位掩码来关闭。典型例子是时钟中断(一个硬件时钟以恒定频率—如50Hz—发出的中断)。

    3 处理器间中断(interprocessor interrupt)。一种特殊的硬件中断。由处理器发出,被其它处理器接收。仅见于多处理器系统,以便于处理器间通信或同步。

    4 伪中断(spurious interrupt)。一类不希望被产生的硬件中断。发生的原因有很多种,如中断线路上电气信号异常,或是中断请求设备本身有问题。
    软件中断指是一条CPU指令,用以自陷一个中断。由于软中断指令通常要运行一个切换CPU至内核态(Kernel Mode/Ring 0)的子例程,它常被用作实现系统调用(System call)。

    中断的功能:在现代计算机中采用中断的主要目的是:

    ①提高计算机系统效率。

    ②维持系统可靠正常工作。

    ③满足实时处理要求。

    ④提供故障现场处理手段。

    中断过程

    按照事件发生的顺序,中断过程包括 :

    ①中断源发出中断请求;

    ②判断当前处理机是否允许中断和该中断源是否被屏蔽;

    ③优先权排队;

    ④处理机执行完当前指令或当前指令无法执行完,则立即停止当前程序,保护断点地址和处理机当前状态,转入相应的中断服务程序;

    ⑤执行中断服务程序;

    ⑥恢复被保护的状态,执行“中断返回”指令回到被中断的程序或转入其他程序。

    上述过程中前四项操作是由硬件完成的,后两项是由软件完成的。

    以上就是中断的含义和中断的分类以及作用和中断过程。

    下面我们就来看看STM32中的NVIC中断优先级

    NVIC(内嵌向量中断控制器)

    STM32系列总共有84个中断,其中我用的STM32F103系列的板子有60个中断,可想而知STM32一定有一个中断的管理机制来管理这么多中断,使能中断并且配置相关中断的优先级,这就是NVIC的工作。

    NVIC中对于每个中断需要设置 抢占优先级响应优先级(又称子优先级),很明显,多个中断会先比较 抢占优先级,抢占优先级相同的比较响应优先级,这里值得注意的是 高抢占优先级能够打断低抢占优先级的,但是相同抢占优先级响应优先级不能打断响应优先级。
    在这里说明一下,数值越小代表优先级越高。

    NVIC的核心功能是中断优先级分组、中断优先级的配置、读中断请求标志、清除中断请求标志、使能中断、清除中断等,它控制着STM32中断向量表中中断号为0-59的60个中断!!外部中断信号从核外发出,信号最终要传递到NVIC(嵌套向量中断控制器)。NVIC跟内核紧密耦合,它控制着整个芯片中断的相关功能。

    抢占优先级和相应优先级的区别可以通过以下四句话来概括:

    1)高优先级的抢占优先级是可以打断正在进行的低抢占优先级中断的。
    2)抢占优先级相同的中断,高响应优先级不可以打断低响应优先级的中断。
    3)抢占优先级相同的中断,当两个中断同时发生的情况下,哪个响应优先级高,哪个先执行。
    4)如果两个中断的抢占优先级和响应优先级都是一样的话,则看哪个中断先发生就先执行。

    给大家举个例子就明白了。

    举例:
    在这里插入图片描述

    假定设置中断优先级组为2,然后设置
    中断3(RTC中断)的抢占优先级为2响应优先级为1中断6(外部中断0)的抢占优先级为3响应优先级为0中断7(外部中断1)的抢占优先级为2响应优先级为0

    那么这3个中断的优先级顺序为:中断7>中断3>中断6

    此外需要注意的是:

    1)打断的情况只会与抢占优先级有关, 和响应优先级无关!
    2) 一般情况下,系统代码执行过程中,只设置一次中断优先级分组,比如分组2设置好分组之后一般不会再改变分组。随意改变分组会导致中断管理混乱,程序出现意想不到的执行结果。

    中断优先级分组库函数

    CM3核的优先级分组方式,使用的设置函数NVIC_SetPriorityGrouping()。

    接下来介绍STM32的中断优先级分组函数NVIC_PriorityGroupConfig(),用来进行中断分组设置的,此函数是在固件库下misc.c文件中(文件目录是:

    STM32F10x_StdPeriph_Lib_V3.5.0\Libraries\STM32F10x_StdPeriph_Driver\src\misc.c):

    void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup)
    {
      /* Check the parameters */
      assert_param(IS_NVIC_PRIORITY_GROUP(NVIC_PriorityGroup));
      
      /* Set the PRIGROUP[10:8] bits according to NVIC_PriorityGroup value */
      SCB->AIRCR = AIRCR_VECTKEY_MASK | NVIC_PriorityGroup;
    }
    

    函数的参数的取值,是在同文件中进行宏定义的:

    #define NVIC_PriorityGroup_0         ((uint32_t)0x700) /*!< 0 bits for pre-emption priority
                                                                4 bits for subpriority */
    #define NVIC_PriorityGroup_1         ((uint32_t)0x600) /*!< 1 bits for pre-emption priority
                                                                3 bits for subpriority */
    #define NVIC_PriorityGroup_2         ((uint32_t)0x500) /*!< 2 bits for pre-emption priority
                                                                2 bits for subpriority */
    #define NVIC_PriorityGroup_3         ((uint32_t)0x400) /*!< 3 bits for pre-emption priority
                                                                1 bits for subpriority */
    #define NVIC_PriorityGroup_4         ((uint32_t)0x300) /*!< 4 bits for pre-emption priority
                                                                0 bits for subpriority */
    
    #define IS_NVIC_PRIORITY_GROUP(GROUP) (((GROUP) == NVIC_PriorityGroup_0) || \
                                           ((GROUP) == NVIC_PriorityGroup_1) || \
                                           ((GROUP) == NVIC_PriorityGroup_2) || \
                                           ((GROUP) == NVIC_PriorityGroup_3) || \
                                           ((GROUP) == NVIC_PriorityGroup_4))
    

    中断优先级设置库函数
    接下来介绍如何使用库函数实现中断优先级管理,这里使用NVIC_Init()函数来进行对每个中断优先级的设置(misc.c文件中):

    void NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct)
    {
      uint32_t tmppriority = 0x00, tmppre = 0x00, tmpsub = 0x0F;
      
      /* Check the parameters */
      assert_param(IS_FUNCTIONAL_STATE(NVIC_InitStruct->NVIC_IRQChannelCmd));
      assert_param(IS_NVIC_PREEMPTION_PRIORITY(NVIC_InitStruct->NVIC_IRQChannelPreemptionPriority));  
      assert_param(IS_NVIC_SUB_PRIORITY(NVIC_InitStruct->NVIC_IRQChannelSubPriority));
        
      if (NVIC_InitStruct->NVIC_IRQChannelCmd != DISABLE)
      {
        /* Compute the Corresponding IRQ Priority --------------------------------*/    
        tmppriority = (0x700 - ((SCB->AIRCR) & (uint32_t)0x700))>> 0x08;
        tmppre = (0x4 - tmppriority);
        tmpsub = tmpsub >> tmppriority;
    
        tmppriority = (uint32_t)NVIC_InitStruct->NVIC_IRQChannelPreemptionPriority << tmppre;
        tmppriority |=  NVIC_InitStruct->NVIC_IRQChannelSubPriority & tmpsub;
        tmppriority = tmppriority << 0x04;
            
        NVIC->IP[NVIC_InitStruct->NVIC_IRQChannel] = tmppriority;
        
        /* Enable the Selected IRQ Channels --------------------------------------*/
        NVIC->ISER[NVIC_InitStruct->NVIC_IRQChannel >> 0x05] =
          (uint32_t)0x01 << (NVIC_InitStruct->NVIC_IRQChannel & (uint8_t)0x1F);
      }
      else
      {
        /* Disable the Selected IRQ Channels -------------------------------------*/
        NVIC->ICER[NVIC_InitStruct->NVIC_IRQChannel >> 0x05] =
          (uint32_t)0x01 << (NVIC_InitStruct->NVIC_IRQChannel & (uint8_t)0x1F);
      }
    }
    

    其中,NVIC_InitTypeDef为一个结构体,它的成员变量为

    typedef struct
    {
      uint8_t NVIC_IRQChannel;                    /*!< Specifies the IRQ channel to be enabled or disabled.
                                                       This parameter can be a value of @ref IRQn_Type 
                                                       (For the complete STM32 Devices IRQ Channels list, please
                                                        refer to stm32f10x.h file) */
    
      uint8_t NVIC_IRQChannelPreemptionPriority;  /*!< Specifies the pre-emption priority for the IRQ channel
                                                       specified in NVIC_IRQChannel. This parameter can be a value
                                                       between 0 and 15 as described in the table @ref NVIC_Priority_Table */
    
      uint8_t NVIC_IRQChannelSubPriority;         /*!< Specifies the subpriority level for the IRQ channel specified
                                                       in NVIC_IRQChannel. This parameter can be a value
                                                       between 0 and 15 as described in the table @ref NVIC_Priority_Table */
    
      FunctionalState NVIC_IRQChannelCmd;         /*!< Specifies whether the IRQ channel defined in NVIC_IRQChannel
                                                       will be enabled or disabled. 
                                                       This parameter can be set either to ENABLE or DISABLE */   
    } NVIC_InitTypeDef;
    

    NVIC_InitTypeDef结构体有4个成员变量:

    1 NVIC_IRQChannel:定义初始化的是哪一个中断,这个可以在stm32f10x.h文件中查到每个中断对应的名字,如USART1_IRQn;
    2 NVIC_IRQChannelPreemptionPriority:定义此中断的抢占优先级别;
    3 NVIC_IRQChannelSubPriority:定义此中断的响应优先级别;
    4 NVIC_IRQChannelCmd:该中断是否使能。

    其实我们看NVIC_Init()函数内部使能中断,也是通过ISER寄存器配置的。这与我么之前的内容并不矛盾。函数内部使用NVIC->ISER,而NVIC是一个宏定义:

    #define NVIC     ((NVIC_Type *) NVIC_BASE)     /*!< NVIC configuration struct   
    

    也就是直接操作结构体来实现操作ISER寄存器。具体原理见STM32 MDK中寄存器地址名称映射

    比如,使能串口1中断,抢占优先级为1,响应优先级为2,初始化的方法为:

    NVIC_InitTypeDef   NVIC_InitStructure;
    NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;//串口1中断
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1 ;// 抢占优先级为1
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;// 子优先级位2
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//IRQ通道使能
    NVIC_Init(&NVIC_InitStructure);	//根据上面指定的参数初始化NVIC寄存器
     
    

    总结与分析

    最后总结一下中断优先级设置的步骤:

    1、系统运行后先设置中断优先级分组。调用函数:

    void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup);
    

    整个系统执行过程中,只设置一次中断分组;

    2、针对每个中断,设置对应的抢占优先级和响应优先级:

    void NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct);
    

    3、如果需要挂起/解挂,查看中断当前激活状态,分别调用相关函数即可。

    展开全文
  • NVIC中断优先级管理 STM32中断优先级简介 如何管理中断? 什么是“抢占优先级”和“响应优先级”呢? 优先级是如何定义的? 特别说明 函数介绍 中断优先级分组选择函数 对于每个中断怎么设置优先级? 如何...

    目录

    NVIC中断优先级管理

    STM32中断优先级简介

    如何管理中断?

    什么是“抢占优先级”和“响应优先级”呢?

    优先级是如何定义的?

    特别说明

    函数介绍

    中断优先级分组选择函数

    对于每个中断怎么设置优先级?

    如何理解中断挂起与解挂的含义?

    获取中断状态的函数

    清除/设置中断标志位的函数

    针对于中断标志位的操作有什么用?

    举例说明


    NVIC中断优先级管理

    STM32中断优先级简介

     

    NVIC的缩写是“嵌套向量中断控制器(Nested Vectored Interrupt Controller)”。

    如何管理中断?

    STM32中断优先级管理采用“响应优先级和抢占优先级”结合的方法,并且进行了中断分组。

     

    以第1组为例:1bit抢占优先级说明抢占优先级共有两级,3bits响应优先级说明响应优先级共有8级。我们可以看到无论如何分组,中断优先级总有16种。

     

    什么是“抢占优先级”和“响应优先级”呢?

    抢占优先级和响应优先级都是区分那个中断优先进行的标志,但是两者的含义去不尽相同。

    抢占优先级从名字上就比响应优先级霸气一些,因此抢占优先级起决定作用,当抢占优先级相同时,响应优先级高的才会优先发生。

    优先级是如何定义的?

    值越小,优先级越大。

    例如:假定设置中断优先级组为2,然后设置中断3(RTC中断)的抢占优先级为2,响应优先级为1。  中断6(外部中断0)的抢占优先级为3,响应优先级为0。中断7(外部中断1)的抢占优先级为2,响应优先级为0。

    优先级顺序:中断7>中断3>中断6

    结论:抢占优先级高的必定先抢占中断,如果抢占优先级相同,那就看响应优先级,此时谁的响应优先级高,谁就先发生。

    除此之外,如果他们的抢占式优先级和响应优先级都相等,则根据他们在中断表中的排位顺序决定先处理哪一个,排序越考上,中断越优先。中断向量地址可以参考“STM32中文参考手册->中断->中断异常向量”部分的内容。部分示例:

     

    特别说明

    一般情况下,系统代码执行过程中,只设置一次中断优先级分组,比如分组2,设置好分组之后一般不会再改变分组。随意改变分组会导致中断管理混乱,程序出现意想不到的执行结果。

    函数介绍

    在操作函数的底层中,我们一般只用到ISER、ICER、IP这3个寄存器。ISER用于使能中断,ICER用来清除中断,IP用来设置中断优先级。

    中断优先级分组选择函数

    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);

    我们选择的是按照组2的方式进行分组,即抢占优先级总数为4级(0-3),响应优先级总级数为4级(0-3)。我们可以看到无论如何分组,中断优先级总有16种。

     

    对于每个中断怎么设置优先级?

    NVIC_InitTypeDef NVIC_InitStructure;  
    NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;  
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;  
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;  // 2<3
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;  //3<=3
    NVIC_Init(&NVIC_InitStructure);  

     

    如何理解中断挂起与解挂的含义?

    中断的挂起与解挂针对的是中断标志位,也可以叫做允许中断发生的位。

    获取中断状态的函数

    函数原型
    
    static __INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn);
    
    函数应用
    
    uint32_t IterruptFlag = NVIC_GetPendingIRQ(USART1_IRQn);
    
    // 这个函数获取了串口1中断的状态

    清除/设置中断标志位的函数

    函数原型
    
    static __INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn);
    
    static __INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn)
    
    函数使用
    
    NVIC_SetPendingIRQ(USART1_IRQn);
    
    NVIC_ClearPendingIRQ(USART1_IRQn);

    针对于中断标志位的操作有什么用?

    1、一般来说单片机的中断发生有两个条件,一是中断标志位置位,二是中断允许,如果这两个条件都满足则进入中断,因为正常情况下中断一直是允许的,那么只能通过标志位来区分是否有中断挂起;

    2、如果进入中断不清除标志位,那么这一中断服务程序结束后由于标志位还是置位的并且中断是允许的,那么还会再次进入该中断,就会发生一直在执行中断程序的情况。

    举例说明

    在A中断中设置B中断的中断标志位为1,那么当B中断条件满足时,B中断可以发生,但是如果清除A中B中断标志位,那么无论是否满足触发B中断的条件,A中断中永远不可能执行B中断,因为中断发生的条件是:“中断标志位有效+中断条件满足”。

    展开全文
  • NVIC中断优先级管理

    2021-05-25 18:27:25
    目录1 简介2 中断管理的方法3 响应优先级和抢占优先级原则4 中断优先级的设置步骤 1 简介 具体定义可以自行进行百度百科,这里只挑重点进行讲解。 STM32F40xx/STM32F41xx的92个中断里面,包括10个内核中断和82个可...
  • CM3 内核支持 256 个中断,其中包含了 16 个内核中断和 240 个外部中断,并且具有 256级的可编程中断设置。但 STM32 并没有使用 CM3 内核的全部东西,而是只用了它的一部分。
  • STM32可以对中断进行分组,可以分为5组。
  • 对于中断这个概念,我喜欢用经常发生在CPU中的多线程...1.NVIC中断优先级分 CM3内核支持256个中断,其中包含了16个内核中断和240个外部中断,并且具有256级的可编程中断设置。 STM32并没有使用CM3内核的全部东西,...
  • STM32 NVIC中断优先级

    2020-08-06 19:58:14
    STM32有84个中断,包括68个可屏蔽中断和16个内核中断。STMF103系列只有60个可屏蔽中断
  • STM32的 NVIC中断优先级分组 中断 CM3 内核支持 256 个中断,其中包含了 16 个内核中断和 240 个外部中断,并且具有 256 级的可编程中断设置。 STM32 并没有使用 CM3 内核的全部东西,而是只用了它的一部分。 STM32 ...
  • 【STM32】NVIC中断优先级的理解

    千次阅读 多人点赞 2019-11-26 22:25:50
    大千世界,无所不有,而前后顺序,等级顺序,则一直伴随左右。而STM32也不例外。 我们在学习STM32中串口啊,定时器啊...具有高优先级中断可以在低优先级正在运行时打断其运行,然后执行自己的程序,运行完后再...
  • STM32 NVIC 中断优先级

    2020-01-17 10:22:35
    NVIC 中断优先级 CM3 内核支持 256 个中断,其中包含了 16 个内核中断和 240 个外部中断,并且具有 256级的可编程中断设置。但 STM32 并没有使用 CM3 内核的全部东西,而是只用了它的一部分。STM32 有 84 个中断,...
  • 1 NVIC中断优先级分组 1.1NVIC的中断向量表 Cortex-M3和CM4内核都支持256个中断,其中包含了16个内核中断(异常)和240个外部中断,并且具有256级的可编程中断设置。但是,STM32F1并没有使用CM3内核的全部东西,...
  • Stm32学习(五)NVIC中断优先级

    千次阅读 2020-07-11 16:45:51
    1.NVIC中断优先级分组 CM3内核支持256个中断,其中包含了16个内核中断和240个外部中断,并且具有256级的可编程中断设置。 STM32并没有使用CM3内核的全部东西,而是只用了它的一部分 STM32有84个中断,包括16个内核...
  • NVIC 中断优先级管理详解

    万次阅读 多人点赞 2018-08-12 01:14:46
    1.NVIC(内嵌向量中断控制器) NVIC:Nested Vectored Interrupt Controller,STM32系列有84个中断,相对于的开发板STM32F103系统
  • STM32 NVIC中断优先级管理

    千次阅读 2018-04-03 15:23:03
    STM32 NVIC中断优先级管理 后面用一个具体的例子说明了中断分组、中断线、中断通道的连接关系,先看基本概念: CM3内核支持256个中断,包括16个内核中断和240个外部中断,并且具有256级的可编程中断设置。STM32只...
  • 1.NVIC中断优先级分组 NVIC的全称是Nested vectoredinterrupt controller,即嵌套向量中断控制器。STM32F中文参考手册中搜索向量表可以找到相应的中断说明。 CM4/CM7 内核支持256个中断,其中包含了16个内核中断和...
  • CM4 内核支持 256 个中断,其中包含了 16 个内核中断和 240 个外部中断,并且具有256 级的可编程中断设置。但 STM32F4 并没有使用 CM4 内核的全部东西,而是只用了它的一部分。 STM32F40xx/STM32F41xx 总共有 92 个...
  • NVIC中断优先级分组

    千次阅读 2018-05-23 22:14:08
    CM7内核支持256个中断,其中包含了16个内核中断和...STM32具有16级可编程的中断优先级,而我们常用的就是这些可屏蔽中断。 ???几十个中断,怎么管理?首先,对STM32中断进行分组,组0~4,同时,对每个中断设置...
  • NVIC 中断优先级管理

    2021-04-29 17:27:48
    NVIC 中断优先级分组 stm32 将中断分为 5 个组(0~4), 抢占优先级 & 响应优先级 (数字越小优先级越高) 只有抢占优先级才可以打断,响应只是决定发生顺序 高优先级的抢占优先级可以打断正在进行的低抢占...
  • STM32F103系列NVIC中断优先级分组讲解

    千次阅读 2019-05-17 16:29:33
    但是STM32只用到了CM3内核的一部分,STM32有84个中断,包括16个内核中断和68个可屏蔽中断,具有16级可编程中断优先级。 STM32F103系列只有60个可屏蔽中断。 二、中断管理 1.对STM32进行中断分组,组0-4,同时对...
  • 了解STM32的NVIC中断优先级管理及初始化简介NVIC总结NVIC中断优先级分组中断优先级设置 简介 1、CM3内核支持256个中断,其中包含了16个内核中断和240个外部中断,并且具有256级的可程中断设置。 2、STM32F103系列...
  • 之前学习嵌入式的时候不太明白中断优先级分组与抢占优先级和响应优先级的关系,比如分组为2,抢占优先级也为2,响应优先级也为2,就是不明白他们之间有什么关系,谁决定谁,总共有多少个数值可供选择。    ...
  • NVIC中断优先级管理: 首先是中断分组,我们知道所用的CM3内核支持256个中断,其中包含了16个内核中断和240个外部中断,并且具有256级的可编程中断设置。然而STM32并没有使用CM3内核的全部东西,而是只用了它的一...
  • STM32F103系列上面,又只有60个可屏蔽中断(在107系列才有68个) 中断管理方法 首先,对STM32中断进行分组,组0~4。同时,对每个中断设置...抢占优先级相同的中断,高响应优先级不可以打断低响应优先级中断。...
  • 数值越小,优先级越高 高优先级的抢占优先级是可以打断正在进行的低抢占优先级中断的。 抢占优先级相同的中断,高响应优先级不可以打断低响应优先级的中断。...中断优先级分组函数 在misc.c函数中 void NVIC_P...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 13,746
精华内容 5,498
关键字:

nvic中断优先级