STM32----中断优先级设置

步骤一  设置中断分组

STM32中断规则

中断优先级分为抢占式优先级和子优先级。对于每一个中断需事先设置其抢占式优先级和子优先级。 

抢占式优先级级别高的中断可以打断抢占式优先级级别地的中断。抢占式优先级级别相同时,互相均不能打断对方中断执行,且同时产生两个中断时,按照中断的子优先级顺序执行中断。

例子:中断2设置抢占式优先级为1,子优先级为2。中断3的抢占式优先级为2,子优先级为1。中断8的抢占式优先级为1,子优先级为3

此时中断优先级:中断2>中断8>中断3

具体的 当中断3执行过程中,中断2或中断8任意一个产生,均可以使中断3挂起而先执行后产生的中断。另外当中断2和中断8同时产生的时候,优先执行中断2中断2执行完毕后执行中断8。

中断分组的实现

COM3内核中存在设置中断优先级分组的寄存器(IP[240]:)

IP寄存器有240个8Bbit的寄存器。STM32只是使用60个。每个寄存器都可以设置特定的一个中断的抢占式优先级和子优先级的级别。比如中断2,其对应的IP寄存器的值可能为      01 10  0000(这是中断优先级分组设置为2的情况下 即两位用来标识抢占式优先级 两位用来标识子优先级) 或 1 010  0000。STM32只是使用其高四位,另外两种可能的设置方法取决于中断分组设置。中断分组的设置由SCB->IRCR寄存器(bit10~8)设置决定。

中断分组可分为5组:当SCB->AIRCR寄存器(bit10~8)数分别为111、110、101、011、001时  ,不同类优先级能表示位数比:抢占式优先级:子优先级=  0:4   or    1:3    or   2:2   or   3:1   or   4:0

分组使用的函数

void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup) //NVIC_PriorityGroup的值为NVIC_PriorityGroup_X ,其中X=0~4,分别代表不同中断分组情况
{
 assert_param(IS_NVIC_PRIORITY_GROUP(NVIC_PriorityGroup));
 SCB->AIRCR = AIRCR_VECTKEY_MASK | NVIC_PriorityGroup;
}



步骤二  中断初始化

对中断初始化结构体相关赋值

中断初始化的结构体

typedef struct
{
 uint8_t NVIC_IRQChannel;                    //要设置的中断号 
 uint8_t NVIC_IRQChannelPreemptionPriority;  //抢占式优先级级别
 uint8_t NVIC_IRQChannelSubPriority;         //子优先级级别
 FunctionalState NVIC_IRQChannelCmd;         //中断使能
} NVIC_InitTypeDef;


中断初始化

中断初始化函数

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);
  }
}


根据STM32中断规则实现多级中断嵌套

参考

《Cortex-M3权威指南》

《STM32F1开发指南-库函数版本》

  • 9
    点赞
  • 51
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
对于STM32微控制器的中断优先级配置,可以按照以下步骤进行操作: 1. 确定所需中断的优先级范围:STM32微控制器中,中断优先级可以分为0到15共16个级别。级别越低,优先级越高。 2. 设置全局中断优先级分组:在启用中断之前,需要设置全局中断优先级分组。可以使用函数`NVIC_PriorityGroupConfig()`来进行设置。常见的分组方式有4-位抢占优先级和0-位子优先级,也可以根据具体需求进行设置。 3. 配置具体中断的优先级:对于每个中断源,需要使用函数`NVIC_Init()`来进行配置。函数的输入参数包括中断通道号和优先级等信息。例如,对于外部中断线 EXTI0 的优先级配置,可以使用如下代码: ```c NVIC_InitTypeDef NVIC_InitStruct; NVIC_InitStruct.NVIC_IRQChannel = EXTI0_IRQn; // 中断通道号 NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0; // 抢占优先级 NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0; // 子优先级 NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStruct); ``` 在配置完所有中断的优先级后,可以根据具体应用的需求对中断进行使能或禁止操作。 需要注意的是,具体的中断优先级配置会受到中断分组的影响,因此需要根据具体应用场景和需求来进行合理的配置。同时,在设计中断服务程序时,也应该注意不同中断间的优先级关系,避免出现优先级反转等问题。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值