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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Java项目:48 ssm008医院门诊挂号系统+jsp(含文档)

作者主页&#xff1a;舒克日记 简介&#xff1a;Java领域优质创作者、Java项目、学习资料、技术互助 文中获取源码 项目介绍 本选题则旨在通过标签分类管理等方式实现 管理员&#xff1b;个人中心、药房管理、护士管理、医生管理、病人信息管理、科室信息管理、挂号管理、诊断…

如何解决word字体大小显示不一,部分文字无法显示/显式为空白?

问题重现 今天重启后打开word&#xff0c;显示如下&#xff1a; 从第1张图看&#xff0c;字体显示大小不同&#xff0c;第2张图&#xff0c;敲“满分”&#xff0c;无法显示“满”字&#xff0c;而且“分”的大小比一般字体要大。 我的解决方案 – 修复office 采用GPT的建议…

移除元素

文章目录 移除元素删除有序数组中的重复项移动零比较含退格的字符串有序数组的平方 移除元素 双指针 删除指定项且不改变顺序 def removeElement(nums: list[int], val: int) -> int:fast slow 0while fast < len(nums):if nums[fast] ! val:nums[slow] nums[fast]sl…

GEE:将数据设置为任何人可读

一些 Google Earth Engine(GEE) 平台的初学者在分享代码的时候&#xff0c;往往不会对代码中的数据设置成任何人可读。这会导致别人打开代码的时候无法正常运行代码&#xff0c;也就无法帮助你修改和调试代码。针对这个问题&#xff0c;本文记录了对 Assets 和 Imports 中的数据…

24年英语四六级报名,注意这5点否则报名失败

多地3月中旬后开始四六级报名&#xff0c;报名前注意这5点&#xff0c;否则报名失败&#xff01; 1、四六级名额有限?报名需要抢&#xff0c;没有抢到的考生可以提交“候补报名”&#xff0c;还有报名机会 2、有的学校则规定六级考到500分则不能再刷分。 3、很多大学的报名…

Tcl语言:基础入门(三)

相关阅读 Tcl语言https://blog.csdn.net/weixin_45791458/category_12488978.html?spm1001.2014.3001.5482 Tcl中的大括号 大括号{}可以使得被其包围的所有内容被解释为字面量&#xff0c;所以不会进行命令替换&#xff0c;转义符替换&#xff08;大部分情况的转义&#xff0…

视频监控管理系统EasyCVR平台设备增删改操作不生效是什么原因?

国标GB28181协议EasyCVR安防平台可以提供实时远程视频监控、视频录像、录像回放与存储、告警、语音对讲、云台控制、平台级联、磁盘阵列存储、视频集中存储、云存储等丰富的视频能力&#xff0c;平台支持7*24小时实时高清视频监控&#xff0c;能同时播放多路监控视频流&#xf…

气膜建筑是由什么材料制成的?PVDF膜材的革新应用值得期待吗?

随着科技的不断进步和发展&#xff0c;建筑行业也在不断涌现新型的建筑材料。气膜建筑作为其中一种创新的建筑膜材&#xff0c;在体育馆、运动场馆、展览厅等场所得到了广泛的应用。那么&#xff0c;究竟是什么材料构成了气膜建筑呢&#xff1f;轻空间小编将为您详细介绍。 气膜…

ELF技术贴|如何在开发板上实现对Java的支持

Java作为一种功能强大且广泛应用的编程语言&#xff0c;具有广泛的适应性和实用性。在ELF 1开发板上集成Java支持&#xff0c;无疑将赋予嵌入式开发者更广阔的选择空间&#xff0c;今天就为各位小伙伴详细解析如何在ELF 1开发板上成功部署和运行Java环境。 1.拷贝两个压缩包到E…

Caffeine本地缓存快速上手教程,通俗易懂

1. 概述 使用缓存的优点是可以减少直接访问数据库的压力。Caffeine是目前单机版缓存性能最高的&#xff0c;提供了最优的缓存命中率。用法和java中的map集合比较类似&#xff0c;底层使用一个ConcurrencyHashMap来保存所有数据&#xff0c;可以理解为一个增强版的map集合&…

基于SpringBoot的“留守儿童爱心网站”的设计与实现(源码+数据库+文档+PPT)

