【ESP32】3.串口的发送与接受

串口发送部分

1.用ESP_IDF创建并选择blink工程

2.包含串口驱动

c 复制代码
#include "driver/uart.h"

3.宏定义串口和缓冲区大小,当然也可以在函数体里面直接用UART_NUM_0,或者直接填1024

c 复制代码
#define UART_NUM UART_NUM_0
#define BUF_SIZE (1024)

4.添加串口初始化函数

c 复制代码
void uart_init() {
    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,
        .source_clk = UART_SCLK_DEFAULT,
    };
    uart_param_config(UART_NUM, &uart_config);
    uart_driver_install(UART_NUM, BUF_SIZE * 2, 0, 0, NULL, 0);
}

5.main里while前初始化,uart_init();打印输出(字符串和HEX均可):

c 复制代码
void app_main(void)
{
   const char* data = "Hello, UART!\r\n";
   unsigned char buff[5]={0x11,0x12,0x13,0x14,0x15};
    /* Configure the peripheral according to the LED type */
    configure_led();
    uart_init();
    while (1) {
        //ESP_LOGI(TAG, "Turning the LED %s!", s_led_state == true ? "ON" : "OFF");
       // blink_led();
        /* Toggle the LED state */
       // s_led_state = !s_led_state;
       //验证两种方式输出:字符串和HEX
         uart_write_bytes(UART_NUM, data, strlen(data));//使用strlen来获取字符串长度
         vTaskDelay(500 / portTICK_PERIOD_MS);
         uart_write_bytes(UART_NUM, buff,5);            //打印HEX数据
         vTaskDelay(500 / portTICK_PERIOD_MS); 
    }
}

6.可在串口助手上观察交替打印"Hello, UART!"和HEX字符串。

做接受部分

需求:当接受到"AT+PAUSE=1"后打印"data open",接受到"AT+PAUSE=0"后打印"data

close",接受到"AT+BAND=0"后打印"2.4g close",接受到"AT+BAND=1"后打印"2.4g open"

下面整体代码,主要是用函数uart_read_bytes()读取数据,100ms的超时,在uart_init()之后创建了一个任务来处理读取到的数据,其中process_command()是命令处理函数,放在了串口任务函数里面。

strcmp函数需要#include"string.h"

c 复制代码
#define UART_NUM        UART_NUM_0
#define BUF_SIZE        128



// 命令处理函数
void process_command(const char* command) {
    if (strcmp(command, "AT+PAUSE=1") == 0) {
        uart_write_bytes(UART_NUM, "data open\r\n", strlen("data open\r\n"));
    } else if (strcmp(command, "AT+PAUSE=0") == 0) {
        uart_write_bytes(UART_NUM, "data close\r\n", strlen("data close\r\n"));
    } else if (strcmp(command, "AT+BAND=0") == 0) {
        uart_write_bytes(UART_NUM, "2.4g close\r\n", strlen("2.4g close\r\n"));
    } else if (strcmp(command, "AT+BAND=1") == 0) {
        uart_write_bytes(UART_NUM, "2.4g open\r\n", strlen("2.4g open\r\n"));
    } else {
        uart_write_bytes(UART_NUM, "Unknown command\r\n", strlen("Unknown command\r\n"));
    }
}

// UART 任务处理函数
void uart_task_entry(void *param) {
    uint8_t data[BUF_SIZE];

    while (1) {
        // 从 UART 读取数据,最多等待 100ms
        int len = uart_read_bytes(UART_NUM, data, BUF_SIZE - 1, pdMS_TO_TICKS(100));
        if (len > 0) {
            data[len] = '\0';  // 添加字符串结束符
            ESP_LOGI(TAG, "Received: %s", data);
            process_command((char*)data);
        }
    }
}

// UART 初始化函数
void uart_init() {
    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_param_config(UART_NUM, &uart_config);

    // 安装驱动程序(带缓冲区)
    uart_driver_install(UART_NUM, BUF_SIZE * 2, 0, 0, NULL, 0);

    // 启动 UART 任务
    xTaskCreate(uart_task_entry, "uart_task", 2048, NULL, 10, NULL);
}


