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

相关推荐
悠哉悠哉愿意9 天前
【单片机学习笔记】串口、超声波、NE555的同时使用
笔记·单片机·学习
Lester_11019 天前
STM32霍尔传感器输入口设置为复用功能输入口时,还能用GPIO函数直接读取IO的状态吗
stm32·单片机·嵌入式硬件·电机控制
三佛科技-187366133979 天前
120W小体积碳化硅电源方案(LP8841SC极简方案12V10A/24V5A输出)
单片机·嵌入式硬件
z20348315209 天前
STM32F103系列单片机定时器介绍(二)
stm32·单片机·嵌入式硬件
古译汉书9 天前
【IoT死磕系列】Day 7:只传8字节怎么控机械臂?学习工业控制 CANopen 的“对象字典”(附企业级源码)
数据结构·stm32·物联网·http
TDengine (老段)9 天前
TDengine IDMP 数据可视化——散点图
大数据·数据库·物联网·信息可视化·时序数据库·tdengine·涛思数据
Lupino9 天前
从逻辑“脑裂”到 AI 重构:不到 2 美金解决物联网电位反转难题
python·物联网
Alaso_shuang9 天前
STM32 核心输入、输出模式
stm32·单片机·嵌入式硬件
脚后跟9 天前
AI助力嵌入式物联网项目全栈开发
嵌入式硬件·物联网·ai编程
2501_918126919 天前
stm32死锁是怎么实现的
stm32·单片机·嵌入式硬件·学习·个人开发