05-ESP32-S3-IDF USART

news2024/11/18 9:48:28

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 官方手册

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1515008.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【教学类-34-10】20240313 春天拼图(Midjounery生成线描图,4*4格拼图块)(AI对话大师)

作品展示&#xff1a; 背景需求&#xff1a; 利用华文彩云空心字&#xff08;粗胖字体。凑满9个拼图&#xff09;制作了3*3的拼图块 【教学类-34-09】20240310华文彩云学号拼图&#xff08;3*3格子浅灰底图 深灰拼图块&#xff09;&#xff08;AI对话大师&#xff09;-CSDN博…

3.2 RK3399项目开发实录-初次使用的环境搭建(物联技术666)

通过百度网盘分享的文件&#xff1a;嵌入式物联网单片… 链接:https://pan.baidu.com/s/1Zi9hj41p_dSskPOhIUnu9Q?pwd8qo1 提取码:8qo1 复制这段内容打开「百度网盘APP 即可获取」 1. 用户和密码 1.1. Ubuntu Desktop 系统 Ubuntu Desktop 系统开机启动后&#xff0c;自动登录…

使用Docker在windows上安装IBM MQ

第一步、安装wsl 详见我另一篇安装wsl文章。 第二步、安装centos 这里推荐两种方式&#xff0c;一种是从微软商城安装&#xff0c;一种是使用提前准备好的镜像安装&#xff0c;详见我另一篇windos下安装centos教程。 第三步、安装windows下的Docker desktop 详见我另一篇wind…

yum安装mysql 数据库tab自动补全

centos7上面没有mysql&#xff0c;它的数据库名字叫做mariadb [rootlocalhost ~]#yum install mariadb-server -y [rootlocalhost ~]#systemctl start mariadb.service [rootlocalhost ~]#systemctl stop firewalld [rootlocalhost ~]#setenforce 0 [rootlocalhost ~]#ss -na…

【LeetCode热题100】240. 搜索二维矩阵 II

一.题目要求 编写一个高效的算法来搜索 m x n 矩阵 matrix 中的一个目标值 target 。该矩阵具有以下特性&#xff1a; 每行的元素从左到右升序排列。 ‘每列的元素从上到下升序排列。 二.题目难度 中等 三.输入样例 示例 1&#xff1a; 输入&#xff1a;matrix [[1,4,7…

Pytorch入门-Transforms

文章目录 ComposeToTensorNormalizeResize 在PyTorch中&#xff0c;transforms是一个用于图像预处理和数据增强的模块&#xff0c;通常与torchvision库一起使用。torchvision提供了大量预先定义的transforms&#xff0c;它们可以方便地应用于图像数据&#xff0c;以进行预处理或…

strcpy的模拟实现

strcpy函数的定义&#xff1a; strcpy函数功能的解释&#xff1a; 会将源字符串中的 内容包括\0 拷贝到目标数组&#xff0c;所以源字符串必须以 \0 结束。 返回值为拷贝完成后的目标数组的首地址。 Const 是因为源字符串的内容不需要被修改&#xff0c;所以const最好。 strcpy…

程序员的三重境界:码农,高级码农、程序员!

见字如面&#xff0c;我是军哥&#xff01; 掐指一算&#xff0c;我在 IT 行业摸爬滚打 19 年了&#xff0c;见过的程序员至少大好几千&#xff0c;然后真正能称上程序员不到 10% &#xff0c;绝大部分都是高级码农而已。 今天和你聊聊程序员的三个境界的差异&#xff0c;文章不…

【DL经典回顾】激活函数大汇总列表(持续更新中...)

激活函数大汇总列表&#xff08;持续更新中…&#xff09; 欢迎来到我们深入探索神经网络核心组成部分——激活函数的系列博客。在人工智能的世界里&#xff0c;激活函数扮演着不可或缺的角色&#xff0c;它们决定着神经元的输出&#xff0c;并且影响着网络的学习能力与表现力…

