STM32F1中断NVIC

目录

[1. 中断系统](#1. 中断系统)

[2. 中断向量表](#2. 中断向量表)

[3. NVIC基本结构](#3. NVIC基本结构)

[4. NVIC优先级分组](#4. NVIC优先级分组)

[5. NVIC程序编写](#5. NVIC程序编写)

[5.1 中断分组](#5.1 中断分组)

[5.2 中断结构体变量](#5.2 中断结构体变量)

[5.3 中断通道选择](#5.3 中断通道选择)

[5.4 抢占优先级和响应优先级配置](#5.4 抢占优先级和响应优先级配置)

[6. 中断程序执行](#6. 中断程序执行)


1. 中断系统

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

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

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

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

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

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

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

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

2. 中断向量表

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

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

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

3. NVIC基本结构

NVIC:嵌套中断向量控制器

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

NVIC内核外设,CPU的小助手

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

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

4. NVIC优先级分组

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

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

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

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

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 抢占优先级和响应优先级配置

根据如图分组进行配置,我们配置为分组"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);
	}
}

学习笔记,仅供参考。

相关推荐
学习噢学个屁7 分钟前
基于STM32汽车温度空调控制系统
c语言·stm32·单片机·嵌入式硬件·汽车
郦77734 分钟前
价格性价比高系列的高性能单片机MS32C001-C
单片机·嵌入式硬件
iCxhust1 小时前
汇编字符串比较函数
c语言·开发语言·汇编·单片机·嵌入式硬件
小智学长 | 嵌入式1 小时前
Arduino入门教程:1-1、先跑起来(点亮LED&打印Helloworld)
单片机·嵌入式硬件
码小文2 小时前
MCU、MPU、GPU、Soc、DSP、FPGA、CPLD……它们到底是什么?
笔记·单片机·嵌入式硬件·学习·ic常识
我命由我123453 小时前
STM32 开发 - 中断案例(中断概述、STM32 的中断、NVIC 嵌套向量中断控制器、外部中断配置寄存器组、EXTI 外部中断控制器、实例实操)
c语言·开发语言·c++·stm32·单片机·嵌入式硬件·嵌入式
宋一平工作室4 小时前
单片机队列功能模块的实战和应用
c语言·开发语言·stm32·单片机·嵌入式硬件
SY师弟4 小时前
台湾TEMI协会竞赛——2、足球机器人组装教学
c语言·单片机·嵌入式硬件·机器人·嵌入式·台湾temi协会
挨踢玩家4 小时前
stm32---dma串口发送+fifo队列框架
stm32·单片机·嵌入式硬件
youcans_4 小时前
【EdgeAI实战】(3)边缘AI开发套件 STM32N6570X0 用户手册
stm32·单片机·嵌入式硬件·边缘计算·边缘ai