ESP32的UART(串口)

本文详细介绍了ESP32芯片的三个UART控制器(UART0、UART1和UART2)的配置过程,包括波特率、数据位、停止位等参数设置,以及创建了相应的接收任务和发送测试。展示了如何在ESP32中实现多路串口通信。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、ESP32 的 UART 概览

1、简介
ESP32芯片有三个UART控制器(UART0、UART1和UART2),具有一组功能相同的寄存器,便于编程和灵活性。

每个UART控制器可独立配置波特率、数据位长、位序、停止位数、奇偶校验位等参数。

具体工程已上传至优快云我的资源里,可直接免费下载

包含#include

#include <stdio.h>
#include <inttypes.h>
#include "sdkconfig.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_chip_info.h"
#include "esp_flash.h"
#include "esp_log.h"
#include "esp_system.h"

#include "spi_flash_mmap.h"
#include "esp_wifi.h"
#include "esp_event.h"
#include "esp_err.h"
#include "nvs_flash.h"
#include "driver/ledc.h"
#include "driver/uart.h"
#include "driver/gpio.h"
#include "string.h"

宏定义

/*
===========================
宏定义
===========================
*/
// UART0
#define RX0_BUF_SIZE (1024)
#define TX0_BUF_SIZE (512)
#define TXD0_PIN (GPIO_NUM_43)
#define RXD0_PIN (GPIO_NUM_44)

// UART1
#define RX1_BUF_SIZE (1024)
#define TX1_BUF_SIZE (512)
#define TXD1_PIN (GPIO_NUM_5)
#define RXD1_PIN (GPIO_NUM_4)

// UART2
#define RX2_BUF_SIZE (1024)
#define TX2_BUF_SIZE (512)
#define TXD2_PIN (GPIO_NUM_12)
#define RXD2_PIN (GPIO_NUM_13)

ESP32三路串口初始化

void uart_init(void)
{
	//串口配置结构体


//串口参数配置->uart0
	uart_config_t uart0_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_0, &uart0_config); //设置串口
	// IO映射-> T:IO1  R:IO3
	uart_set_pin(UART_NUM_0, TXD0_PIN, RXD0_PIN, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE);
	//注册串口服务即使能+设置缓存区大小
	uart_driver_install(UART_NUM_0, RX0_BUF_SIZE * 2, TX0_BUF_SIZE * 2, 0, NULL, 0);



//串口参数配置->uart1
	uart_config_t uart1_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, &uart1_config); //设置串口

	// IO映射-> T:IO4  R:IO5
	uart_set_pin(UART_NUM_1, TXD1_PIN, RXD1_PIN, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE);
	//注册串口服务即使能+设置缓存区大小
	uart_driver_install(UART_NUM_1, RX1_BUF_SIZE * 2, TX1_BUF_SIZE * 2, 0, NULL, 0);



//串口参数配置->uart2
	uart_config_t uart2_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_2, &uart2_config); //设置串口
	// IO映射-> T:IO12  R:IO13
	uart_set_pin(UART_NUM_2, TXD2_PIN, RXD2_PIN, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE);
	//注册串口服务即使能+设置缓存区大小
	uart_driver_install(UART_NUM_2, RX2_BUF_SIZE * 2, TX2_BUF_SIZE * 2, 0, NULL, 0);
}

接收任务

// 串口0接收任务
void uart0_rx_task()
{
	uint8_t *data = (uint8_t *)malloc(RX0_BUF_SIZE + 1);
	while (1)
	{
		//获取串口0接收的数据
		const int rxBytes = uart_read_bytes(UART_NUM_0, data, RX0_BUF_SIZE, 10 / portTICK_PERIOD_MS);
		if (rxBytes > 0)
		{
			data[rxBytes] = 0;
			uart_write_bytes(UART_NUM_0, "uart0 cb\r\n", strlen("uart0 cb\r\n"));
			//将接收到的数据发出去
			uart_write_bytes(UART_NUM_0, (char *)data, rxBytes);
		}
	}
	free(data);
}



//串口1接收任务
void uart1_rx_task()
{
	uint8_t *data = (uint8_t *)malloc(RX1_BUF_SIZE + 1);
	while (1)
	{
		//获取串口1接收的数据
		const int rxBytes = uart_read_bytes(UART_NUM_1, data, RX1_BUF_SIZE, 10 / portTICK_PERIOD_MS);
		if (rxBytes > 0)
		{
			data[rxBytes] = 0;
			uart_write_bytes(UART_NUM_1, "uart1 cb\r\n", strlen("uart1 cb\r\n"));
			//将接收到的数据发出去
			uart_write_bytes(UART_NUM_1, (char *)data, rxBytes);
		}
	}
	free(data);
}



//串口2接收任务
void uart2_rx_task()
{
	uint8_t *data = (uint8_t *)malloc(RX2_BUF_SIZE + 1);
	while (1)
	{
		const int rxBytes = uart_read_bytes(UART_NUM_2, data, RX2_BUF_SIZE, 10 / portTICK_PERIOD_MS);
		if (rxBytes > 0)
		{
			data[rxBytes] = 0;
			uart_write_bytes(UART_NUM_2, "uart2 cb\r\n", strlen("uart2 cb\r\n"));
			//将接收到的数据发出去
			uart_write_bytes(UART_NUM_2, (char *)data, rxBytes);
		}
	}
	free(data);
}

