STM32 中断优先级以及全局允许和禁止

发布者:巳午未最新更新时间:2018-12-03 来源: eefocus关键字:STM32  中断优先级  全局允许  禁止 手机看文章 扫描二维码
随时随地手机看文章

请问例程上为什么要把串口中断优先级设置在NVIC中断分组2


NVIC: M3内核允许8bit做优先级分组设置,而STM32只有4bit可以设置。 

AIRCR寄存器的4个位的分组方式如下: 

第0组:所有4位用于指定响应优先级 

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

第2组:最高2位用于指定抢占式优先级,最低2位用于指定响应优先级 

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

第4组:所有4位用于指定抢占式优先级 

例:定义为第二组,抢占式优先级2bit,响应式优先级2bit,2bit共可有4种状态,也就是总共能设置4*4=16个中断优先级。 

定义为第三组,抢占式优先级3bit,响应式优先级1bit,也就是总共能设置8*2=16个中断优先级。


我觉得可能是易于程序员查看代码吧,比如把串口1、2、3分在同一组,把SPI1、2、3分在同一组,看起来比较直观。 

实际上分不分组都能实现同一种结果。


====================================


优先级可以被分为高低两个位段,分别是抢占优先级和亚优先级


Cortex-M3允许具有较少中断源时使用较少的寄存器位指定中断源的优先级,因此STM32把指定中断优先级的寄存器位减少到4位 AIRC 中 PRIGROUP 的值规定了设置和确定每个外部中断通道优先级的格式。例如,在上面将 0x05 写入了 AIRC 中 PRIGROUP,也就规定了当前系统中只能有 4 个抢先式优先级,相同的抢先式优先级下还可以有 4 个不同级别的子优先级,他们分别为: 

位[7:6]                   位[5:4]                  位[3:0] 
00         0 号抢先优先级   00        0 号子优先级    无效 
01         1 号抢先优先级   01        1 号子优先级    无效 
10         2 号抢先优先级   10        2 号子优先级    无效 
11         3 号抢先优先级   11        3 号子优先级    无效 


在Cortex—M3的优先级分配中,较低的优先级值具有较高的优先级。


数值小的优先级高, 数值大的优先级低


a 只能高抢先优先级的中断可以打断低抢先优先级的中断服务,构成中断嵌套。


b 当 2(n)个相同抢先优先级的中断出现,它们之间不能构成中断嵌套,但 STM32 首先响应子优先级高的中断。


c 当 2(n)个相同抢先优先级和相同子优先级的中断出现,STM32 首先响应中断通道所对应的中断向量地址低的那个中断。 


可以通过调用STM32的固件库中的函数NVIC_PriorityGroupConfig()选择使用哪种优先级分组方式,这个函数的参数有下列5种:

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


第0组:所有4位用于指定响应优先级   ( 从不嵌套 )

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

第2组:最高2位用于指定抢占式优先级,最低2位用于指定响应优先级

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

第4组:所有4位用于指定抢占式优先级 ( 最大的嵌套可能性 ) ( 类似于 STR710 )



subpriority 开始的位号 :


如果从 7 号开始 那么没有 pre-emption priority, [ b7 b6 b5 b4 ] 全部为 subpriority 


如果从 6 号开始 那么 [ b7 ]为 pre-emption priority, [ b6 b5 b4 ] 为 subpriority 


如果从 3 号开始 那么 [ b7 b6 b5 b4 ]为 pre-emption priority, 没有 subpriority 


[pre-emption priority] :: [ subpriority ] ( STM32 共计 4 位 ) 所以无论如何配置做多只能有 16 级, 数值最小的具有最高的优先级


在程序中合理按排中断优先级可以达到具有高抢占式优先级的中断可以在具有低抢占式优先级的中断处理过程中被响应,即中断嵌套,或者说高抢占式优先级的中断可以嵌套低抢占式优先级的中断。


要注意的几点是:

1)如果指定的抢占式优先级别或响应优先级别超出了选定的优先级分组所限定的范围,将可能得到意想不到的结果;

2)抢占式优先级别相同的中断源之间没有嵌套关系;

3)如果某个中断源被指定为某个抢占式优先级别,又没有其它中断源处于同一个抢占式优先级别,则可以为这个中断源指定任意有效的响应优先级别。



#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 */


