使用CubeMX新建EXTI外部中断工程——不使用回调函数
具体的使用CubeMX新建工程的步骤看这里:STM32CubeMX学习笔记(3)——EXTI(外部中断)接口使用_cubemx exti-CSDN博客
之前一直都是在看野火的视频没有亲手使用CubeMX生成工程,而且野火给的例程代码框架和自动生成的框架也不一样,原本想着对比着例程应该不会多难,但是动手实践下来还是有很多问题的,光看视频确实没有动手操作更能帮助理解。
1、使用CubeMX生成的是外设的初始化代码,应用代码需要自己加上。
本实验使用CubeMX生成的GPIO部分都在一个文件中,不管是接收中断信号的引脚PA0,PC13还是控制LED灯的引脚PB0,PB1,配置模式和初始化都在gpio.c这一个文件中,这与例程分别放在bsp_led.c和bsp_exti.c文件中不同,反正我目前是直接用了,没有新建板级支持包。
bsp_led.c文件放LED灯对应的引脚PB0 PB1的初始化。
bsp_exti.c文件放KEY对应的引脚PA0 PC13的EXTI模式和初始化。
应用代码部分就是在中断服务函数那里让LED翻转的程序。
2、整体流程就是按下按键产生中断跳转到对应中断服务函数中执行里面的程序
所以就是按键1对应引脚PA0,按下后产生中断跳转到中断服务函数执行使PB0电平反转的操作,对应的绿灯翻转。按键2同样。
3、在中断服务函数里面执行的程序
if(__HAL_GPIO_EXTI_GET_IT(GPIO_PIN_0) != RESET) {// LED1 取反 digitalToggle(GPIOB,GPIO_PIN_0);//清除中断标志位__HAL_GPIO_EXTI_CLEAR_IT(GPIO_PIN_0); }
先判断是否产生中断,然后对应引脚电平取反,清除中断标志位
问题1:
不清楚__HAL_GPIO_EXTI_GET_IT(GPIO_PIN_0)功能
-
__HAL_GPIO_EXTI_GET_IT(GPIO_PIN_0)
只能检查 EXTI 线 0 是否触发了中断,无法区分具体是哪个端口的引脚(如 PA0 或 PB0)。 -
如果需要判断是否是 PA0 触发的中断,必须结合
HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0)
来读取 PA0 的电平状态。 -
在初始化时,确保 EXTI 线 0 只连接到 PA0,避免其他引脚干扰。
问题2:
需要定义:#define digitalToggle(p,i) {p->ODR ^=i;} //输出翻转状态
4、使用库函数
HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_0); 可以代替digitalToggle(p,i) 。
5、与使用回调函数的写法相比:
中断服务程序(ISR)通常是一个单独的函数,所有的中断逻辑都在这个函数内部实现。这种方式比较直接,适合简单的应用场景。
-
解耦设计:通过使用回调函数,可以将具体的中断处理逻辑从ISR中分离出来,ISR只需要负责调用相应的回调函数。这样做的好处是可以根据需要灵活地定义和修改中断处理逻辑,而无需更改ISR本身。
-
提高模块化和复用性:每个中断事件对应的处理逻辑都可以被封装成独立的回调函数,这不仅提高了代码的模块化程度,还使得这些处理逻辑可以在不同场景下重复利用。
-
增强灵活性:可以根据不同的条件或状态动态设置不同的回调函数,从而实现更加灵活的中断处理策略。
-
简化ISR:ISR变得更加简洁,主要职责是检查中断源并调用相应的回调函数。这样可以缩短ISR执行时间,减少对系统实时性的负面影响。
-
更好的实时响应:因为ISR的工作量减少,可以更快地响应中断事件,对于对时间敏感的应用来说非常重要。
总的来说,使用中断回调函数可以使你的中断处理机制更加灵活、易于管理和扩展,同时也能提高系统的响应速度和整体性能。而不使用回调函数的方式则较为直接简单,适用于中断处理逻辑相对简单固定的场景。选择哪种方式取决于具体的应用需求和项目复杂度。