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位数进行左移。

    完!

  • 相关阅读:
    Java实现 蓝桥杯VIP 算法提高 排队打水问题
    Java实现 蓝桥杯VIP 算法提高 排队打水问题
    Java实现 蓝桥杯VIP 算法提高 排队打水问题
    Java实现 蓝桥杯VIP 算法提高 特殊的质数肋骨
    Java实现 蓝桥杯VIP 算法提高 特殊的质数肋骨
    Java实现 蓝桥杯VIP 算法提高 特殊的质数肋骨
    Java实现 蓝桥杯VIP 算法提高 特殊的质数肋骨
    现在使用控件, 更喜欢继承(覆盖控件已有的函数,很奇怪的一种使用方式)
    Controls 属性与继承 TShape 类的小练习(使用TShape可以解决很多图形问题)
    QT创建窗口程序、消息循环和WinMain函数(为主线程建立了一个QEventLoop,并执行exec函数)
  • 原文地址:https://www.cnblogs.com/leo0621/p/8694752.html
Copyright © 2011-2022 走看看