STM32外部中断EXTI介绍及配置(标准库)详解

什么是中断

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

STM32有68个可屏蔽中断通道(不包含16个Cortex™-M3的中断线),16个可编程的优先等级(使用了4位中断优先级)(可以对优先级进行分组,设置抢占优先级和响应优先级),使用NVIC(嵌套向量中断控制器)进行统一管理。

STM32外部中断示意图简介

介绍为从右往左

NVIC套向量中断控制器

内核外设,进行中断优先级分配

NVIC有多个输入口,可以接入多个外设

一个外设可能会同时占用多个中断通道,所以有n条线进行连接

NVIC只有一个输出口,根据中断优先级向CPU输出当前该处理的中断

NVIC优先级分组

NVIC的中断优先级由优先级寄存器的4位(0-15)决定,分为高n位的抢占优先级和低4-n位的响应优先级。分组位数取值为2的0-4次方。

抢占优先级高的可以打断别的程序中断,优先进行自己的中断。也就是中断嵌套。

响应优先级高的,可以在别人的中断后面进行排队。vip插队,但不能打断正在进行的中断程序,只能排在下一位。

抢占优先级和响应优先级为同级关系,按优先级号进行优先中断,数值越小优先级越高,0为最高优先级。如果抢占优先级和响应优先级的优先等级相同,则看中断号排队,可以参考STM32中断中的向量表。

EXTI外部中断

简介

EXTI可以监测指定GPIO口的电平信号,当指定的GPIO口的电平信号发生改变的时候,EXTI立即向NVIC发送中断申请,经过NVIC裁决后中断CPU主程序执行EXTI中断程序。

触发方式:上升沿、下降沿、软件触发

支持的GPIO口:所有的GPIO口,但相同的Pin不能同时触发中断
例如:PA0和PB0只能触发其中的一个,如下图,共有16个外部中断线路,下图只截取了其中一个共16个。

通道数:EXTI支持20个中断和时间屏蔽位

下图中,GPIO端口连接到16个外部中断/事件线上;EXTI0 — EXTI15;外加PVD电源电压检测、RTC闹钟、USB唤醒和以太网唤醒四个蹭网设备并联接入ETIO,可参考整体结构图。

响应方式:中断响应(触发中断)和事件响应(不触发中断触发其他外设,ADC等)

 外部中断整体结构图

要注意EXTI0-EXTI4每个都有一个单独的中断函数。

EXTI9_5和EXTI15-10分别在一个数据通道中,执行中断时需要判断是哪个引脚触发的中断。

触发其他外设为事件响应,有20条通道。

EXTI内部框图

 

 

AFIO数据选择器

在GPIOx的16个引脚里选择其中一个连接到后面的EXTI的通道里。所以相同的Pin不能同时触发中断。

AFIO主要用于引脚复用功能的选择和重定义

在STM32中AFIO主要完成两个任务:复用功能引脚重映射、中断引脚选择。

一个引脚可以有多个功能为复用,有些引脚的功能可以映射到其他引脚进行使用(感觉有点像fate里的投影)。

AFIO选择中断引脚结构图

STM32外部中断配置 

配置中断整体结构框图中的外设即可

中断服务映射关系

 表格来源STM32 外部中断详解(原理+配置代码)_stm32外部中断代码-CSDN博客

配置流程

1.配置RCC         打开涉及到外设的时钟

2.配置GPIO        端口为输入模式

3.配置AFIO

4.配置EXTI        边沿触发方式选择以及触发响应方式,中断or事件

5.配置NVIC        选择合适优先级

RCC时钟配置

内核外设不用开启时钟

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);//开启GPIOB的时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);//开启AFIO的时钟

GPIO初始化

EXTI推荐配置为浮空、上拉或下拉

GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //上拉输入
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14;    //选择14号引脚
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);	

AFIO配置

 AFIO库函数
