Skip to content

EXTI

EXTI外设简介

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

中断事件与中断线

中断/事件线 输入源
EXTI0 PX0(X可为A,B,C,D,E,F,G,H,I)
EXTI1 PX1(X可为A,B,C,D,E,F,G,H,I)
EXTI2 PX2(X可为A,B,C,D,E,F,G,H,I)
EXTI3 PX3(X可为A,B,C,D,E,F,G,H,I)
EXTI4 PX4(X可为A,B,C,D,E,F,G,H,I)
EXTI5 PX5(X可为A,B,C,D,E,F,G,H,I)
EXTI6 PX6(X可为A,B,C,D,E,F,G,H,I)
EXTI7 PX7(X可为A,B,C,D,E,F,G,H,I)
EXTI8 PX8(X可为A,B,C,D,E,F,G,H,I)
EXTI9 PX9(X可为A,B,C,D,E,F,G,H,I)
EXTI10 PX10(X可为A,B,C,D,E,F,G,H,I)
EXTI11 PX11(X可为A,B,C,D,E,F,G,H,I)
EXTI12 PX12(X可为A,B,C,D,E,F,G,H,I)
EXTI13 PX13(X可为A,B,C,D,E,F,G,H,I)
EXTI14 PX14(X可为A,B,C,D,E,F,G,H,I)
EXTI15 PX15(X可为A,B,C,D,E,F,G,H,I)
EXTI16 PVD输出
EXTI17 RTC闹钟事件
EXTI18 USB唤醒事件
EXTI19 以太网唤醒事件(只适用互联型)

AFIO引脚复用

image-20240916233559097

中断相关概念

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

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

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

image-20240916233233740

NVIC优先级分组

  • NVIC的中断优先级由优先级寄存器的4位(0~15)决定,这4位可以进行切分,分为高n位的抢占优先级和低4-n位的响应优先级
  • 抢占优先级 高的可以中断嵌套,**响应优先级**高的可以优先排队,抢占优先级和响应优先级均相同的按中断号排队
分组方式 抢占优先级 响应优先级
分组0 0位,取值为0 4位,取值为0~15
分组1 1位,取值为0~1 3位,取值为0~7
分组2 2位,取值为0~3 2位,取值为0~3
分组3 3位,取值为0~7 1位,取值为0~1
分组4 4位,取值为0~15 0位,取值为0

STM32CubeMX>中对应 抢占优先级响应优先级 参数配置

image-20240919222424896

STM32CubeMX配置

EXTI配置

image-20240919222942930

NVIC优先级配置

image-20240919223855861

代码介绍

中断触发函数介绍

stm32f1xx_it.c文件找到中断触发函数,内容如下

/**
  * @brief This function handles EXTI line4 interrupt.
  */
void EXTI4_IRQHandler(void)
{
  /* USER CODE BEGIN EXTI4_IRQn 0 */

  /* USER CODE END EXTI4_IRQn 0 */
  HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_4);
  /* USER CODE BEGIN EXTI4_IRQn 1 */

  /* USER CODE END EXTI4_IRQn 1 */
}

HAL_GPIO_EXTI_IRQHandler调用的函数内容,如下

/**
  * @brief  This function handles EXTI interrupt request.
  * @param  GPIO_Pin: Specifies the pins connected EXTI line
  * @retval None
  */
void HAL_GPIO_EXTI_IRQHandler(uint16_t GPIO_Pin)
{
  /* EXTI line interrupt detected */
  if (__HAL_GPIO_EXTI_GET_IT(GPIO_Pin) != 0x00u)
  {
    __HAL_GPIO_EXTI_CLEAR_IT(GPIO_Pin);
    HAL_GPIO_EXTI_Callback(GPIO_Pin);
  }
}

判断是否触发中断,即不为0x00u则触发中断

__HAL_GPIO_EXTI_GET_IT(GPIO_Pin) != 0x00u

清除触发中断的 标志位

__HAL_GPIO_EXTI_CLEAR_IT(GPIO_Pin);

这是一个“弱”回调函数,提供用户可以在自己的代码中重写函数,所以我们需要重写这个函数实现业务

HAL_GPIO_EXTI_Callback(GPIO_Pin);

编写回调函数

这个函数位置可以放在stm32f1xx_it.cmain.c均可

void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)  
{  
  if (GPIO_Pin == GPIO_PIN_0)  
  {  
    // 假设LED连接在GPIOB的第0个引脚上,并且初始状态是关闭的  
    HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_0); // 翻转LED的状态  
  }  
}