STM32学习之路-AIRCR寄存器PRIGROUP位的配置<NIVC

来源:互联网 发布:linux命令自动补全 编辑:程序博客网 时间:2024/06/15 00:04

原文出处:http://blog.csdn.net/demetered/article/details/26044693

AIRCR是NIVC配置中一个关键的寄存器.而PRIGROUP又是AIRCR中关键的位

让我们看看CM3技术手册中该为是怎么配置的


上面说得很清楚,PRIGROUP的值是代表一个从LSB左边开始的小数值.怎么理解呢?看看下面

CM3使用8bit位来设置这里, 也就是说从0-7位.在寄存器中是这样的

|7| 6| 5| 4| 3| 2 |1| 0|

当PRIGROUT[10:8]的值为111时,即为7时,就是说7位(第8位)为有效位的开始位,用数值代表就像这样 0.76543210

110(6)时,就是7.6543210 依次类推

而STM32原理和它一样,不过只是用了4bit来表示,看看下图


好,那现在来说说为什么要这样搞.

让我们时光倒流一下,谈谈中断优先级的问题,请看图


可以看到优先组别总用有5组, 0-4,分为占先式优先级和副优先级,为什么要搞成这样,原因在下面:

因为STM32有很多中断,要处理这些中断的时候总是需要先后顺序的,所以来给他们给级别了!

怎么设置组号呢?

在misc.h可以看到这些宏的定义

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

在看看,它的值是0x700, 在看看 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);这个函数,这就是配置AIRCR寄存器的函数

再看看它的内容

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

OK, AIRCR_VECTKEY的值为 #define AIRCR_VECTKEY_MASK    ((uint32_t)0x05FA0000)

再来看看这小坏蛋为什么要这样设置:


看到了吧31:16位要写0X05FA,然后与上0X700那就设置了[10:8]这里为111.再想想上面分析的,0组就是这么实现的呀!

已经晚了,今天就记录这么多吧.. 见下一篇.

---------------------------------------------------------------------我是分割线(⊙o⊙)哦------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

优先级的问题可以分为以下情况:

抢占优先级和响应优先级

(1)抢占优先级高的可以打断抢占优先级低的,形成嵌套.

(2)抢占优先级相同时,看响应优先级.如果两个中断前后发生的话,后来的中断不能打断前一个中断

只能等,如果两个中断同时发生的话,则响应优先级高的先响应.

(3)抢占级别和响应级别都一样时,按照中断的地址来响应,地址低的先响应

这样就解决了优先级的问题.

哪个级别高呢?  0>1>2>...... 

STM32共有5组分别是0-4组,还是借那个图


可以看到第4组所有的位都用来设置抢占式优先级了(占先式),所以它能嵌套15个中断,然后自身一个中断,一次类推

0组只有响应式优先级,所以它不能嵌套任何中断,也就是这个组别的中断不能打断任何的其他在运行的中断.

配置NIVC的例子

[cpp] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. void NVIC_Configuration(void)  
  2. {  
  3.   NVIC_InitTypeDef NVIC_InitStructure;  
  4.       
  5.   NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1); //配置组别  
  6.     
  7.   /* Enable the EXTI9-5 Interrupt */  
  8.   NVIC_InitStructure.NVIC_IRQChannel =EXTI9_5_IRQn;      //配置哪个中断              
  9.   NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //抢占优先级        
  10.   NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;        //优先响应级          
  11.   NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;       //使能               
  12.   NVIC_Init(&NVIC_InitStructure);  
  13.   
  14.   NVIC_InitStructure.NVIC_IRQChannel = EXTI2_IRQn;                
  15.   NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;        
  16.   NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;                
  17.   NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                  
  18.   NVIC_Init(&NVIC_InitStructure);  
  19.   
  20.   NVIC_InitStructure.NVIC_IRQChannel = EXTI3_IRQn;                 
  21.   NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;        
  22.   NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;                 
  23.   NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                 
  24.   NVIC_Init(&NVIC_InitStructure);  
  25. }  
这里的配置中3个中断的抢占级别是一样的,都是0,所以谁都不能打断谁,优先响应级别是EXTI3_IRQn最高,

EXTI3_IRQn的值是多少呢,在stm32f10x.h中可以看到




0 0