void app_main(void)
{
   const char* data = "Hello, UART!\r\n";
   unsigned char buff[5]={0x11,0x12,0x13,0x14,0x15};
    /* Configure the peripheral according to the LED type */
    configure_led();
    uart_init();

    while (1) {
        //ESP_LOGI(TAG, "Turning the LED %s!", s_led_state == true ? "ON" : "OFF");
       // blink_led();
        /* Toggle the LED state */
       // s_led_state = !s_led_state;
       //验证两种方式输出:字符串和HEX
        // uart_write_bytes(UART_NUM, data, strlen(data));//使用strlen来获取字符串长度
        // vTaskDelay(500 / portTICK_PERIOD_MS);
        // uart_write_bytes(UART_NUM, buff,5);            //打印HEX数据
         vTaskDelay(500 / portTICK_PERIOD_MS); 
    }
}

可以看到发送与接受结果符合预期:

注意:ESP-IDF 要求每个源码目录都要有对应的 CMakeLists.txt 来声明其内容。

main/CMakeLists.txt 内容如下:

c 复制代码
# 注册 main 组件中的源文件
idf_component_register(SRCS "blink_example_main.c"
                    INCLUDE_DIRS "."
                    REQUIRES driver)

没加之前是这样:

c 复制代码
# 注册 main 组件中的源文件
idf_component_register(SRCS "blink_example_main.c"
                    INCLUDE_DIRS "."
                    )

我两种都试过了,貌似区别不大,不知道有没有高手可以解释下不。

tips:

1.关闭文件:顶栏-->文件-->关闭文件夹

2.openOCD打不开,在设置乐鑫设备目标里面,选对应型号后,注意这个USB--JTAG要选对。

3.Can't proceed with flashing, since project elf file (project-name2.elf) is missing from the build dir. (c:\Users\XYZN\esp32_project\project-name2\build)

这个错误提示表明在你的项目目录中缺少了 project-name2.elf 文件,而这个文件是进行固件烧录所必需的。通常,.elf 文件是由编译过程生成的,它包含了程序的机器码。重新编译大概率能好。

4.vscode写代码输入0会跳出中文简体选项,这个选项在VSCODE内部,但是我只想写个代码0而已?

这个0在数字键盘里面敲就可以。

5.整体注释的方法:Ctrl+/

6.使用监视设备后,打开外部串口助手会发现串口占用,要想用外部串口,需要拔掉串口线在vscode打开监视设备,肯定会识别错误,然后插上串口线,打开外部串口助手多试几次就可以用了。

相关推荐
Jerry丶Li8 小时前
十九、STM32的TIM(十)(编码器)
stm32·单片机·嵌入式硬件
IT阳晨。8 小时前
【STM32】串口通信及相关实验和项目
stm32·单片机·嵌入式硬件
搜移IT科技17 小时前
2025广州国际物联网产业生态博览会(物联网展)最新技术与亮点揭秘!
物联网
安庆平.Я17 小时前
STM32——IWDG
stm32·单片机·嵌入式硬件
怀民民民18 小时前
轮询&中断 串口实训
单片机·嵌入式硬件·串口·中断·轮询·学习日志·keill
卍郝凝卍18 小时前
NVR(网络视频录像机)和视频网关的工作方式
网络·图像处理·物联网·音视频·视频解决方案
kaka❷❷19 小时前
STM32 单片机 ESP8266 联网 和 MQTT协议
stm32·单片机·嵌入式硬件·物联网·mqtt·esp8266
古译汉书19 小时前
Stm32江科大入门教程--各章节详细笔记---查阅传送门
数据结构·stm32·单片机·嵌入式硬件·算法
塔能物联运维20 小时前
物联网运维中基于数字孪生的实时设备状态同步与仿真验证技术
运维·物联网
一个学Java小白21 小时前
LV.5 文件IO
stm32·单片机·嵌入式硬件