ESP32 提供了三个工作在 3.3V TTL 电平的通用同步接收器和发送器 (UART) 端口,例如 UART0、UART1 和 UART2。这三个串行接口是硬件支持的。它们每个都暴露 4 个引脚:RX、TX、RTS 和 CTS。然而,Arduino IDE 仅使用 RX 和 TX 引脚。
默认情况下,只能使用 UART0 和 UART2。要使用 UART1,我们必须重新定义引脚,因为 UART1 的默认引脚(例如 GPIO9 和 GPIO10)在内部连接到 SPI 闪存。此外,在某些 ESP32 板上,它们甚至暴露在引出线头上。因此,如果不在 Arduino IDE 中重新分配管脚,我们不能直接使用 UART1。
下表指定了 ESP32 中可用的三个 UART 端口中每个端口的 RX 和 TX 引脚。
UART序号 | Rx PIN | Tx PIN | 是否可用 |
UART0 | GPIO3 | GPIO1 | 是 |
UART1 | GPIO9 | GPIO10 | 是, 但与SPI flash相关联需要重新定义 |
UART2 | GPIO16 | GPIO17 | 是 |
如上图所示,几乎所有资料都显示串口1的IO是GPIO9和10,,串口2使用的是GPIO16和17.如果你是用2.x的SDK这些都是对的,但是从ESP32的SDK升级到3.0以来,串口1和串口2的默认引脚就被更换了。
下面我们来看一下SDK的版本差异,uart1的默认引脚改变了
v2.x
v3.0.x
同样,uart2的默认引脚也改变了
v2.x
自从3.0.x开始,被配置到GPIO4,25.
其实ESP32可以更改串口的引脚。您几乎可以将任何引脚分配给任何串行端口的 TX 和 RX 信号,但有一些限制:任何 GPIO 引脚都可以用作串行 RX,但只有 GPIO0 和 GPIO31 之间的引脚可以用作 TX。
我先展示一个串口0的例子,这个例子非常简单,也非常常用。
void setup() {
// 初始化串口通信,波特率设置为9600
Serial.begin(9600);
Serial.println("串口已打开,请输入数据...");
}
void loop() {
// 检查是否有数据可读
if (Serial.available() > 0) {
// 读取串口数据
char incomingByte = Serial.read();
// 打印接收到的数据
Serial.print("接收到的数据: ");
Serial.println(incomingByte);
// 将接收到的数据发送回去(回显)
Serial.print("回显: ");
Serial.println(incomingByte);
}
}
下面举例写一个重映射串口1的例子
void setup() {
// 初始化串口1通信,波特率设置为9600
Serial1.begin(9600, SERIAL_8N1, 18, 19);
Serial.println("串口已打开,请输入数据...");
}
void loop() {
// 检查是否有数据可读
if (Serial1.available() > 0) {
// 读取串口数据
char incomingByte = Serial1.read();
// 打印接收到的数据
Serial1.print("接收到的数据: ");
Serial1.println(incomingByte);
// 将接收到的数据发送回去(回显)
Serial1.print("回显: ");
Serial1.println(incomingByte);
}
}
串口2和串口1的使用方法完全一致。
参考
ESP32 串口不够用?硬串口重定义,解锁UART1串口 – 凌顺实验室 (lingshunlab.com)
使用 Arduino IDE 访问 ESP32 UART0、UART1、UART2 - Copperhill (copperhilltech.com)
使用Arduino开发ESP32(02):串口(Serial port)使用说明-优快云博客
arduino-esp32/cores/esp32/HardwareSerial.h at release/v2.x · espressif/arduino-esp32 · GitHub