HAL_EXTI

张开发
2026/4/11 2:26:14 15 分钟阅读
HAL_EXTI
文章目录一、EXTI简介二、EXTI模块详解1、EXTI1.输入线2.边沿检测电路3.或门电路4.与门电路5.输出到NVIC6.与门电路7.脉冲发生器电路8.脉冲信号总结2、中断/事件线3、中断触发方式4、事件触发方式三、CudeMx配置EXTI1、配置GPIO引脚为中断模式2、配置触发方式3、配置上拉/下拉4、开启中断开关四、EXTI模块组成1、数据结构2、句柄3、实用API1. 初始化 GPIO EXTI自动配置中断线2. 中断服务函数固定写法3. 中断回调函数你写业务逻辑4. 清中断挂起标志5. 获取中断标志4、底层 EXTI 专用 API1. 配置 EXTI 线底层核心2. 获取挂起状态3. 清除挂起标志4. 失能 EXTI 线5. 使能 EXTI 线5、状态/错误1. 中断触发状态2. 常用判断方式3. 引脚电平状态五、EXTI模块应用实例1、中断实例PA0 按键下降沿中断翻转 PB5 LED1. 头文件 时钟使能2. GPIO 初始化EXTI 配置在这里3. 中断服务函数stm32f1xx_it.c 或 main.c 均可4. 中断回调函数核心业务逻辑5. 主函数2、EXTI 事件模式Event下降沿事件1. 功能说明2. GPIO 初始化事件模式关键3. 主函数WFE 等待事件4. 运行效果一、EXTI简介EXTIExternal interrupt/event controller—外部中断/事件控制器管理了控制器的20个中断/事件线。每个中断/事件线都对应有一个边沿检测器可以实现输入信号的上升沿检测和下降沿的检测。EXTI可以实现对每个中断/事件线进行单独配置 可以单独配置为中断或者事件以及触发事件的属性。二、EXTI模块详解1、EXTI1.输入线EXTI控制器有19个中断/事件输入线这些输入线可以通过寄存器设置为任意一个GPIO也可以是一些外设的事件。输入线一般是存在电平变化的信号。2.边沿检测电路根据上升沿触发选择寄存器(EXTI_RTSR)和下降沿触发选择寄存器(EXTI_FTSR)对应位的设置来控制信号触发。边沿检测电路以输入线作为信号输入端如果检测到有边沿跳变就输出有效信号1给编号3电路否则输出无效信号0。可以设置只有上升沿触发、只有下降沿触发或者上升沿和下降沿都触发。3.或门电路输入来自编号2电路另外一个输入来自软件中断事件寄存器(EXTI_SWIER)。 EXTI_SWIER允许我们通过程序控制就可以启动中断/事件线。 或门电路作用就是有1就为1。 这两个输入随便一个有有效信号1就可以输出1给编号4和编号6电路。4.与门电路一个输入是编号3电路另外一个输入来自中断屏蔽寄存器(EXTI_IMR)。门电路要求输入都为1才输出1 导致的结果是如果EXTI_IMR设置为0时那不管编号3电路的输出信号是1还是0最终编号4电路输出的信号都为0如果EXTI_IMR设置为1时 最终编号4电路输出的信号才由编号3电路的输出信号决定。5.输出到NVIC将EXTI_PR寄存器内容输出到NVIC内从而实现系统中断事件控制。6.与门电路一个输入来自编号3电路 另外一个输入来自事件屏蔽寄存器(EXTI_EMR)。如果EXTI_EMR设置为0时那不管编号3电路的输出信号是1还是0最终编号6电路输出的信号都为0如果EXTI_EMR设置为1时最终编号6电路输出的信号才由编号3电路的输出信号决定。7.脉冲发生器电路当它的输入端即编号6电路的输出端是一个有效信号1时就会产生一个脉冲如果输入端是无效信号就不会输出脉冲。8.脉冲信号脉冲信号可以给其他外设电路使用比如定时器TIM、模拟数字转换器ADC等。总结EXTI可分为两大部分功能一个是产生中断12345 另一个是产生事件 123678。2、中断/事件线EXTI有20个中断/事件线每个GPIO都可以被设置为输入线占用EXTI0至EXTI15。还有另外七根用于特定的外设事件。EXTI16-194根特定外设中断/事件线由外设触发。EXTI0-15用于GPIO通过编程控制可以实现任意一个GPIO作为EXTI的输入源。EXTI0可以通过AFIO的外部中断配置寄存器1(AFIO_EXTICR1)的EXTI0[3:0]位选择配置为PA0、 PB0、PC0、PD0、PE0、PF0、PG0、PH0或者PI0。3、中断触发方式输入 → 边沿检测 → 中断屏蔽 (IMR) → 挂起寄存器 (PR) → NVIC → CPU。CubeMXGPIO_EXTIx → Interrupt Mode必须开 NVIC 中断代码重写 HAL_GPIO_EXTI_Callback()External Interrupt Mode with Rising edge trigger detection具有上升沿触发检测的外部中断模式。External Interrupt Mode with Falling edge trigger detection具有下降沿触发检测的外部中断模式。External Interrupt Mode with Rising/Falling edge trigger detection具有上升/下降沿触发检测的外部中断模式。4、事件触发方式输入 → 边沿检测 → 事件屏蔽 (EMR) → 脉冲发生器 → 外设无 CPU、无挂起位。CubeMXGPIO_EXTIx → Event Mode不用开 NVIC代码不用写回调函数作用把引脚边沿变成硬件触发信号给 ADC/DMA/TIMExternal Event Mode with Rising edge trigger detection具有上升沿触发检测的外部事件模式。External Event Mode with Falling edge trigger detection具有下降沿触发检测的外部事件模式。External Event Mode with Rising/Falling edge trigger detection具有上升/下降沿触发检测的外部事件模式。三、CudeMx配置EXTI1、配置GPIO引脚为中断模式找到你要用的引脚比如 PA0选择GPIO_EXTI0数字对应中断线号2、配置触发方式点击该引脚 → GPIO mode配置为中断模式为下降沿触发。External Interrupt Mode with Falling edge trigger detection。3、配置上拉/下拉按键常用Pull-up 上拉没按下时是高电平按下变低。4、开启中断开关左边 System Core → NVIC。找到 EXTI line0 interrupt → 勾选 Enabled。优先级可以默认。四、EXTI模块组成1、数据结构EXTI_ConfigTypeDef配置结构体关键typedefstruct{uint32_tLine;// EXTI 线号EXTI_LINE_0 ~ EXTI_LINE_15uint32_tMode;// 模式中断 / 事件uint32_tTrigger;// 触发边沿uint32_tGPIOSel;// GPIO 端口选择PA~PI}EXTI_ConfigTypeDef;2、句柄EXTI_HandleTypeDefEXTI 句柄typedefstruct{EXTI_TypeDef*Instance;// EXTI 外设基地址EXTIEXTI_InitTypeDef Init;// 初始化配置兼容旧版uint32_tLine;// 当前配置的线号}EXTI_HandleTypeDef;3、实用API1. 初始化 GPIO EXTI自动配置中断线HAL_GPIO_Init(GPIOx, GPIO_InitStruct);作用配置引脚为 中断 / 事件模式自动映射 EXTI 线CubeMX 自动生成最常用2. 中断服务函数固定写法void HAL_GPIO_EXTI_IRQHandler(uint16_t GPIO_Pin);作用清中断标志 → 调用回调函数放在 it.c 文件里3. 中断回调函数你写业务逻辑void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin);EXTI 最重要 API所有引脚中断都进这里用 GPIO_Pin 判断来源4. 清中断挂起标志__HAL_GPIO_EXTI_CLEAR_IT(GPIO_Pin);5. 获取中断标志__HAL_GPIO_EXTI_GET_IT(GPIO_Pin);4、底层 EXTI 专用 API1. 配置 EXTI 线底层核心HAL_EXTI_SetConfigLine(EXTI_HandleTypeDef *hexti, EXTI_ConfigTypeDef *pExtiConfig);手动配置线号、模式、触发边沿、GPIO 端口2. 获取挂起状态HAL_EXTI_GetPending(EXTI_HandleTypeDef *hexti, uint32_t Edge);3. 清除挂起标志HAL_EXTI_ClearPending(EXTI_HandleTypeDef *hexti, uint32_t Edge);4. 失能 EXTI 线HAL_EXTI_DisableConfigLine(EXTI_HandleTypeDef *hexti);5. 使能 EXTI 线HAL_EXTI_EnableConfigLine(EXTI_HandleTypeDef *hexti);5、状态/错误1. 中断触发状态触发中 → PR 标志位置 1处理完 → 软件清除为 02. 常用判断方式// 判断是否触发中断if(__HAL_GPIO_EXTI_GET_IT(GPIO_PIN_0) ! 0)// 清除中断__HAL_GPIO_EXTI_CLEAR_IT(GPIO_PIN_0);3. 引脚电平状态GPIO_PinState state HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0);五、EXTI模块应用实例EXTI 本质 GPIO 引脚电平变化 → 触发硬件信号。这个信号有两条路走中断 → 叫醒 CPU执行代码。走事件 → 直接触发其他硬件CPU 不参与。1、中断实例PA0 按键下降沿中断翻转 PB5 LED1. 头文件 时钟使能#includestm32f1xx_hal.hvoidSystemClock_Config(void);staticvoidMX_GPIO_Init(void);2. GPIO 初始化EXTI 配置在这里staticvoidMX_GPIO_Init(void){// 1. 开时钟__HAL_RCC_GPIOA_CLK_ENABLE();__HAL_RCC_GPIOB_CLK_ENABLE();__HAL_RCC_SYSCFG_CLK_ENABLE();// EXTI 必须开GPIO_InitTypeDef GPIO_InitStruct{0};// PA0 配置为 EXTI 下降沿中断 GPIO_InitStruct.PinGPIO_PIN_0;GPIO_InitStruct.ModeGPIO_MODE_IT_FALLING;// 下降沿中断GPIO_InitStruct.PullGPIO_PULLUP;// 上拉HAL_GPIO_Init(GPIOA,GPIO_InitStruct);// PB5 配置为推挽输出 LED GPIO_InitStruct.PinGPIO_PIN_5;GPIO_InitStruct.ModeGPIO_MODE_OUTPUT_PP;GPIO_InitStruct.PullGPIO_NOPULL;GPIO_InitStruct.SpeedGPIO_SPEED_FREQ_LOW;HAL_GPIO_Init(GPIOB,GPIO_InitStruct);// NVIC 中断配置 HAL_NVIC_SetPriority(EXTI0_IRQn,1,0);HAL_NVIC_EnableIRQ(EXTI0_IRQn);}3. 中断服务函数stm32f1xx_it.c 或 main.c 均可voidEXTI0_IRQHandler(void){// 调用 HAL 库处理函数清标志 调回调HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_0);}4. 中断回调函数核心业务逻辑voidHAL_GPIO_EXTI_Callback(uint16_tGPIO_Pin){// 判断是不是 PA0 触发if(GPIO_PinGPIO_PIN_0){// 简单软件消抖HAL_Delay(20);if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0)0){// 翻转 LEDHAL_GPIO_TogglePin(GPIOB,GPIO_PIN_1);}}}5. 主函数intmain(void){HAL_Init();SystemClock_Config();MX_GPIO_Init();while(1){// 主循环空闲}}2、EXTI 事件模式Event下降沿事件1. 功能说明PA0 → 配置为 EXTI 事件模式下降沿事件按键拉低 PA0 → 产生 EXTI 硬件事件脉冲CPU 执行 __WFE() 进入睡眠事件到来自动唤醒 CPU唤醒后翻转 LEDPB1重点全程没有中断函数、没有回调、不进 ISR纯事件唤醒。2. GPIO 初始化事件模式关键#includestm32f1xx_hal.hvoidMX_GPIO_Init(void){__HAL_RCC_GPIOA_CLK_ENABLE();__HAL_RCC_GPIOB_CLK_ENABLE();__HAL_RCC_SYSCFG_CLK_ENABLE();// EXTI 必须开GPIO_InitTypeDef gpio_conf{0};// PA0EXTI 事件模式下降沿 gpio_conf.PinGPIO_PIN_0;gpio_conf.ModeGPIO_MODE_EVT_FALLING;// 事件不是 ITgpio_conf.PullGPIO_PULLUP;HAL_GPIO_Init(GPIOA,gpio_conf);// PB1LED 输出 gpio_conf.PinGPIO_PIN_1;gpio_conf.ModeGPIO_MODE_OUTPUT_PP;gpio_conf.PullGPIO_NOPULL;gpio_conf.SpeedGPIO_SPEED_FREQ_LOW;HAL_GPIO_Init(GPIOB,gpio_conf);}3. 主函数WFE 等待事件intmain(void){HAL_Init();SystemClock_Config();// 时钟配置MX_GPIO_Init();while(1){// 1. 进入等待事件模式睡眠__WFE();// 2. 事件到来CPU被唤醒执行下面HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_1);// 清除事件唤醒标记防止立刻再次唤醒__SEV();__WFE();}}4. 运行效果程序启动后进入 __WFE () 睡眠按下按键 → PA0 下降沿 → EXTI 产生事件脉冲事件脉冲唤醒 CPU唤醒后翻转 LED再次进入睡眠整个过程没有进入任何中断服务函数。

更多文章