ESP32 ESP-IDF UART使用模式检测中断报告事件实现 收发数据

官网esp-idf参考代码:D:\esp-idf\examples\peripherals\uart\uart_events

开发环境:Source Insight  + esp-idf 

esp32模块:ESP32-WROOM-32

实现功能:使用ESP32的3个UART全部实现收发,要求3个UART同时接收每条数据长度25间隔时间为100ms。

 

初期看了一下官网的uart例程代码,官网推荐使用模式检测。自己也可以使用直接在ISR中处理中断。

#include <stdio.h>
#include <string.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/uart.h"
#include "freertos/queue.h"
#include "driver/gpio.h"


#define BUF_SIZE				(1024)
#define RD_BUF_SIZE 			(BUF_SIZE)


uart_event_t    uart0_event, uart1_event, uart2_event;
QueueHandle_t	uart0_queue, uart1_queue, uart2_queue;


void uart_event_handle(uart_port_t uart_num, QueueHandle_t queue, uart_event_t *event);





void app_main(void)
{
	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_0, &uart_config);
	uart_param_config(UART_NUM_1, &uart_config);
	uart_param_config(UART_NUM_2, &uart_config);

	uart_set_pin(UART_NUM_0, GPIO_NUM_1,  GPIO_NUM_3,  UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE);
	uart_set_pin(UART_NUM_1, GPIO_NUM_18, GPIO_NUM_19, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE);
	uart_set_pin(UART_NUM_2, GPIO_NUM_16, GPIO_NUM_17, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE);

	uart_driver_install(UART_NUM_0, BUF_SIZE * 2, BUF_SIZE * 2, 20, &uart0_queue, 0);
	uart_driver_install(UART_NUM_1, BUF_SIZE * 2, BUF_SIZE * 2, 20, &uart1_queue, 0);
	uart_driver_install(UART_NUM_2, BUF_SIZE * 2, BUF_SIZE * 2, 20, &uart2_queue, 0);

	uart_pattern_queue_reset(UART_NUM_0, 20);
	uart_pattern_queue_reset(UART_NUM_1, 20);
	uart_pattern_queue_reset(U
### 1. ESP-IDF 中虚拟 UART实现概述 ESP32 硬件上支持三个物理 UARTUART0、UART1 和 UART2)。然而,当需要额外的串口时,可以利用软件模拟的方式创建虚拟 UARTESP-IDF 提供了 `uart_driver_install` 函数来初始化 UART 驱动,并且可以通过自定义 GPIO 引脚和配置参数来实现虚拟 UART[^1]。 虚拟 UART 的核心思想是通过软件方式模拟 UART收发行为,从而扩展硬件限制。在 ESP-IDF 中,可以通过以下步骤实现第四个虚拟串口: --- ### 2. 创建虚拟 UART 的步骤 #### (1) 安装 UART 驱动 使用 `uart_driver_install` 函数安装 UART 驱动。该函数允许指定一个未使用UART 单元号(如 UART_NUM_3),并为其分配缓冲区大小和其他参数。 ```c #include "driver/uart.h" #define VIRTUAL_UART_PORT UART_NUM_3 // 使用虚拟 UART 编号 #define TX_PIN 17 // 自定义 TX 引脚 #define RX_PIN 16 // 自定义 RX 引脚 // 初始化虚拟 UART 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, .rx_flow_ctrl_thresh = 122, }; uart_param_config(VIRTUAL_UART_PORT, &uart_config); // 配置 UART 参数 uart_set_pin(VIRTUAL_UART_PORT, TX_PIN, RX_PIN, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE); // 设置引脚 uart_driver_install(VIRTUAL_UART_PORT, 256, 256, 0, NULL, 0); // 安装驱动 ``` 上述代码中,`uart_driver_install` 函数为虚拟 UART 分配了接收和发送缓冲区大小(分别为 256 字节),并且禁用了事件队列[^1]。 --- #### (2) 配置引脚映射 通过 `uart_set_pin` 函数将虚拟 UART 的 TX 和 RX 引脚绑定到用户指定的 GPIO 引脚。这里需要注意的是,ESP32 的任意 GPIO 引脚都可以用作虚拟 UART 的 TX 和 RX 引脚,但必须确保这些引脚未被其他外设占用[^3]。 --- #### (3) 发送与接收数据 一旦虚拟 UART 驱动安装完成,就可以像操作普通 UART 一样进行数据收发。例如: ```c // 发送数据 const char *send_data = "Hello Virtual UART!"; int len = strlen(send_data); uart_write_bytes(VIRTUAL_UART_PORT, send_data, len); // 接收数据 uint8_t buffer[256]; int rxBytes = uart_read_bytes(VIRTUAL_UART_PORT, buffer, sizeof(buffer) - 1, 10 / portTICK_RATE_MS); if (rxBytes > 0) { buffer[rxBytes] = '\0'; // 添加字符串终止符 printf("Received: %s\n", buffer); } ``` 上述代码展示了如何通过虚拟 UART 进行数据发送和接收。注意,`uart_read_bytes` 函数的超时时间以 Tick 为单位,需要根据实际需求调整[^1]。 --- ### 3. 注意事项 - **资源冲突**:确保所选的 GPIO 引脚未被其他外设或功能占用。例如,UART0 默认用于调试输出,因此建议将其保留给 monitor 功能[^3]。 - **性能限制**:虚拟 UART 的性能可能低于硬件 UART,特别是在高波特率下。如果需要更高的传输速度,建议优先使用硬件 UART- **中断处理**:如果需要处理大量数据,可以启用事件队列并注册回调函数以异步处理 UART 事件[^2]。 --- ### 4. 示例完整代码 以下是一个完整的示例代码,展示如何在 ESP-IDF实现使用虚拟 UART: ```c #include "driver/uart.h" #include "esp_log.h" #define VIRTUAL_UART_PORT UART_NUM_3 #define TX_PIN 17 #define RX_PIN 16 void init_virtual_uart() { 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, .rx_flow_ctrl_thresh = 122, }; uart_param_config(VIRTUAL_UART_PORT, &uart_config); uart_set_pin(VIRTUAL_UART_PORT, TX_PIN, RX_PIN, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE); uart_driver_install(VIRTUAL_UART_PORT, 256, 256, 0, NULL, 0); } void send_data(const char *data) { int len = strlen(data); uart_write_bytes(VIRTUAL_UART_PORT, data, len); } void receive_data() { uint8_t buffer[256]; int rxBytes = uart_read_bytes(VIRTUAL_UART_PORT, buffer, sizeof(buffer) - 1, 10 / portTICK_RATE_MS); if (rxBytes > 0) { buffer[rxBytes] = '\0'; ESP_LOGI("UART", "Received: %s", buffer); } } void app_main() { init_virtual_uart(); while (1) { send_data("Hello Virtual UART!\n"); vTaskDelay(1000 / portTICK_RATE_MS); receive_data(); } } ``` ---
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值