主函数入口

void app_main(void)
{
	//串口初始化
	uart_init();
	//创建串口0接收任务
	xTaskCreate(uart0_rx_task, "uart0_rx_task", 1024 * 2, NULL, configMAX_PRIORITIES, NULL);
	//创建串口1接收任务
	xTaskCreate(uart1_rx_task, "uart1_rx_task", 1024 * 2, NULL, configMAX_PRIORITIES, NULL);
	//创建串口2接收任务
	xTaskCreate(uart2_rx_task, "uart2_rx_task", 1024 * 2, NULL, configMAX_PRIORITIES - 1, NULL);


while(1)
{

	//串口0数据发送测试
	uart_write_bytes(UART_NUM_0, "uart0 test OK \r\n", strlen("uart0 test OK \r\n"));
	//串口1数据发送测试
	uart_write_bytes(UART_NUM_1, "uart1 test OK \r\n", strlen("uart1 test OK \r\n"));
	//串口2数据发送测试
	uart_write_bytes(UART_NUM_2, "uart2 test OK \r\n", strlen("uart2 test OK \r\n"));
	vTaskDelay(2000/portTICK_PERIOD_MS);

}

}

运行结果如下图所示

在这里插入图片描述

### ESP32 UART串口通信配置与示例 ESP32UART 串口通信是其核心功能之一,用于与其他设备进行数据交换。以下是关于如何配置和使用 ESP32UART 接口的相关说明。 #### 配置 UART 参数 在使用 ESP32UART 功能之前,需要先初始化并设置参数。这些参数包括波特率、数据位数、停止位以及校验方式等。以下是一个典型的配置过程: ```c #include "driver/uart.h" void uart_init(void) { const int uart_num = UART_NUM_1; // 使用 UART1 uart_config_t uart_conf = { .baud_rate = 9600, // 波特率为 9600bps .data_bits = UART_DATA_8_BITS, // 数据位为 8 位 .parity = UART_PARITY_DISABLE,// 不启用奇偶校验 .stop_bits = UART_STOP_BITS_1, // 停止位为 1 位 .flow_ctrl = UART_HW_FLOWCTRL_DISABLE// 关闭硬件流控 }; uart_param_config(uart_num, &uart_conf); // 设置 UART 参数 uart_set_pin(uart_num, TXD_PIN, RXD_PIN, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE); // 设置 GPIO 引脚 } ``` 此代码片段展示了如何初始化一个 UART 接口[^4]。其中 `TXD_PIN` 和 `RXD_PIN` 应替换为实际使用的 GPIO 编号。 --- #### 发送与接收数据 完成初始化之后,可以通过函数发送或读取数据。下面分别展示发送字符串和接收字符的示例代码。 ##### 发送数据 ```c void send_data(const char* data) { uint8_t* tx_buffer = (uint8_t*)data; uart_write_bytes(UART_NUM_1, (const char*)tx_buffer, strlen(data)); // 将缓冲区中的字节写入到指定的 UART 设备 } ``` ##### 接收数据 ```c #define BUF_SIZE (1024) char rx_buffer[BUF_SIZE]; int receive_data() { int length = uart_read_bytes(UART_NUM_1, (uint8_t *)rx_buffer, sizeof(rx_buffer)-1, 10/portTICK_RATE_MS); if(length > 0){ rx_buffer[length] = '\0'; // 添加终止符以便打印 printf("Received: %s\n", rx_buffer); } return length; } ``` 以上两段代码实现了基本的数据传输操作[^2]。注意,在调用 `uart_read_bytes()` 函数时需考虑超时时间以防止阻塞过久。 --- #### 故障排查指南 当遇到 UART 通信异常时,可以从以下几个方面入手解决问题: 1. **检查硬件连接** - 确认 TX/RX 引脚是否正确连接至目标设备。 - 如果涉及电平转换,请验证逻辑电压匹配情况(如 CMOS/TTL 或 RS-232 转换电路)[^3]。 2. **确认波特率一致性** - 双方设备应采用相同的波特率设定;否则可能导致乱码现象发生。 3. **观察日志输出** - 利用调试工具捕获错误信息,例如通过 `ESP_LOGE` 打印错误提示语句来辅助分析问题所在位置。 4. **测试独立组件** - 单独运行简单的回环测试程序(Loopback Test),即将同一芯片上的 TX 连接到 RX 上看能否正常显示所发内容。 5. **调整软件配置** - 对于复杂应用场合可能还需要额外处理诸如中断服务例程或者 DMA 控制等功能模块。 --- ### 示例总结 综上所述,基于 ESP32 平台构建稳定的 UART 通讯链路并不困难,只需遵循标准 API 文档指导即可快速搭建原型系统。然而针对特定需求则往往还需深入研究更多高级选项才行。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值