05-ESP32-S3-IDF USART

ESP32-S3 IDF USART详解

USART简介

USART是一种串行通信协议,广泛应用于微控制器和计算机之间的通信。USART支持异步和同步模式,因此它可以在没有时钟信号的情况下(异步模式)或有时钟信号的情况下(同步模式)进行通信。

ESP32-S3的USART

ESP32-S3有两个全功能的USART通道,USART0和USART1,USART2,支持异步通信(RS232 和 RS485)和 IrDA,通信速率可达到 5 Mbps。

UART 基本架构图
在这里插入图片描述
UART 模块工作在两个时钟域:APB_CLK 时钟域和 Core 时钟域。UART Core 有三个时钟源:80-MHz APB_CLKRC_FAST_CLK 以及晶振时钟 XTAL_CLK ,可以通过配置 UART_SCLK_SEL 来选择时钟源。分频器用于对时钟源进行分频,然后产生时钟信号来驱动 UARTCore 模块。

更加详细的介绍,可以去看看官方的文档:
ESP32S3官方文档

需要注意一点
ESP32-S3的USART引脚映射是可配置的,这是因为ESP32-S3使用了一个称为GPIO矩阵的特性。GPIO矩阵是ESP32-S3硬件的一部分,它允许将内部信号路由到任何GPIO引脚。这意味着,我们可以将USART的发送(TX)和接收(RX)信号连接到你选择的任何可用GPIO引脚。

ESP32-S3 UART的默认引脚

发送(TX)接收(RX)
UART0IO43IO44
UART1IO17 / 任意IOIO18 / 任意IO
UART2任意IO任意IO

printf()函数

在ESP-IDF中,printf()函数默认使用的是USART0。这是因为在ESP32-S3的启动代码中,USART0被初始化为默认的调试控制台。因此,当我们在代码中使用printf()函数来打印信息时,这些信息将会被发送到USART0,并且可以通过串行接口(如USB转串口适配器)在计算机的串行监视器上看到。

使用ESP-IDF配置USART

在ESP32-S3上使用USART的基本步骤:

  • 设置 UART 参数、分配引脚(可选,不配置则使用默认引脚)
  • 初始化UART
  • 安装 UART 驱动
  • 收发数据
  • 使用中断
  • 卸载 UART 中断驱动,释放资源(当 UART 不再使用时)
#include "driver/uart.h"

void app_main(void)
{
    // -------------1. 配置USART选项-----------------------
    
    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 // 流控
    };

    // --------------2. 初始化USART------------------------
    
    // UART_NUM_1:UART端口号
    // &uart_config:指向uart_config_t结构体的指针
    uart_param_config(UART_NUM_1, &uart_config);

    // --------------3. 安装驱动程序------------------------
    
    // UART_NUM_1:UART端口号
    // 1024 * 2:接收缓冲区大小
    // 0:发送缓冲区大小
    // 0:队列长度
    // NULL:队列句柄(如果不使用队列,可以设置为NULL)
    // 0:中断分配标志(通常设置为0)
    uart_driver_install(UART_NUM_1, 1024 * 2, 0, 0, NULL, 0);

    // 4.---------------4. 发送数据--------------------------
    
    // UART_NUM_1:UART端口号
    // "Hello, world!":要发送的数据
    // 13:要发送的数据的长度
    uart_write_bytes(UART_NUM_1, "Hello, world!", 13);
    
    // ------------------5. 读取数据-----------------------
    
    uint8_t data[128]; // 数据缓冲区
	int length = 0; // 读取的数据长度
	
	// UART_NUM_1:UART端口号
	// data:数据缓冲区
	// sizeof(data):要读取的最大数据长度
	// 1000 / portTICK_RATE_MS:读取超时时间(以RTOS tick为单位)
	length = uart_read_bytes(UART_NUM_1, data, sizeof(data), 1000 / portTICK_RATE_MS);
	
	if (length > 0) {
	    // 如果读取到数据,处理数据
	    // ...
	}

}

前面提到过ESP32-S3的USART引脚映射是可配置的,所以我们可以使用uart_set_pin()来自定义TX和RX

#include "driver/uart.h"

