野火STM32_HAL库版课程笔记-外部中断应用与回调函数

野火STM32_HAL库版课程笔记-外部中断应用与回调函数 外部中断芯片外部的 GPIO 输入中断, 通过检测 GPIO 的输入变化, 来产生中断或者是事件请求的外设模块.EXTI 简介EXTIExternal interrupt/event controller—外部中断/事件控制器管理了控制器的20 个中断/事件线。每个中断/事件线都对应有一个边沿检测器可以实现输入信号的上升沿检测和下降沿的检测。EXTI 可以实现对每个中断/事件线进行单独配置可以单独配置为中断或者事件以及触发事件的属性。中断/事件线中断优先级抢占优先级决定了一个中断能否打断正在执行的其他中断即“插队”响应优先级当多个中断的抢占优先级相同时决定了它们的执行顺序即“排队”两者都是数值越小, 优先级越高. (先看抢占优先级, 再看响应优先级)主要区别是: 抢占优先级高可以打断其他中断, 而响应优先级高并不能打断其他中断.上面的表格主要就是说明有 5 种优先级的分组方式不同的分组方式, 其抢占优先级与响应优先级能够设置的级别不同.(设置抢占级别多, 响应能设置的级别就少了, 反之亦然)外部中断/事件控制器框图图中的 20 , 表示 20 个中断/事件线输入线就是中断的输入信号进入,经过边沿检测电路(设置的 上升沿 or 下降沿 触发)然后经过 ③ 或门, 该或门的两个来源分别为: 软件中断事件寄存器, GPIO 引脚边沿检测.然后继续向左, 通过请求挂起寄存器.请求挂起寄存器用来记录某个中断事件已经发生, 但还没被处理的标志寄存器.(告诉 CPU 这里产生了一个中断, 需要处理, 就会在对应的寄存器中对应位写 1, 表示中断挂起了, 等待 CPU 处理.当 CPU 知道之后就会手动清除这个挂起位, 表示该中断已经在处理, 可以将该标志清除. 否则会一直挂起, CPU 也会一直处理)再向做, 经过 ⑥ 与门 (两个输入都有效, 才会输出), 当已经成功挂起, 并且通过一个事件屏蔽寄存器(控制是否允许某条中断线/事件线产生中断或事件, 即允不允许中断产生, 如果允许, 在寄存器中通常设置为 1).然后在经过 ⑦ 脉冲发生器来触发事件.而当配置的是触发中断, 则经过的是 ④ 与门, 同样经过挂起寄存器已经挂起 并且中断屏蔽寄存器允许产生中断, 两个信号有效. 经过与门产生信号至 NVIC 中断控制器中, 产生中断.回调函数应用回调函数的作用 ——HAL_GPIO_EXTI_Callback ()回调函数是什么回调函数是用户定义的函数由库函数在特定事件发生时自动调用。HAL_GPIO_EXTI_Callback() 是 HAL库提供的 GPIO 外部中断回调函数。为什么要用回调函数把中断触发和业务逻辑分开结构更清晰。多个引脚共用一个回调函数方便集中管理多个中断来源项目配置GPIO 配置使用核心板上 KEY1 作为外部中断输入, 其对应引脚为 PA0设置 PA1, PA2, PA3 对应核心板上三个 LED 灯, 默认电平为高 (灯灭)设置 PA0 为 GPIO_EXTI0, GPIO mode 为External Interrupt Rising edge trigger detection(外部中断上升沿(低电平变高电平) 触发检测)NVIC 配置首先, 使能 EXTI0l, 点击右侧复选框勾选即可.设置优先级分组这里选择第四个优先级分组, 因为现在只用到这一个中断, 也用不到响应优先级. 所以随意, 其他选项默认代码部分这个函数在 EXTI0_IRQHandler - HAL_GPIO_EXTI_IRQHandler 中被调用这里 HAL_GPIO_EXTI_IRQHandler 对应的是检测我们指定引脚的中断挂起标志是否被设置.也就是表示该引脚确实触发了中断, 就会调用这个 HAL_GPIO_EXTI_Callback 回调函数. (并且清除标志)HAL_GPIO_EXTI_Callback这里的HAL_GPIO_EXTI_Callback是一个弱定义函数, 该函数是用户自定义的.以方便我们在别的地方编写一个函数来覆盖它.该函数的参数也是 GPIO_Pin, 也就是引脚, 那么我们就可以在这个函数里判断传入的引脚是哪一个引脚.通过区分引脚来做出对应的中断反应.这里的UNUSED(GPIO_Pin);是如果在函数中没有用到参数, 编译器会有警告 (参数没有被使用) .使用这个函数就可以消除编译器的这个警告.当我们在其他地方编写好这个函数之后, 当外部中断触发时, 就会自动调用该回调函数, 来执行对应的代码.在 USER CODE BEGIN 4 处定义这个函数. 并编写业务逻辑代码 (外部中断触发按键亮灭灯)/* USER CODE BEGIN 4 */ /** * brief EXTI line detection callbacks. * param GPIO_Pin: Specifies the pins connected EXTI line * retval None */ void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) { if (GPIO_Pin KEY1_EXTI0_Pin) // 触发外部中断的是对应的 KEY1 的引脚 | 中断来源是按键1 { // 切换红, 绿, 蓝三个LED灯的状态 (灭-亮, 亮-灭) HAL_GPIO_TogglePin(GPIOA, LED_R_Pin | LED_G_Pin | LED_B_Pin); } } /* USER CODE END 4 */