ESP32 串口不够用?硬串口重定义,解锁UART1串口

实验效果

在本示例中,凌顺实验室(lingshunlab.com)将使用 Arduino IDE 的 UART 硬件库,重新定义UART的串口引脚。在以前我们可能会使用软串口库(espsoftwareserial),解决串口不够的使用场景,但由于软串口的性能相比硬串口还是弱了一些。而一个ESP32中,是有3个硬串口的,但是其中UART1串口的PIN引脚,我们无法正常使用。重新定义UART1的串口引脚,可以让我们完全的解锁ESP32的三个硬串口。

串口的介绍

UART(Universal Asynchronous Receiver / Transmitter)是一种通用的异步收发器,是一种用于连接一个计算机与另一个设备的接口,用于在它们之间传输数据。 UART 使用两根不同的数据线,一根用于发送数据(TX),另一根用于接收数据(RX)。UART 一般与其它外围设备(如鼠标、打印机和外部存储设备)连接,允许从计算机发送和接收数据。 UART 是一种可配置的接口,允许用户配置各种通信参数,如传输速率(称为波特率)、数据位数、奇偶校验、停止位和流控制。UART 也可以采用其它的通信协议,比如 RS-232 、 RS-422 和 RS-485 。

可参考Arduino的串口例程:
Arduino 串口发送与接收应用小实例
Arduino Uno 使用串口 控制舵机角度

ESP32 的默认串口

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

ESP32引脚参考大全:
https://lingshunlab.com/book/esp32/esp32-pinout-reference

代码提点

1,加载「HardwareSerial.h」硬串口库

#include <HardwareSerial.h>

2,创建一个HardwareSerial实例对象

HardwareSerial SerialPort(1); // use UART1

3,初始化SerialPort

在void setup中初始化「SerialPort」

// 初始化串口,并重新定义引脚 
// 参数包括串行通信的波特率、串行模式、使用的 RX 引脚和 TX 引脚。
SerialPort.begin(15200, SERIAL_8N1, 4, 2); 

如果使用 UART1,我们将按如下方式对其进行初始化:

这里需要注意的重要一点是,作为 UART1 TX 和 RX 引脚的一部分的 GPIO 引脚 9 和引脚 10 在内部连接到闪存。此外,这些引脚在 ESP32 开发板上也不可用。因此,我们必须重新分配 UART1 的引脚以进行串行通信。幸运的是,ESP32 开发板能够使用几乎所有 GPIO 引脚进行串行连接。这里我们将 GPIO4 重新分配为 RX 引脚,将 GPIO2 重新分配为 TX 引脚。

4,使用SerialPort

在代码的其他地方,如果使用Serial的方法一样使用自定义的硬串口SerialPort,同样具有read,wirte,print,printle等等的串口方法和属性。

...
// 和其他串口使用方法一样,可以read,write,print
SerialPort.println("hello lingshunlab.com");
...

完整代码

// welcome to lingshunlab.com

#include <HardwareSerial.h> // 加载库

HardwareSerial SerialPort(1); // 使用UART1

void setup()  
{
  //初始化串口,并重新定义引脚 
  // 参数包括串行通信的波特率、串行模式、使用的 RX 引脚和 TX 引脚。
  SerialPort.begin(115200, SERIAL_8N1, 4, 2); 
}

void loop()
{
  ...
  // 和其他串口使用方法一样,可以read,write,print
  SerialPort.println("hello lingshunlab.com");
  ...
}

参考:

ESP32 UART通信示例 说明
https://microcontrollerslab.com/esp32-uart-communication-pins-example/

软串口:
https://github.com/plerup/espsoftwareserial