基于SpringBoot的“留守儿童爱心网站”的设计与实现&#xff08;源码数据库文档PPT) 开发语言&#xff1a;Java 数据库&#xff1a;MySQL 技术&#xff1a;SpringBoot 工具&#xff1a;IDEA/Ecilpse、Navicat、Maven 系统展示 系统首页界面图 宣传新闻界面图 志愿活动界面…

基于Spring Boot的校园管理系统 ,计算机毕业设计(带源码+论文)

源码获取地址&#xff1a; 码呢-一个专注于技术分享的博客平台一个专注于技术分享的博客平台,大家以共同学习,乐于分享,拥抱开源的价值观进行学习交流http://www.xmbiao.cn/resource-details/1767745870094217218

立式学习灯有什么讲究?大路灯原来要这样选,五大台灯分享!

立式学习灯作为近年来最适合照明的护眼家电&#xff0c;为用户提供了良好的光线环境&#xff0c;并且还能够减少光线带来的视觉疲劳感。然而&#xff0c;随着其销量的节节攀升商家为了谋取利润&#xff0c;市面上也涌现了很多劣质产品&#xff0c;这些产品普遍没有经过技术调教…

BEC报考公告 ,柯桥成人学商务英语,商务英语口语学校

BEC报考公告 报名时间 2024年3月12日10:00——2023年3月20日10:00 注册个人信息、上传电子照片并支付考试费用 考试时间 BEC初级&#xff1a;5月12日 BEC中级&#xff1a;5月25日 BEC高级&#xff1a;5月18日 笔试及口试具体时间以准考证为准 报名费用 初级&#xff1a;…

一键美化ppt的ai工具有哪些?推荐5款自动生成PPT的ai软件!

伴随着 ai 人工智能技术的发展&#xff0c;作为普通个体的我们&#xff0c;也有机会享受到技术发展带来的红利&#xff0c;比如用 ai 来润色文章&#xff0c;用 ai 来美化 ppt 演示文稿&#xff0c;用 ai 辅助进行数据分析等等&#xff0c;ai 的应用场景多种多样&#xff0c;使…

加速布局Wi-Fi及蓝牙市场!移远通信再推四款高性能模组新品

3月12日&#xff0c;全球领先的物联网整体解决方案供应商移远通信宣布&#xff0c;其已正式推出四款新型Wi-Fi和蓝牙模组新品&#xff0c;旨在继续致力于满足物联网行业不断升级的应用需求&#xff0c;为智慧家居、工业互联、储能、充电桩等各种场景提供一站式创新解决方案。 此…

【阿里云系列】-ACK的Java应用POD无法访问云数据库Redis

问题介绍 如下图所示&#xff0c;是ACK集群的POD访问阿里云的云数据库Redis&#xff0c;如何实现访问呢 配置步骤 要实现ACK集群内的所有POD都可以访问云数据库Redis&#xff0c;则需要在Redsi的白名单里增加源IP或网段&#xff0c;如下图所示 注意&#xff1a; 以上添加…

朴素贝叶斯算法基础——案例:对新闻进行分类

贝叶斯公式 朴素&#xff1a;假设特征与特征之间相互独立 朴素贝叶斯算法&#xff1a;朴素贝叶斯 应用场景&#xff1a;文本分类&#xff08;单词作为特征&#xff09; 拉普拉斯平滑系数 Ni&#xff1a;F1词在C类别所有文档中出现的次数 N&#xff1a;所属类别C下的文档所…

C语言 指针(4) qsort函数

目录 前言 一、回调函数 二、qsort函数 2.1 使用qsort函数排序整型数据 2.2 使用qsort排序结构数据 三、qsort函数的模拟实现 总结 前言 今天我们主要来学习一下C语言中的qsort排序函数。 一、回调函数 回调函数就是⼀个通过函数指针调用的函数。 如果你把函数的指针&a…

PMP考试心得,与大家共勉

本人刚刚通过PMP考试&#xff0c;有一些自己的经历&#xff0c;写出来欢迎已经是PMP的兄弟们指正&#xff0c;希望能给正在PMP之路上奔跑的人们一些帮助。 其实很早就听说过PMP认证考试了&#xff0c;但是一直工作很忙没有时间来投入学习考试。因此一直拖到今年夏天才有时间参加…