/**
  * @brief  Configures the priority grouping: pre-emption priority and subpriority.
  * @param  NVIC_PriorityGroup: specifies the priority grouping bits length. 
  *   This parameter can be one of the following values:
  *     @arg NVIC_PriorityGroup_0: 0 bits for pre-emption priority
  *                                4 bits for subpriority
  *     @arg NVIC_PriorityGroup_1: 1 bits for pre-emption priority
  *                                3 bits for subpriority
  *     @arg NVIC_PriorityGroup_2: 2 bits for pre-emption priority
  *                                2 bits for subpriority
  *     @arg NVIC_PriorityGroup_3: 3 bits for pre-emption priority
  *                                1 bits for subpriority
  *     @arg NVIC_PriorityGroup_4: 4 bits for pre-emption priority
  *                                0 bits for subpriority
  * @retval None
  */
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;



/**
  * @brief  Initializes the NVIC peripheral according to the specified
  *   parameters in the NVIC_InitStruct.
  * @param  NVIC_InitStruct: pointer to a NVIC_InitTypeDef structure that contains
  *   the configuration information for the specified NVIC peripheral.
  * @retval None
  */
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 // if (NVIC_InitStruct->NVIC_IRQChannelCmd == DISABLE)
  {
    /* Disable the Selected IRQ Channels -------------------------------------*/
    NVIC->ICER[NVIC_InitStruct->NVIC_IRQChannel >> 0x05] =
      (uint32_t)0x01 << (NVIC_InitStruct->NVIC_IRQChannel & (uint8_t)0x1F);
  }
}


stm32如何开关中断


在STM32/Cortex-M3中是通过改变CPU的当前优先级来允许或禁止中断。

PRIMASK位:只允许NMI和hard fault异常,其他中断/异常都被屏蔽(当前CPU优先级=0)。


FAULTMASK位:只允许NMI,其他所有中断/异常都被屏蔽(当前CPU优先级=-1)。


在STM32固件库中(stm32f10x_nvic.c和stm32f10x_nvic.h) 定义了四个函数操作PRIMASK位和FAULTMASK位,改变CPU的当前优先级,从而达到控制所有中断的目的。

下面两个函数等效于关闭总中断:

void NVIC_SETPRIMASK(void);

void NVIC_SETFAULTMASK(void);

下面两个函数等效于开放总中断:
void NVIC_RESETPRIMASK(void);
void NVIC_RESETFAULTMASK(void);

上面两组函数要成对使用,不能交叉使用。

例如:

第一种方法:
NVIC_SETPRIMASK();   //关闭总中断
NVIC_RESETPRIMASK();//开放总中断

第二种方法:
NVIC_SETFAULTMASK();   //关闭总中断
NVIC_RESETFAULTMASK();//开放总中断

常常使用

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



关键字:STM32  中断优先级  全局允许  禁止 引用地址:STM32 中断优先级以及全局允许和禁止

上一篇:STM32 IAP程序跳转前后的中断问题
下一篇:STM32F030使用RTC周期性唤醒STOP模式

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

