【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打开监视设备,肯定会识别错误,然后插上串口线,打开外部串口助手多试几次就可以用了。

相关推荐
机器视觉知识推荐、就业指导1 天前
STM32 外设驱动模块:热敏电阻传感器模块
stm32·单片机·嵌入式硬件
GilgameshJSS1 天前
STM32H743-ARM例程9-IWDG看门狗
c语言·arm开发·stm32·单片机·嵌入式硬件·学习
华普微HOPERF1 天前
Matter over Thread方案,如何助力智能家居生态互通?
物联网·智能家居·matter协议·thread协议
Hello_Embed1 天前
STM32 智能垃圾桶项目笔记(一):超声波模块(HC-SR04)原理与驱动实现
c语言·笔记·stm32·单片机·嵌入式软件·嵌入式项目
ManThink Technology1 天前
如何配置GDO51和GDI51网关通过Basic Station连接到ChirpStack平台
物联网
what&&why1 天前
STM32控制继电器
单片机·嵌入式硬件
openHiTLS密码开源社区1 天前
白盒密码:守护不可信环境中的密钥安全
物联网·aes·白盒密码·数字版权·密钥算法融合·不可信环境·轻量级安全
Net_Walke1 天前
git 的常用命令
git·物联网·github·iot
我不吃西红柿k1 天前
蓝桥杯嵌入式——基础模块的使用(初始化+调度器+LED+按键+LCD)
单片机·嵌入式硬件
XCOSnTh1 天前
XCOSnTh单片机的串口
c语言·单片机·嵌入式硬件·算法·xcosnth