已写文章链接
本专栏主要内容是记录基于ESP32的开发工作,包括介绍 ESP32 基础知识、开发环境搭建、基础外设使用、蓝牙、WiFi 、与微信小程序联动等知识,达到自己动手做一些智能硬件的目的。
开发过程中主要参考官方资料,包括官网、规格书、参考手册、编程指南、驱动包等。
本专栏适合对ESP32感兴趣,想要找一个简单入手教程的同学。
ESP32 基础知识(已完成)
开发环境搭建(已完成)
(2-1)开发环境搭建(基于Arduino)
(2-2)开发环境搭建(基于VS Code+PlatformIO)
(2-3)开发环境搭建(基于ESP-IDF软件)
基础外设使用(已完成)
(3-1)基础外设使用(GPIO)
(3-2)基础外设使用(USART)
蓝牙(已完成)
WiFi(已完成)
微信小程序(已完成)
本章会介绍一下 USART 的基础知识,以及给出基于 USART 打印和收发数据的案例。
硬件和软件版本
本文章使用的软硬件版本如下。
硬件
- 开发板:ESP32-DevKitC-32E
- 模组:ESP32-WROOM-32E
- 芯片:ESP32-DOWD-V3
软件
- 开发环境:Arduino IDE V2.2.1
- ESP32 软件包:V2.0.11
USART 基础知识
USART 的定义
以下定义来自于 ChatGPT。
USART代表通用同步/异步收发器(Universal Synchronous/Asynchronous Receiver/Transmitter)。它是一种用于串行通信的通信协议和硬件接口,常见于微控制器和嵌入式系统中,用于设备之间的数据传输。
USART通常包含以下参数:
- 波特率(Baud Rate):波特率是指每秒传输的位数,用于表示数据传输速度。它定义了通信信号变化的速率,常见的波特率有9600、19200、115200等。两个通信设备之间必须使用相同的波特率进行通信,否则数据会出现错误。
- 数据位数(Data Bits):表示每个数据字节中实际的数据位数,通常为8位或者更少。
- 停止位(Stop Bits):停止位指定了数据字节之后的空闲时间。通常为1或2个停止位。
- 校验位(Parity Bit):校验位用于验证数据在传输过程中是否出现错误。常见的校验方式包括偶校验、奇校验、无校验等。校验位可以用于检测数据传输的错误。
USART通常用于以下场合:
- 串行通信:USART可用于设备之间的串行通信,例如单片机和外部传感器、存储设备或其他嵌入式系统之间的通信。
- 数据传输:它可以用于传输数据、指令、配置信息等,对于需要在设备之间进行可靠、快速数据传输的应用很有用。
- 调试和通信:USART通常用于微控制器的调试、与计算机进行通信以及设备与外部控制器之间的实时数据传输。
在使用USART时,需要确保通信双方的设置(波特率、数据位、停止位、校验位)匹配,并且需要在软件中配置USART寄存器和相应的控制程序来实现数据的发送和接收。USART是一种灵活、广泛应用的串行通信接口,可用于多种嵌入式系统中。
ESP32 的 USART 介绍
通用异步接收器/发送器 (UART) 属于一种硬件功能,通过使用 RS232、RS422、RS485 等常见异步串行通信接口来处理通信时序要求和数据帧。UART 是实现不同设备之间全双工或半双工数据交换的一种常用且经济的方式。
ESP32 芯片有 3 个 UART 控制器(也称为端口),每个控制器都有一组相同的寄存器以简化编程并提高灵活性。
每个 UART 控制器可以独立配置波特率、数据位长度、位顺序、停止位位数、奇偶校验位等参数。所有具备完整功能的 UART 控制器都能与不同制造商的 UART 设备兼容,并且支持红外数据协会 (IrDA) 定义的标准协议。
硬件连接
上面说了 ESP32 有 3 个串口,我们假定用于下载程序的串口为 USART0,测试用的为 USART1。此处纯为了区分,ESP32 内部无此定义。
默认串口(USART0)
上图中有一个用于供电、通信的串口。
从电脑端开始看,USB 电平信号(D+、D-)与 TTL 电平信号(RX、TX)接在了电平转换芯片 CP2102 上,完成了两种不同电平的转换。
从接口芯片出来的 RXD 和 TXD 信号经过 0 欧电阻接到了 RXD0、TXD0。RXD0、TXD0 就是下面框图中的 GPIO3 和 GPIO1。
测试用串口(USART1)
GPIO 的章节写了 ESP32 的 USART 外设是支持自定义引脚的(默认启动的 USART 除外),那我们就试试不同的引脚。
引脚连接如下图。将 ESP32 的 GPIO19 配置为 USART_TX,将 GPIO18 配置为 USART_RX,将其分别接到 USB 转 TTL 模块的 RXD 和 TXD。再将 USB 转 TTL 模块接到电脑端即可。
❗记得 ESP32 开发板和 USB 转 TTL 模块要共地(将两个模块地线接一起)。
将下载串口和测试串口都连接到电脑,此时电脑有两个串口,如下。下载调试串口我们用Arduino
中的串口监视器打开,测试串口我们用串口助手打开。
软件设计
由于默认的打印串口已经占用了一个(USART0),总共还有两个可以使用的串口(USART1、USART2),我们使用 USART1 来完成以下功能。硬件 GPIO19 作发送,GPIO18 作接收。
打印
代码
为啥两个串口初始化参数不一样,原因这个章节写。
/*
Simple Sketch for testing HardwareSerial with different CPU Frequencies
Changing the CPU Frequency may affect peripherals and Wireless functionality
In ESP32 Arduino, UART shall work correctly in order to let the user see DGB info
and other application messages.
CPU Frequency is usually lowered in sleep modes
and some other Low Power configurations
*/
#define BAUD 115200
#define TX_PIN 19
#define RX_PIN 18
void setup() {
Serial.begin(115200);
Serial.println("this is esp32 usart0 printf test! \r\n");
delay(100);
Serial1.begin(BAUD,SERIAL_8N1,RX_PIN,TX_PIN);
Serial1.println("this is esp32 usart1 printf test! \r\n");
}
void loop() {
// Nothing here so far
}
工程
验证结果
查看Arduino
串口监视器内容,有了如下打印。(默认串口的验证)
打开串口 3,有了如下打印。(测试串口的验证)
发送/接收单字节数据
代码
/*
Simple Sketch for testing HardwareSerial with different CPU Frequencies
Changing the CPU Frequency may affect peripherals and Wireless functionality
In ESP32 Arduino, UART shall work correctly in order to let the user see DGB info
and other application messages.
CPU Frequency is usually lowered in sleep modes
and some other Low Power configurations
*/
#define BAUD 115200
#define TX_PIN 19
#define RX_PIN 18
uint8_t recData[1];
void setup() {
Serial.begin(115200);
Serial.println("this is esp32 usart0 printf test! \r\n");
delay(100);
//Serial1.begin(BAUD,SERIAL_8N1,RX_PIN,TX_PIN);
Serial2.begin(BAUD,SERIAL_8N1);
//Serial2.println("this is esp32 usart2 default pins printf test! \r\n");
}
void loop() {
// Nothing here so far
if (Serial2.available() > 0) {
recData[0] = Serial2.read();
Serial2.write(recData,1);
}
}
验证结果
使用测试的串口,设置发送和接收都采用 16 进制,即可实现将接收到的数据又发送出去。
串口的默认引脚
看下面的代码。为什么Serial
,只需要指定波特率即可。而Serial1
却需要指定波特率、参数、接收和发送引脚呢?
答案就在HardwareSerial.cpp
文件中,文件中默认的 USART0_TX 为 GPIO1,USART0_RX 为 GPIO3。也就是这个章节引脚图中看到的。
那我们能不能也使用 USART1 的默认引脚,然后在初始化时不再指定引脚呢?还是在HardwareSerial.cpp
文件中,能看到 USART1_TX 是 GPIO10,USART1_RX 是 GPIO9。
看下面框图,GPIO9、GPIO10 是连在 SPI Flash 上的,不能作为普通 IO 使用。实际测试当做 USART 也不行。
那就试试可以用的串口。用 USART2,GPIO16 作 USART2_RX,GPIO17 作 USART2_TX。
主代码修改如下,注意已经把Serial1
变成了Serial2
。
#define BAUD 115200
#define TX_PIN 19
#define RX_PIN 18
void setup() {
Serial.begin(115200);
Serial.println("this is esp32 usart0 printf test! \r\n");
delay(100);
//Serial1.begin(BAUD,SERIAL_8N1,RX_PIN,TX_PIN);
Serial2.begin(BAUD,SERIAL_8N1);
Serial2.println("this is esp32 usart2 default pins printf test! \r\n");
}
void loop() {
// Nothing here so far
}
实际连接修改一下。
上电看串口助手输出。
实际测试初始化时不指定串口参数 8N1,它自己会默认 8N1。也就是将上述第 11 行的代码改成下面这样,依然可以实现功能。虽然在Arduino
官网看到了默认配置是 8N1,但是没看到在代码中哪一块体现的?
Serial2.begin(BAUD);