STM32外部中断(EXTI)配置指南

EXTI简介

EXTI(Extern Interrupt)外部中断
EXTI可以监测指定GPIO口的电平信号,当其指定的GPIO口产生电平变化时,EXTI将立即向NVIC发出中断申请,经过NVIC裁决后即可中断CPU主程序,使CPU执行EXTI对应的中断程序
支持的触发方式:上升沿/下降沿/双边沿/软件触发
支持的GPIO口:所有GPIO口,但相同的Pin不能同时触发中断
通道数:16个GPIO_Pin,外加PVD输出、RTC闹钟、USB唤醒、以太网唤醒
触发响应方式:中断响应/事件响应

EXTI基本结构

AFIO

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

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

EXTI框图

EXTI配置基本步骤:

  1. 开启相关外设时钟时钟
  2. 配置GPIO,将选定的端口配置为输入模式
  3. 配置AFIO,选择外部中断引脚
  4. 配置EXTI,选择边沿触发方式,选择触发响应方式
  5. 配置NVIC,给中断选择一个优先级

一:开启相关外设时钟时钟:

由于NVIC和EXTI的时钟是一直开启的,所以我们只需要开启GPIO和AFIO
GPIO和AFIO都是在APB2总线上的外设,所以应该用RCC_APB2PeriphClockCmd函数
现在我们开启GPIO和AFIO的时钟:

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

二:配置GPIO

首先查询参考手册,查看EXTI外设使用GPIO时应该将GPIO配置成什么模式

现在我们配置GPIO:

GPIO_InitTypeDef GPIO_InitStruct;//GPIO初始化结构体
GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IPU;//将引脚模式配置为上拉输入
GPIO_InitStruct.GPIO_Pin=GPIO_Pin_14;//配置Pin14口
GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;//设置Pin14口的最大翻转速度为50Mhz(输入模式此项不起作用)
GPIO_Init(GPIOB,&GPIO_InitStruct);//配置B14口

关于输入模式得选择:

想要检测边沿 输入模式
低电平/下降沿 上拉输入
高电平/上升沿 下拉输入
高和低电平/双边沿 浮空输入/下拉输入/上拉输入

四:配置AFIO

我们使用GPIO_EXTILineConfig函数进行外部中断引脚选择
GPIO_EXTILineConfig函数定义:

/ * *
* @brief选择用作外部中断线的GPIO引脚。
* @param GPIO_PortSource:选择某个GPIO外设作为外部中断源。
*取值为GPIO_PortSourceGPIOx,其中x取值为(A..G)。
* @param GPIO_PinSource:指定要配置的外部中断线。
*取值为GPIO_PinSourcex,其中x可以是(0..15)。
* @retval无
* /
* void GPIO_EXTILineConfig(uint8_t GPIO_PortSource, uint8_t GPIO_PinSource)

现在我们配置AFIO:

GPIO_EXTILineConfig(GPIO_PortSourceGPIOB,GPIO_PinSource14);//选择B14口作为外部中断线

四:配置EXTI

配置EXTI函数:

/**
  * @brief  根据指定参数初始化EXTI外设
  * EXTI_InitStruct中的参数。
  * @param  EXTI_InitStruct: 指向EXTI_InitTypeDef结构体的指针
  *包含EXTI外设的配置信息。
  * @retval None
  */
void EXTI_Init(EXTI_InitTypeDef* EXTI_InitStruct)

EXTI_InitStruct结构体:

typedef struct
{
  uint32_t EXTI_Line;               /*!< 指定要配置的外部中断线。该参数可以是@ref EXTI_Lines的任意组合*/
  EXTIMode_TypeDef EXTI_Mode;       //指定外部中断线的响应模式
  EXTITrigger_TypeDef EXTI_Trigger; //指定外部中断的有效边沿
  FunctionalState EXTI_LineCmd;     //指定选择的外部中断线的新状态
 }
成员 可选参数
EXTI_Line EXTI_Line0至 EXTI_Line15//常规外部中断
EXTI_Line16//连接到PVD输出
EXTI_Line17//连接到RTC告警事件
EXTI_Line18//连接USB设备/USB OTG FS从暂停事件中唤醒
EXTI_Line19//连接到以太网唤醒事件
EXTI_Mode EXTI_Mode_Interrupt//中断模式
EXTI_Mode_Event//事件模式
EXTI_Trigger EXTI_Trigger_Rising//上升沿触发
EXTI_Trigger_Falling//下降沿触发
EXTI_Trigger_Rising_Falling//上升下降沿都触发
EXTI_LineCmd ENABLE//开启
DISABLE//关闭

配置NVIC:

配置优先级分组:
NVIC_PriorityGroupConfig函数定义:

/**
  * @brief  配置优先级分组: 抢占优先级和响应优先级.
  * @param  NVIC_PriorityGroup: 指定优先级分组比特长度。
  *   此参数可以是下列值之一:
  *     @arg NVIC_PriorityGroup_0: 0 位抢占优先级(0)
  *                                4 位响应优先级(0-15)
  *     @arg NVIC_PriorityGroup_1: 1 位抢占优先级(0-1)
  *                                3 位响应优先级(0-7)
  *     @arg NVIC_PriorityGroup_2: 2 位抢占优先级(0-3)
  *                                2 位响应优先级(0-3)
  *     @arg NVIC_PriorityGroup_3: 3 位抢占优先级(0-7)
  *                                1 位响应优先级(0-1)
  *     @arg NVIC_PriorityGroup_4: 4 位抢占优先级(0-15)
  *                                0 位响应优先级(0)
  * @retval None
  */
void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup)

现在我们配置中断优先级分组:

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//将中断优先级配置为NVIC_PriorityGroup_2

配置NVIC:
NVIC_Init函数定义:

/**
  * @brief 根据NVIC_InitStruct中的参数配置NVIC外设。
  * @param  NVIC_InitStruct: 指向NVIC_InitStruct结构体的指针
  * @retval None
  */
void NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct)

NVIC_InitStruct结构体:

typedef struct
{
  uint8_t NVIC_IRQChannel;                    //指定要启用或禁用的IRQ通道(对于完整的STM32设备IRQ通道列表,请参考stm32f10x.h文件)
  uint8_t NVIC_IRQChannelPreemptionPriority;  //指定IRQ通道的抢占优先级,这个参数可以是一个值,其取值范围由NVIC_PriorityGroupConfig函数决定
  uint8_t NVIC_IRQChannelSubPriority;         //指定IRQ通道的响应优先级,这个参数可以是一个值,其取值范围由NVIC_PriorityGroupConfig函数决定
  FunctionalState NVIC_IRQChannelCmd;         //指定是否启用在NVIC_IRQChannel中的IRQ通道
} NVIC_InitTypeDef;
成员 可选参数
NVIC_IRQChannel(STM32c8t6,EXTI的IRQ通道) EXTI0_IRQn//EXTI 线0中断
EXTI1_IRQn//EXTI 线1中断
EXTI2_IRQn//EXTI 线2中断
EXTI3_IRQn//EXTI 线3中断
EXTI4_IRQn//EXTI 线4中断
EXTI9_5_IRQn//EXTI 线5-9中断
EXTI15_10_IRQn//EXTI 线10-15中断
NVIC_IRQChannelPreemptionPriority 其取值范围由NVIC_PriorityGroupConfig函数决定
NVIC_IRQChannelSubPriority 其取值范围由NVIC_PriorityGroupConfig函数决定
NVIC_IRQChannelCmd ENABLE//启用
DISABLE//禁用

现在配置NVIC:

	NVIC_InitTypeDef NVIC_IinitStruct;//创建初始化结构体
	NVIC_IinitStruct.NVIC_IRQChannel=EXTI0_IRQn;//指定EXTI0_IRQn通道
	NVIC_IinitStruct.NVIC_IRQChannelCmd=ENABLE;//启用EXTI0_IRQn通道
	NVIC_IinitStruct.NVIC_IRQChannelPreemptionPriority=1;//将EXTI0_IRQn通道的抢占优先级设置为一
	NVIC_IinitStruct.NVIC_IRQChannelSubPriority=1;//将EXTI0_IRQn通道的响应优先级设置为一
	NVIC_Init(&NVIC_IinitStruct);//根据NVIC_IinitStruct中的参数配置NVIC

EXTI中断服务函数和标志位读取函数:

中断服务函数:
在STM32中,中断服务函数的函数名是指定的,以下是EXTI的全部中断服务函数函数名:

函数名 对应中断
EXTI0_IRQHandler EXTI线0中断
EXTI1_IRQHandler EXTI线1中断
EXTI2_IRQHandler EXTI线2中断
EXTI3_IRQHandler EXTI线3中断
EXTI4_IRQHandler EXTI线4中断
EXTI9_5_IRQHandler EXTI线9-5中断
EXTI15_10_IRQHandler EXTI线15-10中断

标志位读取函数:
EXTI_GetITStatus函数定义:

/**
  * @brief  检测指定外部中断线是否被挂起
  * @param  EXTI_Line: 指定要检测外部中断线
  *     @arg EXTI_Linex: 指定外部中断线,x可以为(0..19)
  * @retval 指定外部中断线的最新状态 (SET or RESET).
  */
ITStatus EXTI_GetITStatus(uint32_t EXTI_Line)

EXTI_ClearITPendingBit函数定义:

/**
  * @brief  清除指定外部中断线的挂起状态
  * @param  EXTI_Line: 指定要清除外部中断线
  *   该参数可以是EXTI_Linex的任意组合,其中x可以是(0..19)。
  * @retval None
  */
void EXTI_ClearITPendingBit(uint32_t EXTI_Line)

中断服务函数模板:

void 中断服务函数的函数名(void)
{
	if(EXTI_GetITStatus(EXTI_Line14)==SET)
	{
		//要进行的操作
		EXTI_ClearITPendingBit(EXTI_Line14);
	}
	
}

作者:冯雪娟_00

物联沃分享整理
物联沃-IOTWORD物联网 » STM32外部中断(EXTI)配置指南

发表评论