Redirect相应重定向无法访问WEB-INF下的静态资源,可以跳到外部资源(比如www.baidu.com)

相应重定向无法访问WEB-INF目录下静态资源&#xff0c;WEB-INF目录下静态资源受保护。 访问外部资源 访问Servlet5.do&#xff0c;就跳到百度页面

14、Linux-Shell03:echo、printf和test命令

一、echo echo用于输出字符串 值得关注的地方 1、转义字符\。例如&#xff0c;echo "\"Hello,World\" is a classic sentence for programmer"。 2、read命令用于读取一行的输入&#xff0c;echo可以对输入进行输出 3、\n换行&#xff0c;\c不换行。需…

C编程基础四十分笔记

都是一些基础的C语言 一 输入一个整数&#xff0c;计算这个整数有几位二 编写程序计算一个分布函数三 输入一个字符串&#xff0c;再随便输入一个字母&#xff0c;判断这个字母出现几次四 求 1到10的阶乘之和五 求一个球体体积六 写一个链表&#xff0c;存1&#xff0c;2&#…

网络安全等级测评师考试培训可以参考哪些资料?

网络安全是国家安全的重要组成部分&#xff0c;也是企业安全的重中之重&#xff1b;而网络安全等级测评师则是守护这一安全领域的重要力量。所以专业的网络安全等级测评师是非常重要。作为专业的网络安全等保测评师&#xff0c;他们肩负着对信息系统进行安全评估、发现潜在风险…

系列五十六、如何下载历史版本的Maven?

一、如何下载历史版本的Maven&#xff1f; 1、Maven官网 https://maven.apache.org/download.cgi2、找到Other Releases选项# Maven 3 archives对应的链接url 3、https://archive.apache.org/dist/maven/maven-3/

【Swing】Java Swing实现省市区选择编辑器

【Swing】Java Swing实现省市区选择编辑器 1.需求描述2.需求实现3.效果展示 系统&#xff1a;Win10 JDK&#xff1a;1.8.0_351 IDEA&#xff1a;2022.3.3 1.需求描述 在公司的一个 Swing 的项目上需要实现一个选择省市区的编辑器&#xff0c;这还是第一次做这种编辑器&#xf…

python--类与面向对象-2

一、对象在文本中的输出 class Person: def __init__(self,name,agg,live_value,money): self.namename self.aggagg self.live_valuelive_value self.moneymoney def describe(): print(%s的攻击力是%s%(self.name,self.agg)) pPerson(bob,10,10000,100) bPerson(tony,…

Python之装饰器

一&#xff1a;作用 在函数名以及函数体不改变的前提下&#xff0c;给一个函数附加一些额外代码 二、语法 三、举例子 两个功能函数 test1&#xff0c; test2 遵循 “开放封闭原则”&#xff0c; 已经写好的代码&#xff0c;尽可能不要修改。 如果想要新增功能&#xff0c;…

YOLOv5目标检测学习(5):源码解析之:推理部分dectet.py

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、导入相关包与路径、模块配置1.1 导入相关的python包1.2 获取当前文件的相对路径1.3 加载自定义模块1.4 总结 二、执行主体的main函数所以执行推理代码&…

Linux中YUM仓库的配置

Linux软件包的管理 YUM仓库是什么YUM的常用命令修改YUM源其实CentOS7已经对YUM做了优化 YUM仓库是什么 之前传统RPM的管理方式 可以简单理解为写Java的时候不用Maven管理 jar包都要自己手动去导入 去下载 但是配置好YUM仓库 就放佛在用Maven管理Java项目 基于RPM包管理 能够从…

temu英国电商市场洞察:2月份商品销售数据分析Python数据采集Api

文章目录 引言可视化分析数据展示商品类目占比分析销售额分析价格区间占比分析各类目新品占比分析 写在最后 引言 在美国市场稳步增长基础上&#xff0c;Temu也不断加快全球步伐&#xff0c;现已进入47个国家&#xff0c;光23年9月份就进驻了10个国家&#xff0c;创造单月扩张国…