Arduino项目多标签页下如何在主标签调用A、B标签中定义的中断
Arduino多标签页中断调用可行方案
前置逻辑说明
- Arduino IDE会自动将同项目下所有
.ino后缀的标签页内容,按主文件优先、其余按文件名排序的规则拼接为完整源文件再编译,所有标签页的全局定义、函数默认全局可见,无需额外声明即可跨标签调用。 - 注意:中断服务函数(ISR)由硬件触发自动执行,无法主动手动调用,你只需要在主文件中完成中断初始化配置,触发后对应ISR会自动执行。
具体实现步骤
1. 子标签页规范写法
以A标签页(A.ino)为例,B标签页逻辑一致:
// A.ino 子标签页代码 // 中断关联的全局变量必须加volatile修饰,避免编译器优化导致值不同步 volatile uint8_t a_interrupt_flag = 0; // 中断服务函数,触发后自动执行,内部不要放耗时操作 void A_interrupt_handler() { a_interrupt_flag = 1; } // 封装A模块的中断初始化接口,供主文件调用 void init_A_interrupt() { pinMode(2, INPUT_PULLUP); // 直接将本页定义的中断处理函数作为参数传入注册接口即可 attachInterrupt(digitalPinToInterrupt(2), A_interrupt_handler, FALLING); } // 封装中断标志读取接口,避免主文件直接操作volatile变量 uint8_t check_A_interrupt() { noInterrupts(); // 读取前关中断,避免值被中途修改 uint8_t res = a_interrupt_flag; a_interrupt_flag = 0; interrupts(); // 读取完成后恢复中断 return res; }
2. 主标签页调用逻辑
// 主标签页代码 void setup() { Serial.begin(115200); // 直接调用两个子页的初始化接口完成中断注册 init_A_interrupt(); init_B_interrupt(); } void loop() { // 轮询检查中断触发状态,执行业务逻辑 if(check_A_interrupt() == 1) { Serial.println("A模块中断触发"); // 此处写A中断对应的业务处理逻辑 } if(check_B_interrupt() == 1) { Serial.println("B模块中断触发"); // 此处写B中断对应的业务处理逻辑 } }
踩坑提示
- 同一个中断向量只能注册一个处理函数,不要在A、B两个子页中注册同一个引脚的中断,否则会编译报错。
- 中断服务函数内禁止使用
delay()、串口打印等耗时操作,尽量只做标志位修改,业务逻辑统一放到主循环执行。 - 如果使用原生
ISR(xxx_vect)宏定义中断,不需要再调用attachInterrupt()注册,二者二选一即可。
内容的提问来源于stack exchange,提问作者pat des pat
相关产品推荐
相关产品推荐

