14920| 1
|
[ESP32系列教程] ESP32 Arduino教程:外部中断 |
简介此esp32 arduino教程旨在解释如何使用ESP32开发板和Arduino核心处理外部中断。 测试是在一个集成在ESP32开发板中的DFRobot的ESP-WROOM-32设备上进行的。 设置代码首先我们将对该中断附加在全局变量上的引脚进行声明。请注意,根据您的ESP32开发板,ESP32微控制器的引脚编号和开发板标注的引脚编号可能不匹配。在FireeBeetle esp32开发板中,以下使用的引脚(数字引脚25)与标记为IO25/D2的引脚相互匹配。
此外我们还将对计数器进行声明,中断例程将使用该计数器与主循环函数进行通信,并发出中断已发生的信号。请注意,此变量需要声明为volatile(易失性),因为它将由ISR和主代码共享。否则,该变量可能会因编译器优化而将其删除。
此外,我们将声明一个计数器,对自程序启动后全局究竟出现多少次中断进行追踪。因此,每次发生中断时,此计数器都会递增。
最后,我们将声明一个portMUX_TYPE类型的变量,利用其对主代码和中断之间的同步进行处理。我们稍后会看到如何使用该变量。
转到设置功能,我们首先打开一个串行连接,以便能够输出我们程序的结果。
接下来,由于我们将使用外部引脚中断,我们需要将先前声明的引脚编号配置为输入引脚。为此,我们调用pinMode函数,将引脚编号和操作模式作为参数传递。
为了在引脚无电气信号输入时获悉输入状态,我们使用INPUT_PULLUP模式。因此,当无信号输入时,它将处于VCC电压等级而非处于浮动状态,以免检测到任何不存在的外部中断。 接下来,我们通过调用attachInterrupt函数将中断附加到引脚。作为首个参数,我们将调用结果传递给digitalPinToInterrupt函数,该函数将使用的引脚编号转换为相应的内部中断编号。 接下来,我们传递中断处理函数,换而言之,当指定引脚上出现中断时,该函数将予以执行。我们将其称为handleInterruptand,稍后再指定其代码。 最后我们传递中断模式,它基本指定了在引脚输入信号中哪种类型变化触发了中断。我们将使用FALLING,这意味着当在引脚上检测到从VCC到GND的变化时,中断将会发生。
最终的设置代码如下所示。
主循环现在我们将转到主循环。那里我们将简单检查中断计数器是否大于零。如果是,这意味着我们存在中断需要处理。 因此,如果出现中断,我们首先要注意递减该中断计数器,以发出中断已被检测到并将被处理的信号。 请注意,此计数器方法比使用标志更好,因为如果当主代码无法处理所有中断时,多个中断出现,我们将不会丢失任何事件。作为对比,如果我们使用一个标志,并且在没有主代码能够对其进行处理的情况下发生多个中断,那么标志值设置将在ISR中保持为真,并且主循环处理程序将仅解释为似乎仅发生了一次中断。 值得注意的是,其它重要事项还包括我们应该在写入与中断共享的变量时禁用中断。这样我们就可以确保主代码和ISR之间不存在任何对它的并发访问。 在Arduino环境中,我们通常使用NoInterrupts函数和Interrupts函数禁用和重启中断。尽管如此,在撰写本文时,这些功能尚未在ESP32 Arduino核心中予以实现(https://github.com/espressif/arduino-esp32/blob/master/cores/esp32/Arduino.h#L82-L85 )。 因此,我们使用portENTER_CRITICAL和portEXIT_CRITICAL宏进行声明,在临界区内执行变量递减。这些调用都接收先前声明的portMUX_TYPE全局变量的地址作为输入。
在负责递减计数器之后,我们现在将递增全局计数器,该计数器保存自程序开始以来检测到的中断数。由于中断服务程序不会访问它,因此不需要在临界区内增加此变量。 随后,我们将打印一条消息,指示已检测到中断以及到目前为止究竟发生了多少次中断。注意由于ISR旨在尽快执行,因此绝不应在中断服务程序内,完成向串行端口的数据发送。如果这样做,您很可能会遇到各种运行时问题。 这样在我们的体系结构中,ISR只负责发出中断发生的主循环的简单操作,然后主循环处理其余事项。 您可以查看以下完整的主循环代码。
中断处理函数为了结束代码运行,我们将声明我们的中断处理函数。如前所述,它只会对向主循环发出中断信号的全局变量递增行为进行处理。 我们还将此操作封装到关键环节,通过调用portENTER_CRITICAL_ISR和portExit_CRITICAL_ISR宏对该环节进行声明。它们还接收portMUX_TYPE全局变量地址作为输入。 这是必需的,因为我们将要使用的变量也通过主循环进行更改,如前所述,我们需要防止并发访问问题。
中断处理函数的完整代码如下所示。 最终的代码最终的源代码如下所示。您可以将其复制并粘贴到Arduino环境中进行测试。
测试代码如需测试代码,只需将其上传到ESP32并打开Arduino IDE串行监视器即可。触发中断的最简单方法是使用电线连接,并断开中断连接到GND的数字引脚。 由于引脚被声明为INPUT_PULLUP,因此这将触发从VCC到GND的转换,并将检测到外部中断。请务必保持谨慎,以免将接地引脚连接到错误的GPIO,并造成整个电路板的损坏。 您应该获得类似图1的输出,该输出显示正在触发的中断和正在打印的全局计数器。 图1 - 中断处理程序输出。 注:本文作者是Nuno Santos,他是一位和蔼可亲的电子和计算机工程师,住在葡萄牙里斯本 (Lisbon)。 查看更多ESP32/ESP8266教程和项目: |
© 2013-2024 Comsenz Inc. Powered by Discuz! X3.4 Licensed