zoukankan      html  css  js  c++  java
  • STM32-M0中断优先级介绍

      先解释中断优先级,后面讲代码的实现。

      差异:M0的中断优先级相比于M4,没有用到分组,且只用到了2个bit位(即0~3)来设置,数值越小,优先级越高;同等优先级,根据终端号的大小来决定谁先执行。

      根据下面这张编程手册里的图来说明:

     

      从上往下看,共32个IRQ中断,每个中断优先级占8个位,一个寄存器存4个中断的优先级,所以M0的IRQ中断最多只有32个;表27中高亮部分,说的是只用高两位来表示优先级的值,低六位填0,没有用到。

      还有一个要提到的是word-accessible,就是寄存器只能按字操作。

      M0的中断优先级就讲完了,还是很简单的,那我们讲一下代码的实现:

     

     1 void NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct)
     2 {
     3   uint32_t tmppriority = 0x00;
     4   
     5   /* Check the parameters */
     6   assert_param(IS_FUNCTIONAL_STATE(NVIC_InitStruct->NVIC_IRQChannelCmd));
     7   assert_param(IS_NVIC_PRIORITY(NVIC_InitStruct->NVIC_IRQChannelPriority));  
     8     
     9   if (NVIC_InitStruct->NVIC_IRQChannelCmd != DISABLE)
    10   {
    11     /* Compute the Corresponding IRQ Priority --------------------------------*/    
    12     tmppriority = NVIC->IP[NVIC_InitStruct->NVIC_IRQChannel >> 0x02];
    13     tmppriority &= (uint32_t)(~(((uint32_t)0xFF) << ((NVIC_InitStruct->NVIC_IRQChannel & 0x03) * 8)));
    14     tmppriority |= (uint32_t)((((uint32_t)NVIC_InitStruct->NVIC_IRQChannelPriority << 6) & 0xFF) << ((NVIC_InitStruct->NVIC_IRQChannel & 0x03) * 8));    
    15     
    16     NVIC->IP[NVIC_InitStruct->NVIC_IRQChannel >> 0x02] = tmppriority;
    17     
    18     /* Enable the Selected IRQ Channels --------------------------------------*/
    19     NVIC->ISER[0] = (uint32_t)0x01 << (NVIC_InitStruct->NVIC_IRQChannel & (uint8_t)0x1F);
    20   }
    21   else
    22   {
    23     /* Disable the Selected IRQ Channels -------------------------------------*/
    24     NVIC->ICER[0] = (uint32_t)0x01 << (NVIC_InitStruct->NVIC_IRQChannel & (uint8_t)0x1F);
    25   }
    26 }

      这段代码是官方库的代码,我说下思路:

        1、要设置优先级,要先找到该中断的优先级寄存器在哪个寄存器里,将中断号除以4,得到对应寄存器,读该寄存器的值给变量tmppriority ,代码如下:

          tmppriority = NVIC->IP[NVIC_InitStruct->NVIC_IRQChannel >> 0x02];

        2、再判断该终端号的优先级值在对应寄存器的哪个位置,并清零该8位,共四个位置为:0~7、8~15、16~23、24~31,代码如下,NVIC_InitStruct->NVIC_IRQChannel & 0x03表示对4求余的结果;

          tmppriority &= (uint32_t)(~(((uint32_t)0xFF) << ((NVIC_InitStruct->NVIC_IRQChannel & 0x03) * 8)));

        3、接着给该8位写入要设置的优先级的值,由于优先级只占了8位的高两位,所以NVIC_InitStruct->NVIC_IRQChannelPriority << 6写高两位,再左移到在该寄存器中对应的位置,和读到寄存器的值tmppriority 与运算,就完成了对该寄存器的对应位写优先级值得操作,记住,这是一个32位的数;

          tmppriority |= (uint32_t)((((uint32_t)NVIC_InitStruct->NVIC_IRQChannelPriority << 6) & 0xFF) << ((NVIC_InitStruct->NVIC_IRQChannel & 0x03) * 8)); 

        4、把这个32位的数写入该寄存器中;  

          NVIC->IP[NVIC_InitStruct->NVIC_IRQChannel >> 0x02] = tmppriority;

        废话:((NVIC_InitStruct->NVIC_IRQChannel & 0x03) * 8))这个语句是用来获得在寄存器中的偏移值得,用这个偏移值就能把8位数进行左移。

    完!

  • 相关阅读:
    window redis 安装配置
    mongodb下载及安装配置教程【仅供参考】
    合并对象
    JSON
    函数声明与函数表达式
    mongodb write 【摘自网上,只为记录,学习】
    javascript 操作cookie
    javascript 将多维数组转换为一维数组
    javascript 去除字符串中重复字符
    javascript 获取url参数
  • 原文地址:https://www.cnblogs.com/leo0621/p/8694752.html
Copyright © 2011-2022 走看看