我爱编程

运动控制器33:STM32的中断嵌套控制器NVIC

2018-02-02  本文已影响0人  吴松乾

NVIC_Init中断控制器初始化

uint8_t  NVIC_IRQChannel 
FunctionalState  NVIC_IRQChannelCmd 
uint8_t  NVIC_IRQChannelPreemptionPriority 
uint8_t  NVIC_IRQChannelSubPriority 

  1. 在stm32f10x.h中有一个枚举体typedef enum IRQn,里面定义了中断NVIC_IRQChannel。
  2. NVIC_IRQChannelCmd,使能
  3. 这里我们一定要理解两个概念:
    • 抢占优先级:抢占优先可以中断别的中断服务程序,数值越小,级别越高,为主优先级。
    • 响应优先级:不能抢占,但是如果两个抢占级别一样,则先执行响应优先级更好的服务。
  4. 所以设置中断时,首先要确定我们分配几个抢占优先级,几个响应优先级,然后再分配该中断的抢占优先级级,然后分配响应优先级级别,如果抢占和响应都相同,则按照中断向量表的序号进行优先执行,优先级数值越低,则更优先执行,我们上一篇已经介绍,STM32F103ZET6一共有68个中断通道(每一个中断通道还有中断源)。
  5. 下面为多个定时器设置中断时候的程序例子
   //一共5组,0组则0个抢占优先级,16个响应优先级,1组为两个抢占8个响应,2组为4个抢占4个响应
   NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
 
   //TIM2,抢占和响应都为0,最优先执行
   NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
   NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
   NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
   NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
   NVIC_Init(&NVIC_InitStructure);
   
   //抢占为1级
   NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;
   NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
   NVIC_Init(&NVIC_InitStructure);
 
   //抢占为2,优先级最低
   NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn;
   NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
   NVIC_Init(&NVIC_InitStructure);

NVIC_PriorityGroupConfig

这个函数在上面有介绍,每次设置NVIC初始化之前都要调用,如果之前有调用过,则可以略过。

NVIC_SetVectorTable

了解这个函数我们必须先了解IAP,也就是“在应用编程”In Application Programming

IAP是In Application Programming的首字母缩写,IAP是用户自己的程序在运行过程中对User Flash的部分区域进行烧写,目的是为了在产品发布后可以方便地通过预留的通信口对产品中的固件程序进行更新升级。
对于STM32来说,因为它的中断向量表位于程序存储器的最低地址区,为了使第一部分代码能够正确地响应中断,通常会安排第一部分代码处于Flash的开始区域,而第二部分代码紧随其后。在第二部分代码开始执行时,首先需要把CPU的中断向量表映像到自己的向量表,然后再执行其他的操作。

NVIC_SystemLPConfig

系统低功耗配置,进入低功耗的模式进行设置,模式有SEVONPEND ,SLEEPDEEP 和SLEEPONEXIT 三种,系统从某种模式下,通过外部中断和内部的事件进入睡眠等模式的设置。

SysTick_CLKSourceConfig

设置SYSTICK的时钟源,是HCLK还是进行8分频。

使用建议

我们可以在BSP时进行NVIC的初始化,初始化时,配置好向量表的位置,以及设置好中断向量的优先级组,如下:

void Nvic_init(void)
{
    #ifdef  VECT_TAB_RAM    //中断向量表存放地址到SRAM 0x20000000  
        NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0); 
    #else                   //中断向量表存放地址到FLASH   0x08000000
        NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);   
    #endif
    //嵌套向量中断控制器设置
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1); 
}
上一篇下一篇

猜你喜欢

热点阅读