运动控制器33:STM32的中断嵌套控制器NVIC
2018-02-02 本文已影响0人
吴松乾
NVIC_Init中断控制器初始化
uint8_t NVIC_IRQChannel
FunctionalState NVIC_IRQChannelCmd
uint8_t NVIC_IRQChannelPreemptionPriority
uint8_t NVIC_IRQChannelSubPriority
- 在stm32f10x.h中有一个枚举体typedef enum IRQn,里面定义了中断NVIC_IRQChannel。
- NVIC_IRQChannelCmd,使能
- 这里我们一定要理解两个概念:
- 抢占优先级:抢占优先可以中断别的中断服务程序,数值越小,级别越高,为主优先级。
- 响应优先级:不能抢占,但是如果两个抢占级别一样,则先执行响应优先级更好的服务。
- 所以设置中断时,首先要确定我们分配几个抢占优先级,几个响应优先级,然后再分配该中断的抢占优先级级,然后分配响应优先级级别,如果抢占和响应都相同,则按照中断向量表的序号进行优先执行,优先级数值越低,则更优先执行,我们上一篇已经介绍,STM32F103ZET6一共有68个中断通道(每一个中断通道还有中断源)。
- 下面为多个定时器设置中断时候的程序例子
//一共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);
}