void app_main(void)
{
    // 设置UART1的TX引脚为GPIO10,RX引脚为GPIO9
    uart_set_pin(UART_NUM_1, 10, 9, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE);
}

这里uart_set_pin()函数的最后两个参数是RTS(请求发送)和CTS(清除发送),我没有使用所以将它们设置为UART_PIN_NO_CHANGE

USART实验

在这里插入图片描述
串口UART_NUM_1接收数据,并分别在串口UART_NUM_0和串口UART_NUM_1返回

这次我们依旧使用面向对象的方法来编写驱动,驱动API接口参考Arduino的格式

USART.h

/**
 * @file USART.h
 * @author 宁子希 (1589326497@qq.com)
 * @brief   串口初始化类
 * @version 0.1
 * @date 2024-03-12
 * 
 * @copyright Copyright (c) 2024
 * 
 */

#ifndef _USART_H_
#define _USART_H_

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

#ifdef __cplusplus
 extern "C" {
#endif


class Uart {
public:
    // 构造函数,接收UART端口号和TX、RX引脚作为参数
    Uart(uart_port_t uart_num, int tx_pin, int rx_pin);

    // 发送数据,接收一个字符数组和长度作为参数
    void write(const char* data, int len);

    // 接收数据,接收一个字符数组和长度作为参数,返回实际接收的长度
    int read(uint8_t* buf, int len);

private:
    uart_port_t _uart_num; // UART端口号
    int _tx_pin; // TX引脚
    int _rx_pin; // RX引脚
};


#ifdef __cplusplus
 }
#endif

#endif

USART.cpp

/**
 * @file USART.cpp
 * @author 宁子希 (1589326497@qq.com)
 * @brief   串口初始化类
 * @version 0.1
 * @date 2024-03-12
 * 
 * @copyright Copyright (c) 2024
 * 
 */
#include "USART.h"

// 构造函数
Uart::Uart(uart_port_t uart_num, int tx_pin, int rx_pin)
    : _uart_num(uart_num), _tx_pin(tx_pin), _rx_pin(rx_pin) {
    // 配置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, // 流控制
    };
    // 配置UART参数
    uart_param_config(uart_num, &uart_config);

    // 设置UART引脚
    // 设置UART的TX和RX引脚
    uart_set_pin(uart_num, tx_pin, rx_pin, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE);

    // 安装UART驱动程序
    // 安装UART驱动程序
    uart_driver_install(uart_num, 1024 * 2, 0, 0, NULL, 0);
}

// 发送数据
void Uart::write(const char* data, int len) {
    // 调用ESP-IDF库函数来发送数据
    uart_write_bytes(_uart_num, data, len);
}

// 接收数据
int Uart::read(uint8_t* buf, int len) {
    // 调用ESP-IDF库函数来接收数据
    return uart_read_bytes(_uart_num, buf, len, 1000 / portTICK_PERIOD_MS);
}

main.cpp

/**
 * @file main.cpp
 * @author 宁子希 (1589326497@qq.com)
 * @brief   串口通信实验
 * @version 0.1
 * @date 2024-03-13
 * 
 * @copyright Copyright (c) 2024
 * 
 */

#include <iostream>
#include <string>
#include "USART.h"
using namespace std;

extern "C" void app_main(void){

    // 创建一个Uart对象使用UART_NUM_1 TX:8 RX:9
    Uart uart1(UART_NUM_1, 8, 9);

    // 发送数据
    uart1.write("Hello, ESP32!", 13);

    while(true){

        // 接收数据
        uint8_t buf[128];
        int len = uart1.read(buf, sizeof(buf));

        // 处理接收到的数据
        if (len > 0) {
            // 假设我们只是简单地将接收到的数据打印出来
            for (int i = 0; i < len; i++) {
                printf("%c", buf[i]);
            }
            printf("\n");

            // 然后我们可以再次发送处理后的数据
            uart1.write((const char*)buf, len);
        }
    }
}

总结

更加详细的内容可以去看看官方的资料:
ESP32S3 USART 官方手册