stm32 SPI 读取和写入的问题
stm32 SPI的读取和写入和USART 一样需要判断标志位 unsigned char SPI1_ReadWrite(unsigned char writedat) { /* Loop while DR register in not emplty */ while(SPI_I2S_GetFlagStatus(SPI1,SPI_I2S_FLAG_TXE) == RESET); /* Send byte through the SPI1 peripheral */ SPI_I2S_SendData(SPI1, writedat); /* Wait to receive a byte */ while(SP
[单片机]
STM32 USB OTG官方库移植
实ST公司的官方usb库已经做得很不错了。只是一开始不会用,导致浪费了很多时间。 首先拿到库,需要确认板上的端口资源。 VBUS D- D+ GND 四条线至少要有,但是VBUS不一定要接在芯片端口上。作为从机的话VBUS可以直接拉高到3v以上。电流大小待确认。D-,D+一定要接到芯片的OTG FS HS均可 DM DP对应 D- D+。作为主机可以不接VBUS,也可将VBUS接到芯片端口作为检测口,此处不明是硬件原因还是什么原因,若使用VBUS检测的话,拔掉usb线会造成JLINK崩溃,因此我将VBUS口作为普通I/O口,查询读取是否连接或失去连接。 OTG_HS想用的话需要外接PHY,若无外接PHY,也将HS口配置成FS口。
[单片机]
无人机设计中STM32库实现的模拟i2c代码
目前发现国内正儿八经机器人、无人机并且还能活跃地上网关注行业前沿动向、热爱写科普文章的研究人员原来越少。因此所有的研究回答里都没有人真正说明白无人机到底是什么,而理解无人机到底是什么才是回答这个问题的先决条件。 什么是无人机 首先,无人机就是不载人的飞行器,而说到飞行器,通常我们又可以把飞行器分为三类。 1、固定翼(fixed wing)。平时坐的波音747空客A380,还有F-16歼-15之类的都是固定翼飞机。顾名思义就是翅膀形状固定,靠流过机翼的风提供升力。动力系统包括桨和助推发动机。固定翼根据机翼尺寸的不同还有很多小的分类,在此不细说。固定翼飞行器的优点是在三类飞行器里续航时间最长、飞行效率最高、载荷最大,缺点是起飞的时
[单片机]
无人机设计中<font color='red'>STM32</font>库实现的模拟i2c代码
单片机STM32时钟设计分析
  STM32互连型系列产品分为两个型号: STM32F105和STM32F107。STM32F105具有USB OTG 和CAN2.0B接口。STM32F107在USB OTG 和CAN2.0B接口基础上增加了以太网10/100 MAC模块 。片上集成的以太网MAC支持MII和RMII,因此,实现一个完整的以太网收发器只需一个外部PHY芯片。只使用一个25MHz晶振即可给整个微控制器提供时钟频率,包括以太网和USB OTG外设接口。微控制器还能产生一个25MHz或50MHz的时钟输出,驱动外部以太网PHY层芯片,从而为客户节省了一个附加晶振。   音频功能方面,新系列微控制器提供两个I2S音频接口,支持主机和从机两种模式,既
[单片机]
单片机<font color='red'>STM32</font>时钟设计分析
STM32-自学笔记(11.通过串口与PC通信,发Hello)
USART,中文是通用同步/异步串行接收/发送器。 人们常常称为串口(要知道串行通信口USART和串行总线接口SPI是完全不同的接口设备)。 USART在当代的通用计算机上几乎消失殆尽了,因为其通信速率、距离、硬件特性等不适合PC的要求, 取而代之的是“通用串行通信口” ,也就是USB口。 但在嵌入式应用领域,USART仍无法取代。 STM32的USART的配备: 可实现全双工的异步通信。 符合NRZ标准格式。 配备分频数波特率发生器:波特率可编程,发送和接收共用,最高达4.5Mbps。 可编程数据长度(8位或9位)。 可配置停止位,支持1或2个停止位。 可充当LIN总线主机,发送同步断开符;还可充当LIN
[单片机]
stm32不同闪存存储器容量启动文件选择说明
小容量产品是指闪存存储器容量在16K至32K字节之间的STM32F101xx、STM32F102xx和STM32F103xx微控制器。 选择 startup_stm32f10x_ld.s。 中容量产品是指闪存存储器容量在64K至128K字节之间的STM32F101xx、STM32F102xx和STM32F103xx微控制器。 选择 startup_stm32f10x_md.s。 大容量产品是指闪存存储器容量在256K至512K字节之间的STM32F101xx和STM32F103xx微控制器。 选择 startup_stm32f10x_hd.s。 还需要说明的一点是在 MDk安装路径\ARM\Startup\ST\下有一个
[单片机]
STM32 APB1总线时钟配置问题
调试载波通信系统的时候遇到这样一个问题:两台设备分别为A何B,他们都使用了定时器2~4来进行通讯,A设备的PCLK1配置为HCLK,而B设备的PCLK1配置为1/2HCLK,通讯过程发现A,B两个设备偶尔能通讯偶尔不能通讯,表现出通讯部稳定。理论上应该完全不能通讯才是,深入研究STM32F101C8T6的数据手册发现问题所在,截图如下: 图1 STM32功能框图 图2 STM32 时钟系统 从图1可以看到APB1总线挂接了TIM2~4,UART2~2...WWD等设备。然后从图2中可以看到只有外设直接使用了APB1的时钟作为实际时钟,而TIM2~4根据APB1的时钟进行了调整。因此当设备B的PCLK1配置为1/2HCL
[单片机]
<font color='red'>STM32</font> APB1总线时钟配置问题
开漏输出和推挽输出
概述 在STM32或者GD32中,普通的输出GPIO输出方式主要是开漏输出和推挽输出,下面我们开始讲解这2种模式的区别。 下图是GPIO内部的结构示意图。 在上图中,P-MOS带了一个⚪,说明是低电平导通。 上图是GPIO的示意图,有输入和输出,如果简化为输出,则如下所示。 模拟文件下载 https://download.csdn.net/download/qq_24312945/85250172 推挽输出 推挽输出的内部电路大概是下图这个样子,由一个P-MOS和一个N-MOS组合而成,同一时间只有一个管子能够进行导通。 当输出高电平时候,P-MOS导通,N-MOS截至,此时电源电流入R5。 当输出低电平时
[单片机]
开漏输出和推挽输出
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

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

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

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