1 串口背景介绍
ESP32是一款强大的微控制器,广泛应用于物联网(IoT)和嵌入式系统中。它支持多种通信协议,其中串口通信是最常用的一种。以下是关于ESP32串口通信的详细介绍。串口通信是通过串行数据传输的方式进行设备间的通信,常见于与计算机、传感器、模块等的连接。ESP32支持多个串口,通常称为UART(通用异步收发传输器)。
1.1 ESP32的UART接口
ESP32有三个UART接口:
UART0:默认用于调试输出(通过USB连接)。
UART1:可用于用户自定义的串口通信。
UART2:同样可以用于用户自定义的串口通信。
1.2 每个UART支持以下参数设置:
波特率:常见如9600、115200等。
数据位:通常为8位。
停止位:常见为1位或2位。
校验位:可选,通常为无校验。
1.3 硬件连接
ESP32的串口引脚如下:
UART0:TX0(GPIO1),RX0(GPIO3)
UART1:TX1(GPIO10),RX1(GPIO9)
UART2:TX2(GPIO17),RX2(GPIO16)
在进行串口通信时,需要将ESP32的TX引脚连接到其他设备的RX引脚,将ESP32的RX引脚连接到其他设备的TX引脚。
1.4 使用注意事项
波特率匹配:确保发送和接收设备的波特率一致。
电平转换:如果与其他设备(如Arduino)连接,注意电平兼容性(ESP32工作在3.3V)。
流量控制:对于高数据率传输,可以考虑使用硬件流量控制(如RTS/CTS)来避免数据丢失。
1.5 应用场景
ESP32的串口通信广泛应用于
- 与传感器的数据采集与发送。
- 通过串口模块(如HC-05蓝牙模块)进行无线通信。
- 与其他微控制器(如Arduino)进行联动控制。
1.6 结论
ESP32的串口通信功能强大且灵活,适用于多种应用场景。通过正确的硬件连接和软件编程,可以实现高效的数据传输。在开发中,确保配置正确及注意电平兼容,可以有效避免问题的发生。
2 常见函数
代码添加头文件:
#include "driver/uart.h"
2.1 初始化串口,安装UART驱动和设置接收和发送缓冲区的大小
esp_err_t uart_driver_install(uart_port_t uart_num, int rx_buffer_size, int tx_buffer_size, int intr_alloc_flags, void* queue, int intr_source);
功能:安装串口驱动
参数:
uart_num: 串口号
rx_buffer_size: 接收缓冲区大小
tx_buffer_size: 发送缓冲区大小
queue_size: 事件队列大小 (0 表示不创建队列)
uart_queue: 返回的事件队列句柄
intr_alloc_flags: 中断分配标志
返回值:ESP_OK 成功,其他为错误码
2.2 配置波特率、数据位、停止位和校验位等参数
esp_err_t uart_param_config(uart_port_t uart_num, const uart_config_t *uart_config);
其中 uart_port_t 结构体如下:
typedef struct {
int baud_rate; // 波特率
uart_word_length_t data_bits; // 数据位 (UART_DATA_5_BITS 到 UART_DATA_8_BITS)
uart_parity_t parity; // 校验位 (UART_PARITY_DISABLE, UART_PARITY_EVEN, UART_PARITY_ODD)
uart_stop_bits_t stop_bits; // 停止位 (UART_STOP_BITS_1, UART_STOP_BITS_1_5, UART_STOP_BITS_2)
uart_hw_flowcontrol_t flow_ctrl;// 硬件流控 (UART_HW_FLOWCTRL_DISABLE, UART_HW_FLOWCTRL_RTS, UART_HW_FLOWCTRL_CTS, UART_HW_FLOWCTRL_CTS_RTS)
uint8_t rx_flow_ctrl_thresh; // RTS 阈值 (0-255)
} uart_config_t;
uart_num: 串口号 (UART_NUM_0, UART_NUM_1, UART_NUM_2)
返回值:ESP_OK 成功,其他为错误码
2.3 设置引脚
esp_err_t uart_set_pin(uart_port_t uart_num, int tx_pin, int rx_pin, int rts_pin, int cts_pin);
设置UART的TX和RX引脚,以及硬件流控制的RTS和CTS引脚。
2.4 读取数据
int uart_read_bytes(uart_port_t uart_num, uint8_t* buffer, uint32_t length, TickType_t ticks_to_wait);
从UART接收缓冲区读取数据。
功能:接收数据
参数:
uart_num: 串口号
buf: 接收缓冲区
length: 要读取的长度
ticks_to_wait: 等待时间 (portMAX_DELAY 表示无限等待)
返回值:实际读取的字节数
2.5 发送数据
int uart_write_bytes(uart_port_t uart_num, const char* src, size_t size);
向UART发送数据。
功能:发送数据
参数:
uart_num: 串口号
src: 数据源指针
size: 数据大小
返回值:实际发送的字节数
2.6 清空缓冲区
清空UART的发送和接收缓冲区。
esp_err_t uart_flush(uart_port_t uart_num);
参数说明
uart_num: UART的编号,通常为 UART_NUM_0、UART_NUM_1 或 UART_NUM_2,表示要清空的UART端口。
返回值
返回 esp_err_t 类型的状态代码:
ESP_OK: 表示操作成功。
其他错误代码:表示在执行过程中遇到的问题,例如无效的 UART 端口。
2.7 设置UART特性
设置UART的工作模式(如全双工、半双工等)。
esp_err_t uart_set_mode(uart_port_t uart_num, uart_mode_t mode);
参数说明:
uart_num: UART的编号,通常是UART_NUM_0、UART_NUM_1或UART_NUM_2。
mode: UART工作模式,类型为uart_mode_t,可以是以下几种模式之一:
UART_MODE_UART: 标准UART模式(全双工)。
UART_MODE_HALF_DUPLEX: 半双工模式。
UART_MODE_IRDA: 红外模式(用于红外通信)。
返回值
返回esp_err_t类型的错误代码,表示函数执行的结果:
ESP_OK: 操作成功。
其他错误代码:表示不同的错误情况(例如参数无效等)。
注意事项
在设置UART模式之前,确保已经正确配置UART的其他参数,例如波特率和引脚。
半双工模式需要适当的硬件设计支持,因为它只允许一个方向的数据传输。在此模式下,TX和RX引脚可能共享同一个引脚,但实际使用时必须控制数据流向。如果使用红外模式,确保外设与ESP32之间的连线和协议是兼容的。
2.8 获取当前UART的缓冲区大小
int uart_get_buffer_size(uart_port_t uart_num);
3 映射
ESP32 有 3 个串口(UART0、UART1、UART2),可以灵活映射到任意 GPIO。UART0 默认连接到 USB 串口,用于烧录和调试,不建议重定向。UART1 和 UART2 可任意映射引脚,用于自定义通信。GPIOs 6-11 是 SPI flash 引脚,不建议用作串口引脚。
4 案例
4.1 初始化
#include "driver/uart.h"
void uart_init_example() {
uart_config_t uart_config = {
.baud_rate = 115200,
.data_bits = UART_DATA_8_BITS,
.parity = UART_PARITY_DISABLE,
.stop_bits = UART_STOP_BITS_1,
.flow_ctrl = UART_HW_FLOWCTRL_DISABLE
};
uart_param_config(UART_NUM_1, &uart_config);
uart_set_pin(UART_NUM_1, 17, 16, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE);
uart_driver_install(UART_NUM_1, 1024, 1024, 0, NULL, 0);
}
4.2 发送接收示例
// 发送数据
const char *test_str = "Hello ESP32 UART!\n";
uart_write_bytes(UART_NUM_1, test_str, strlen(test_str));
// 接收数据
uint8_t data[128];
int len = uart_read_bytes(UART_NUM_1, data, sizeof(data), 20 / portTICK_PERIOD_MS);
//20 / portTICK_PERIOD_MS 表示将 20 毫秒转换为对应的 tick 数
// 也可以使用 pdMS_TO_TICKS(20)
if (len > 0) {
// 处理接收到的数据
}