单片机/MCU论坛
直播中

韦春榴

未满1年用户 3经验值
擅长:控制/MCU
私信 关注
[问答]

ESP32usart接收中断求助

我的项目需要ESP32USART使用串口接收中断工作,用IDF5.12版本编译所有例程均未能通过,希望有高手帮帮我,谢谢。

回帖(1)

jf_87481316

2025-11-4 14:22:55
完整的 UART 接收中断示例
#include
#include
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/queue.h"
#include "driver/uart.h"
#include "esp_log.h"

static const char *TAG = "UART_EXAMPLE";

// UART 配置
#define UART_PORT_NUM      UART_NUM_1
#define UART_BAUD_RATE     115200
#define UART_TXD_PIN       17
#define UART_RXD_PIN       16
#define UART_BUF_SIZE      1024
#define UART_QUEUE_LEN     20

static void uart_event_task(void *pvParameters)
{
    uart_event_t event;
    size_t buffered_size;
    uint8_t *dtmp = (uint8_t *)malloc(UART_BUF_SIZE);
   
    for (;;) {
        // 等待 UART 事件
        if (xQueueReceive(uart_get_event_queue(UART_PORT_NUM), &event, portMAX_DELAY)) {
            bzero(dtmp, UART_BUF_SIZE);
            
            switch (event.type) {
                case UART_DATA:
                    // 数据接收事件
                    uart_read_bytes(UART_PORT_NUM, dtmp, event.size, portMAX_DELAY);
                    ESP_LOGI(TAG, "Received %d bytes: %.*s", event.size, event.size, dtmp);
                    break;
                    
                case UART_FIFO_OVF:
                    ESP_LOGI(TAG, "HW FIFO Overflow");
                    uart_flush_input(UART_PORT_NUM);
                    xQueueReset(uart_get_event_queue(UART_PORT_NUM));
                    break;
                    
                case UART_BUFFER_FULL:
                    ESP_LOGI(TAG, "Ring Buffer Full");
                    uart_flush_input(UART_PORT_NUM);
                    xQueueReset(uart_get_event_queue(UART_PORT_NUM));
                    break;
                    
                case UART_BREAK:
                    ESP_LOGI(TAG, "UART Break");
                    break;
                    
                case UART_PARITY_ERR:
                    ESP_LOGI(TAG, "UART Parity Error");
                    break;
                    
                case UART_FRAME_ERR:
                    ESP_LOGI(TAG, "UART Frame Error");
                    break;
                    
                case UART_PATTERN_DET:
                    // 模式检测(可用于帧尾检测)
                    uart_get_buffered_data_len(UART_PORT_NUM, &buffered_size);
                    int pos = uart_pattern_pop_pos(UART_PORT_NUM);
                    ESP_LOGI(TAG, "Pattern detected at position: %d", pos);
                    if (pos != -1) {
                        uart_read_bytes(UART_PORT_NUM, dtmp, pos, 100 / portTICK_PERIOD_MS);
                        ESP_LOGI(TAG, "Pattern data: %.*s", pos, dtmp);
                    }
                    break;
                    
                default:
                    ESP_LOGI(TAG, "UART event type: %d", event.type);
                    break;
            }
        }
    }
   
    free(dtmp);
    dtmp = NULL;
    vTaskDelete(NULL);
}

void app_main(void)
{
    // UART 配置参数
    uart_config_t uart_config = {
        .baud_rate = UART_BAUD_RATE,
        .data_bits = UART_DATA_8_BITS,
        .parity = UART_PARITY_DISABLE,
        .stop_bits = UART_STOP_BITS_1,
        .flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
        .source_clk = UART_SCLK_DEFAULT,
    };
   
    // 配置 UART 参数
    ESP_ERROR_CHECK(uart_param_config(UART_PORT_NUM, &uart_config));
   
    // 设置 UART 引脚
    ESP_ERROR_CHECK(uart_set_pin(UART_PORT_NUM, UART_TXD_PIN, UART_RXD_PIN,
                                UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE));
   
    // 安装 UART 驱动
    ESP_ERROR_CHECK(uart_driver_install(UART_PORT_NUM,
                                       UART_BUF_SIZE * 2,  // 接收缓冲区大小
                                       UART_BUF_SIZE * 2,  // 发送缓冲区大小  
                                       UART_QUEUE_LEN,     // 事件队列大小
                                       NULL,               // 事件队列句柄
                                       0));                // 中断分配标志
   
    // 如果需要模式检测(帧尾检测),可以设置模式
    // uart_enable_pattern_det_baud_intr(UART_PORT_NUM, '\n', 1, 9, 0, 0);
    // uart_pattern_queue_reset(UART_PORT_NUM, UART_QUEUE_LEN);
   
    // 创建 UART 事件处理任务
    xTaskCreate(uart_event_task, "uart_event_task", 4096, NULL, 12, NULL);
   
    // 发送测试数据
    const char *test_data = "Hello UART!\n";
    uart_write_bytes(UART_PORT_NUM, test_data, strlen(test_data));
   
    ESP_LOGI(TAG, "UART initialized successfully");
}

对应的 CMakeLists.txt
# CMakeLists.txt
cmake_minimum_required(VERSION 3.5)

include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(uart_example)

set(SOURCES
    main/main.c
)

idf_component_register(SRCS ${SOURCES}
                    INCLUDE_DIRS ".")

target_link_libraries(${CMAKE_PROJECT_NAME} PRIVATE -Wl,--start-group -lgcc -lstdc++ -Wl,--end-group)

如果仍有问题,尝试这个简化版本
#include
#include "driver/uart.h"
#include "esp_log.h"

static const char *TAG = "UART_SIMPLE";

void app_main(void)
{
    // 基本 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,
        .source_clk = UART_SCLK_DEFAULT,
    };
   
    // 安装 UART 驱动(使用默认引脚)
    uart_driver_install(UART_NUM_0, 1024, 0, 0, NULL, 0);
    uart_param_config(UART_NUM_0, &uart_config);
   
    ESP_LOGI(TAG, "UART basic example running");
   
    while(1) {
        char test_str[] = "Hello World\n";
        uart_write_bytes(UART_NUM_0, test_str, sizeof(test_str));
        vTaskDelay(1000 / portTICK_PERIOD_MS);
    }
}


举报

更多回帖

发帖
×
20
完善资料,
赚取积分