ESP32的电容touch和外部中断
代码编写
#include <Arduino.h>
#define EXT_ISR_MODE 0
void TouchEvent()
{
Serial.printf("Touch Event.\r\n");
}
void PinIntEvent()
{
Serial.printf("PinInt Event.\r\n");
}
void setup()
{
Serial.begin(115200);
#if 1 == EXT_ISR_MODE
touchAttachInterrupt(T0, TouchEvent, 40);
#elif 2 == EXT_ISR_MODE
pinMode(0, INPUT_PULLUP);
attachInterrupt(0, PinIntEvent, FALLING);
#endif
}
void loop()
{
#if 0 == EXT_ISR_MODE
Serial.printf("touch:%d\r\n", touchRead(T0));
#endif
delay(200);
}
定义外部中断的模式:
-
如果EXT_ISR_MODE = 0,也就是无中断,程序会在setup()函数中初始化完串口后,使用Serial.printf()函数打印返回GPIO4引脚电容传感器的值 -
如果EXT_ISR_MODE = 1,在setup函数中初始化串口后,会触发touchAttachInterrupt,其中设置一个阈值是40,如果低于40则触发Touch中断,调用TouchEvent事件,打印输出"Touch Event" -
如果EXT_ISR_MODE = 2,将0号引脚设置为上拉输入模式,将0号引脚设置为下降沿触发,当由高电平到低电平的过程中会触发一个外部中断attachInterrupt,调用PinIntEvent事件,打印输出"PinInt Event"
代码剖析
Serial.begin(115200);
可以查看这行代码的定义:
void HardwareSerial::begin(unsigned long baud, uint32_t config, int8_t rxPin, int8_t txPin, bool invert, unsigned long timeout_ms, uint8_t rxfifo_full_thrhd);
可以看到这行代码的begin函数其实是HardwareSerial类中的一个成员函数: 这里的HardwareSerial 库是c++编写的,应用于esp32 Arduino应用环境的串口驱动库,我们在安装好ESP32的Arduino开发环境后就已经集成了这个串口操作库,在实际应用时直接引用就可以了。 HardwareSerial 在声明一个对象的时候,首先调用带参的构造函数:
HardwareSerial(int uart_nr);
将串口的值传入进去,可以传入0 1 2 分别代表Serial、Serial1、Serial2。 声明对象后就可以按一般串口的方法使用了:
void HardwareSerial::begin(unsigned long baud, uint32_t config, int8_t rxPin, int8_t txPin, bool invert, unsigned long timeout_ms, uint8_t rxfifo_full_thrhd);
baud:串口波特率,该值写0则会进入自动侦测波特率程序;
config:串口参数,默认SERIAL_8N1为8位数据位、无校验、1位停止位;
rxPin:接收管脚针脚号;
txPin:发送管脚针脚号;
invert:翻转逻辑电平,串口默认高电平为1、低电平为0;
timeout_ms:自动侦测波特率超时时间,如果超过该时间还未获得波特率就不会使能串口;
- Serial.printf()函数说明
由于HardwareSerial.h中引入了Stream.h,Stream.h中引入了 Print.h,Print.h中有被public修饰的printf()函数 Serial.printf()和Serial.print()是从串行端口打印数据 Serial.println()是从串口打印数据并且回车换行 - touchAttachInterrupt()函数说明:
touchAttachInterrupt(T0, TouchEvent, 40);
上面的这条语句T0代表的是GPIO4 当低于阈值40的时候,ESP32会触发touchAttachInterrupt()中断函数,紧接着调用TouchEvent()函数。 可以查看touchAttachInterrupt具体的函数定义:
void touchAttachInterrupt(uint8_t pin, void (*userFunc)(void), uint16_t threshold);
attachInterrupt(0, PinIntEvent, FALLING);
将0号引脚设置为下降沿触发attachInterrupt中断,当attachInterrupt中断触发时会调用PinIntEvent()函数。 attachInterrupt函数定义如下:
void attachInterrupt(uint8_t pin, std::function<void(void)> intRoutine, int mode)
touchRead(T0);
返回指定引脚电容传感器的值 具体的函数定义如下:
uint16_t touchRead(uint8_t pin);
|