<think>嗯,用户想要找关于ESP32-S3 N16R8模块在FreeRTOS下的使用指南、示例代码和配置方法。首先,我需要确认ESP32-S3和N16R8模块的基本信息。ESP32-S3是乐鑫推出的双核Xtensa LX7 MCU,支持Wi-Fi和蓝牙,而N16R8可能指的是模块的型号,可能带有16MB Flash和8MB PSRAM?这个需要核实一下。 接下来,用户提到了FreeRTOS,说明他们需要在ESP32-S3上使用实时操作系统。乐鑫的ESP-IDF框架默认使用FreeRTOS,所以可能需要从ESP-IDF入手。用户可能已经知道一些基本的环境搭建,但可能需要具体的配置步骤和示例代码。 然后,用户提供的引用中提到了PlatformIO和ESP-IDF的环境搭建,以及GPIO矩阵的配置。这些信息应该整合进去,特别是关于UART引脚配置的部分,因为引用3提到ESP32-S3USART引脚是可配置的,这可能对用户的开发有帮助。 用户可能需要知道如何配置FreeRTOS的任务、队列、信号量等,以及如何利用双核特性。示例代码部分应该包括创建任务、使用GPIO、UART通信等基础内容。同时,需要确保代码符合ESP-IDF的最新版本,因为乐鑫的SDK更新较快。 另外,用户可能对内存配置感兴趣,特别是N16R8模块的16MB Flash和8MB PSRAM的使用方法。需要解释如何在sdkconfig中调整内存分配,比如PSRAM的使用配置。 还要考虑常见问题,比如如何优化FreeRTOS的任务堆栈大小,如何监控任务状态,以及如何解决外设驱动中的问题,比如UART的引脚映射。引用3中提到GPIO矩阵,这部分需要详细说明如何灵活配置UART引脚,避免用户在使用默认引脚时遇到冲突。 最后,生成相关问题时要覆盖环境搭建、多任务处理、外设驱动、内存优化和调试技巧等方面,确保用户能全面了解ESP32-S3在FreeRTOS下的开发流程。</think>### ESP32-S3 N16R8 FreeRTOS使用指南 #### 一、开发环境搭建 1. **PlatformIO配置** 推荐使用VSCode+PlatformIO组合开发: ```ini [env:esp32s3] platform = espressif32 board = esp32s3-devkitc-1 framework = espidf monitor_speed = 115200 ``` 通过`board_build.flash_size`参数可配置16MB Flash支持[^1] 2. **ESP-IDF环境配置** ```bash git clone --recursive https://github.com/espressif/esp-idf.git cd esp-idf ./install.sh source export.sh ``` #### 二、FreeRTOS核心配置 1. **任务创建示例** ```c void my_task(void *pvParameters) { while(1) { printf("Core %d running\n", xPortGetCoreID()); vTaskDelay(1000 / portTICK_PERIOD_MS); } } void app_main() { xTaskCreatePinnedToCore(my_task, "Task1", 4096, NULL, 5, NULL, 0); xTaskCreatePinnedToCore(my_task, "Task2", 4096, NULL, 5, NULL, 1); } ``` 2. **双核调度配置** 在`sdkconfig`中设置: ``` CONFIG_FREERTOS_UNICORE=n CONFIG_FREERTOS_HZ=1000 ``` #### 三、外设驱动配置 1. **GPIO矩阵配置(以UART为例)** ```c #define TX_PIN 17 #define RX_PIN 18 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_1, &uart_config); uart_set_pin(UART_NUM_1, TX_PIN, RX_PIN, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE); ``` 2. **PSRAM配置** 在`sdkconfig`中启用: ``` CONFIG_ESP32S3_SPIRAM_SUPPORT=y CONFIG_SPIRAM_MODE_OCT=y CONFIG_SPIRAM_SIZE=8388608 # 8MB ``` #### 四、典型应用场景 1. **WiFi+BLE双模通信** ```c void wifi_init() { ESP_ERROR_CHECK(esp_netif_init()); ESP_ERROR_CHECK(esp_event_loop_create_default()); wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); ESP_ERROR_CHECK(esp_wifi_init(&cfg)); } void bluetooth_init() { esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT(); esp_bt_controller_init(&bt_cfg); } ``` #### 五、调试技巧 1. **FreeRTOS状态监控** ```c void print_task_info() { char buffer[1024]; vTaskList(buffer); printf("Task Name\tState\tPriority\tStack\tCore\n"); printf("%s\n", buffer); } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

宁子希

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值