void GPIO_AFIODeInit(void);//复位
void GPIO_PinLockConfig(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);//锁定配置

//事件输出
void GPIO_EventOutputConfig(uint8_t GPIO_PortSource, uint8_t GPIO_PinSource);
void GPIO_EventOutputCmd(FunctionalState NewState);

void GPIO_PinRemapConfig(uint32_t GPIO_Remap, FunctionalState NewState);//引脚重映射

//配置AFIO数据选择器,选择对应引脚
void GPIO_EXTILineConfig(uint8_t GPIO_PortSource, uint8_t GPIO_PinSource);

void GPIO_ETH_MediaInterfaceConfig(uint32_t GPIO_ETH_MediaInterface);//以太网相关
初始化
//将外部中断的14号线映射到GPIOB,即选择PB14为外部中断引脚
GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource14);

EXTI配置

EXTI库函数
void EXTI_DeInit(void);//复位
void EXTI_Init(EXTI_InitTypeDef* EXTI_InitStruct);//通过结构体配置,类似GPIO
void EXTI_StructInit(EXTI_InitTypeDef* EXTI_InitStruct);//结构体变量赋值

void EXTI_GenerateSWInterrupt(uint32_t EXTI_Line);//软件触发外部中断

FlagStatus EXTI_GetFlagStatus(uint32_t EXTI_Line);//获取指定标志位是否被置1,主程序使用
void EXTI_ClearFlag(uint32_t EXTI_Line);//清除标志位

ITStatus EXTI_GetITStatus(uint32_t EXTI_Line);//获取指定标志位是否被置1,中断函数中使用
void EXTI_ClearITPendingBit(uint32_t EXTI_Line);//清除标志位
 初始化EXTI
EXTI_InitTypeDef EXTI_InitStructure;						//定义结构体变量
EXTI_InitStructure.EXTI_Line = EXTI_Line14;					//选择配置外部中断的14号线
EXTI_InitStructure.EXTI_LineCmd = ENABLE;					//指定外部中断线使能
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;			//指定外部中断线为中断模式
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;		//指定外部中断线为下降沿触发
EXTI_Init(&EXTI_InitStructure);								//配置EXTI外设

 NVIC配置

在misc库文件中

NVIC库函数
void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup);//中断分组
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);//系统低功耗配置
void SysTick_CLKSourceConfig(uint32_t SysTick_CLKSource);
初始化NVIC
//NVIC中断分组
//此分组配置在整个工程中仅需调用一次
//若有多个中断,可以把此代码放在main函数内,while循环之前
//若调用多次配置分组的代码,则后执行的配置会覆盖先执行的配置
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);		//配置NVIC为分组2
	    											
	
NVIC_InitTypeDef NVIC_InitStructure;						//定义结构体变量
NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn;		//选择配置NVIC的EXTI15_10线
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;				//指定NVIC线路使能
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;	//指定NVIC线路的抢占优先级为1
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;			//指定NVIC线路的响应优先级为1
NVIC_Init(&NVIC_InitStructure);								//配置NVIC外设

 中断函数

 在启动文件中IRQHeadler结尾的名称

/*
EXTI0_IRQHandler           
EXTI1_IRQHandler           
EXTI2_IRQHandler          
EXTI3_IRQHandler          
EXTI4_IRQHandler 
EXTI9_5_IRQHandler
EXTI15_10_IRQHandler
*/

void EXTI15_10_IRQHandler(void)
{
	if (EXTI_GetITStatus(EXTI_Line14) == SET)//判断是否是外部中断14号线触发的中断
	{
		

		EXTI_ClearITPendingBit(EXTI_Line14);//清除外部中断14号线的中断标志位
											//中断标志位必须清除
											//否则中断将连续不断地触发,导致主程序卡死
	}
}

写的有点啰嗦,方便自己以后看。

以上为学习江科大老师STM32内容总结,图片来源为老师PPT,仅为个人理解如有不对请指出。

  • 51
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值