STM32F1中断NVIC

目录

1.  中断系统

2.  中断向量表

3.  NVIC基本结构

4.  NVIC优先级分组

5.   NVIC程序编写

5.1  中断分组

5.2  中断结构体变量

5.3  中断通道选择

5.4  抢占优先级和响应优先级配置

6.  中断程序执行


1.  中断系统

中断:在主程序运行过程中,出现了特定的中断触发条件(中断源),使得CPU暂停当前正在运行的程序,转而去处理中断程序,处理完成后又返回原来被暂停的位置继续运行

STM32F1中断NVIC_第1张图片

        在此时的断点部分,若是此时主程序还在进行例如加减乘除运算,但是突然有个更加紧急的的事情需要处理,可以在此时进行中断,优先处理更加紧急的事情,等事情处理完后,在返回主程序继续处理。

        在中断这里,我们在断点处离开,编译器会自动帮我们保护现场(当前程序),等我们回来(中断完成后),继续工作。

中断优先级:当有多个中断源同时申请中断时,CPU会根据中断源的轻重缓急进行裁决,优先响应更加紧急的中断源

        例如:两个人同时就医,急诊和门诊。

中断嵌套:当一个中断程序正在运行时,又有新的更高优先级的中断源申请中断,CPU再次暂停当前中断程序,转而去处理新的中断程序,处理完成后依次进行返回

STM32F1中断NVIC_第2张图片

STM32F1中断NVIC_第3张图片

        STM32F1系列包含最多:68个可屏蔽中断通道,包含EXTI、TIM、ADC、USART、SPI、I2C、RTC等多个外设。

        使用NVIC统一管理中断,每个中断通道都拥有16个可编程的优先等级,可对优先级进行分组,进一步设置抢占优先级和响应优先级

2.  中断向量表

STM32F1中断NVIC_第4张图片

        灰色部分为内核中断,了解即可,一般用不上,初学者可以不用那么深入。

        这里仅做了解,编译器已经帮我们做好了。

        中断函数的地址由编译器来进行分配的,是不固定的,但是终端的跳转因为硬件的限制,只能调到固定的地址进行程序的执行,为了让硬件跳转到不固定的一个中断函数里,这里需要在中断函数里定义一个地址的列表,列表地址是固定的,中断发生后跳到这个位置,在这个固定位置由编译器,再加上一条跳转到中断函数的代码,这样就可以调到任意位置。

3.  NVIC基本结构

NVIC:嵌套中断向量控制器

统一分配中断优先级,和管理中断

NVIC内核外设,CPU的小助手

STM32F1中断NVIC_第5张图片

        米色圈住部分,意思是:一个外设可能会占用多个中断通道,所以这里有“n”条线,NVIC只有一个输出口,NVIC根据每个中断的优先级进行分配中断的先后顺序。

例如:医院叫号,CPU为医生,NVIC进行排号,中断是病人,NVIC根据病人的紧急程度进行排号,找医生。

4.  NVIC优先级分组

        NVIC的中断优先级由优先级寄存器的4位(0~15)决定,这4位可以进行切分,分为高n位的抢占优先级和低4-n位的响应优先级

        抢占优先级高的可以中断嵌套,响应优先级高的可以优先排队,抢占优先级和响应优先级均相同的按中断号排队

STM32F1中断NVIC_第6张图片

对于响应优先级,相当于“插队”,此时“1”在看病(程序在进行中),“4”要是比较严重,“4”可以进行插队到“2”前面,但是要等“1”看完(进程走完)

STM32F1中断NVIC_第7张图片

对于抢占优先级(中断嵌套),相当于“1”在看病(程序在进行中),“4”不等“1”看完直接冲到屋内,把“1”推到一边,“4”先看病(进行),“4”先看完,在进行“1”,再依次进行后续的操作。

STM32F1中断NVIC_第8张图片

STM32F1中断NVIC_第9张图片

5.   NVIC程序编写

了解:

中断分组:

void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup);

初始化NVIC:

void NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct);

设置中断向量表:

void NVIC_SetVectorTable(uint32_t NVIC_VectTab, uint32_t Offset);

系统低功耗配置:

void NVIC_SystemLPConfig(uint8_t LowPowerMode, FunctionalState NewState);

5.1  中断分组

/**
  * @brief  Configures the priority grouping: pre-emption priority and subpriority.
  * @param  NVIC_PriorityGroup: specifies the priority grouping bits length. 
  *   This parameter can be one of the following values:
  *     @arg NVIC_PriorityGroup_0: 0 bits for pre-emption priority
  *                                4 bits for subpriority
  *     @arg NVIC_PriorityGroup_1: 1 bits for pre-emption priority
  *                                3 bits for subpriority
  *     @arg NVIC_PriorityGroup_2: 2 bits for pre-emption priority
  *                                2 bits for subpriority
  *     @arg NVIC_PriorityGroup_3: 3 bits for pre-emption priority
  *                                1 bits for subpriority
  *     @arg NVIC_PriorityGroup_4: 4 bits for pre-emption priority
  *                                0 bits for subpriority
  * @retval None
  */
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;
}

根据需求,配置所需要的分组,几个抢占,几个响应。

这里我们选择分组2,两个抢占,两个响应

    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//中断分组

注意:分组方式整个芯片只能用一种

5.2  中断结构体变量

	NVIC_InitTypeDef NVIC_InitStructure;

5.3  中断通道选择

  uint8_t NVIC_IRQChannel;                    /*!< Specifies the IRQ channel to be enabled or disabled.
                                                   This parameter can be a value of @ref IRQn_Type 
                                                   (For the complete STM32 Devices IRQ Channels list, please
                                                    refer to stm32f10x.h file) */

要是我们配置PC13引脚,则:

	NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn;

5.4  抢占优先级和响应优先级配置

STM32F1中断NVIC_第10张图片

        根据如图分组进行配置,我们配置为分组“2”,则抢占优先级和响应优先级的取值都为“0~3”,由于我们只配置一个引脚所以这里全给“1”。

	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;

完整初始化:

	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//中断分组,
	
	NVIC_InitTypeDef NVIC_InitStructure;
	NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
	NVIC_Init(&NVIC_InitStructure);	

6.  中断程序执行

void EXTI15_10_IRQHandler(void)
{
	if (EXTI_GetITStatus(EXTI_Line14) == SET)
	 {
			EXTI_ClearITPendingBit(EXTI_Line14);
	}
}

学习笔记,仅供参考。

你可能感兴趣的:(STM32学习笔记,单片机,嵌入式硬件)