esp32UART串口外设(Arduino)

news2025/1/19 12:58:20

通用异步接收器/发送器 (UART)

介绍

通用异步接收器/发送器 (UART) 是一种硬件功能,它使用广泛采用的异步串行通信接口(如 RS232、RS422 和 RS485)处理通信(即时序要求和数据成帧)。UART提供了一种广泛采用且廉价的方法,可实现不同设备之间的全双工或半双工数据交换。

ESP32 芯片有 3 个 UART 控制器(也称为端口),每个控制器都具有一组相同的寄存器,以简化编程并提高灵活性。

每个UART控制器都可独立配置波特率、数据位长度、位排序、停止位数、奇偶校验位等参数。所有常规UART控制器都与不同制造商的UART设备兼容,还可以支持红外数据关联(IrDA)协议。

官方手册

功能概述

本文介绍了如何使用 UART 驱动的功能和数据类型在 ESP32 和其他 UART 设备之间建立通信。典型的编程工作流程分为以下几个部分:

  1. 设置通信参数 - 设置波特率、数据位、停止位等。

  2. 设置通信引脚 - 分配用于连接到设备的引脚

  3. 安装驱动程序 - 为 UART 驱动程序分配 ESP32 的资源

  4. 运行 UART 通信 - 发送/接收数据

  5. 使用中断 - 在特定通信事件上触发中断

  6. 删除驱动程序 - 如果不再需要 UART 通信,则释放已分配的资源

步骤 1 至 3 包括配置阶段。第 4 步是 UART 开始运行的地方。步骤 5 和 6 是可选的。

UART 驱动程序的函数使用 标识每个 UART 控制器。以下所有函数调用都需要此标识。

基于Arduino的UART串口概述

ESP323个UART串口,分别是UART0UART1UART2,其中UART0用于程序下载和信息交互,UART1专门用于Flash的读写

串口的初始化

void HardwareSerial::begin(unsigned long baud, uint32_t config, int8_t rxPin, int8_t txPin, bool invert, unsigned long timeout_ms, uint8_t rxfifo_full_thrhd)
  • unsigned long baud:波特率,表示每秒传输的位数。
  • uint32_t config:配置位,用于设置串口通信的一些选项,如数据位、停止位和奇偶校验等。
  • int8_t rxPin:接收引脚编号,用于连接接收器。
  • int8_t txPin:发送引脚编号,用于连接发射器。
  • bool invert:是否反转输入信号,如果为 true,则在接收时将信号反转。
  • unsigned long timeout_ms:超时时间(毫秒),当没有数据接收或发送时,该函数将等待指定的时间。
  • uint8_t rxfifo_full_thrhd:接收缓冲区满阈值,当接收缓冲区达到此值时,将触发中断。

以下是一个示例代码,演示如何使用 HardwareSerial::begin() 函数进行串口通信的初始化:

#include <HardwareSerial.h>

// 创建硬件串口对象
HardwareSerial mySerial;

void setup() {
  // 初始化串口通信
  mySerial.begin(9600, SERIAL_8N1, RX_PIN, TX_PIN, false, 1000);
}

void loop() {
  // 检查是否有可用的数据
  if (mySerial.available()) {
    // 读取一个字节的数据
    char receivedChar = mySerial.read();
    // 处理接收到的数据
    // ...
  }
}

在Arduino中,还可以使用Serial对象来处理串口通信。默认情况下,Arduino有3个串口对象:Serial, Serial1Serial2

  • Serial:默认的串口对象
  • Serial1:第二个串口对象
  • Serial2:第三个串口对象

这些串口对象具有相同的方法和属性,可以用于配置串口通信、发送数据和接收数据等操作。以下是一个简单的示例代码,演示如何使用这些串口对象进行串口通信:

void setup() {
  // 初始化串口通信
  Serial.begin(9600);
  Serial1.begin(9600);
  Serial2.begin(9600);
}

void loop() {

}

串口的打印输出函数

Serial.print("hello world");
Serial.printf("hello world");
Serial.println("hello world");

Serial.print()Serial.println()Serial.printf()函数在Arduino编程中都被用于向串口输出数据,但它们之间存在一些主要的区别:

  1. Serial.print():这个函数会将参数转换为字符串并打印到串口,参数之间不会自动添加分隔符或换行符。
  2. Serial.println():此函数除了具有Serial.print()的功能外,还会在输出的末尾自动添加一个换行符。如果参数是字符串、数组或数字,则会将其转换为字符串然后输出。此外,当传入的参数是单个字符时,该函数还会输出该字符的ASCII编码值和一个换行符。
  3. Serial.printf():这个函数与C语言中的printf()函数类似,允许你使用格式化字符串来指定输出数据的格式。与前两者不同,Serial.printf()会将格式化后的字符串直接发送到串口,而不是逐个字符地打印。
void setup() {
  // 初始化串口通信
  Serial.begin(9600);
}

void loop() {
  // 使用Serial.print()函数打印数据
  Serial.print("Hello, ");
  Serial.print("World!");
  
  // 使用Serial.println()函数打印数据
  Serial.println("Hello, World!");	//有回车换行
  Serial.println();	//回车换行
  Serial.println(14,HEX);	//以16进制打印输出数值14
  
  // 使用Serial.printf()函数打印数据
  int dat= 15;
  Serial.printf("Sensor Value: %d", dat);
}

串口的单字发送与接收

串口写单个字节
void Serial.write(uint8_t byte)
  • uint8_t byte:串口待发送的字节数据

在Arduino中使用Serial.write()函数来向串口写入单个字节示例:

void setup() {
  // 打开串口
  Serial.begin(9600);
}

void loop() {
  // 要发送的字节数据
  byte data = 'A';

  // 将字节数据写入串口
  Serial.write(data);

  // 延时一段时间,以便观察输出结果
  delay(1000);
}
检测串口数据接收长度并读取串口缓冲区数据
int Serial.available()
int Serial.read()
  • Serial.available()函数。该函数返回可用的字节数,即从串口缓冲区中可以读取的数据长度。
  • Serial.read()函数。该函数从串口缓冲区中读取一个字节的数据,并将其作为整数返回。

示例:

void setup() {
  // 打开串口
  Serial.begin(9600);
}

void loop() {
  // 检查是否有可用数据
  int availableBytes = Serial.available();

  // 如果有可用数据,则读取并处理
  if (availableBytes > 0) {
    // 读取数据
    char receivedData = Serial.read();

    // 处理数据(例如打印到串口监视器)
    Serial.print("Received data: ");
    Serial.println(receivedData);
  }
}

Serial.available()函数用于检测串口缓冲区中可用的字节数。如果返回值大于0,表示有可用数据,然后使用Serial.read()函数读取一个字节的数据,并进行相应的处理。

串口多字节发送与接收

串口写多个字节
size_t write(const char * buffer, size_t size)
  • buffer:要发送的字节数组指针
  • size:数组的长度
  • 函数的返回值是写入的字节数

Serial.write() 函数发送多个字节数组示例:

#include <Arduino.h>

void setup() {
  // 初始化串口通信
  Serial.begin(9600);
}

void loop() {
  // 定义要发送的字节数组
  byte data[] = {0x01, 0x02, 0x03, 0x04};
  
  // 获取字节数组的长度
  int length = sizeof(data) / sizeof(data[0]);
  
  // 通过串口发送字节数组
  Serial.write(data, length);
  
  // 延时一段时间,以便观察输出结果
  delay(1000);
}

串口读多个字节
size_t HardwareSerial::read(uint8_t *buffer, size_t size)
  • buffer 读取数据保存的数据缓冲区
  • size 将要读取的数据长度,单位为字节

要通过串口读取多个字节,可以使用Serial.available()函数来检查可用的字节数,然后使用Serial.read(buffer, size)函数读取多个字节。以下是一个示例代码:

#include <Arduino.h>

void setup() {
  // 初始化串口通信
  Serial.begin(9600);
}

void loop() {
  if (Serial.available() > 0) {

    // 创建字节数组来存储读取到的字节
    byte receivedData[64];

    delay(10);

    // 读取可用的字节数
    int  numBytes = Serial.available();

    // 逐个读取字节并存储到字节数组中
    Serial.read(receivedData,numBytes);
    // 处理接收到的数据
    //pas
  }
}


实训项目案例

1.单字节数据接收处理在发送

功能要求是接收通过串口(Serial)发送的数据,并将接收到的每个字节数据加1后重新发送回去。
代码:

#include <Arduino.h>

void setup() {
  Serial.begin(115200);
 
}

void loop() {
  unsigned char dat;
  if(Serial.available()>0){
    dat=Serial.read();
    dat++;
    Serial.write(dat);
  }
}

效果:
在串口助手中发送1接收到2
在这里插入图片描述

2.多字节数据接收处理在发送

功能要求接收数据,并发送字符串的大小和字符串

代码:

#include <Arduino.h>

void setup() {
  // 初始化串口通信
  Serial.begin(9600);
}

void loop() {
  if (Serial.available() > 0) {

    // 创建字节数组来存储读取到的字节
    byte receivedData[64];

    delay(10);

    // 读取可用的字节数
    int  numBytes = Serial.available();

    // 逐个读取字节并存储到字节数组中
    Serial.read(receivedData,numBytes);
    // 处理接收到的数据(这里只是简单地打印出来)
    Serial.printf("Received len:%d",numBytes);
    Serial.println();
    Serial.print("Received data: ");
    Serial.write(receivedData, numBytes);
    Serial.println();
    Serial.print("-----------------------");
    Serial.println();
  }
}

效果:
在这里插入图片描述

3.串口字节命令控制灯光开关

#include <Arduino.h>
#define d2 2

void setup() {
    //初始化灯光
    pinMode(d2,OUTPUT);
    //初始化UART
    Serial.begin(115200);
}

void loop() {
  //灯光的控制
  if(Serial.available()>0)
  {
    uint8_t cmd=0;
    cmd=Serial.read();
    switch(cmd)
    {
        case 0xA1:
            digitalWrite(d2,HIGH);
            Serial.println("d2 is ON!");
            break;
        case 0xA2:
            digitalWrite(d2,LOW);
            Serial.println("d2 is OFF!");
            break;
        default:
            Serial.println("输入命令错误");
    }
  }
}

在这里插入图片描述
发送A1,d2被点亮

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

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

相关文章

torch.nn.CrossEntropyLoss()

torch.nn.CrossEntropyLoss(weight=None,size_average=None,ignore_index=-100,reduce=None,reduction=mean,label_smoothing=0.0) 计算过程 nn.CrossEntropyLoss()=nn.LogSoftmax()+nn.NLLLoss() import torch import torch.nn as nnloss_func = nn.CrossEntropyLoss() pre…

Windows11快速安装Android子系统

很多小伙伴想在电脑运行一下安卓程序&#xff0c;或则上班用手机摸鱼不方便&#xff0c;用电脑又没有想要的手机软件&#xff0c;那么怎么用电脑来安装安卓软件呢&#xff1f; 首先设置地区 安装Android子系统的前提需要安装 Amazon Appstore 这个应用&#xff0c;内地不能下载…

【CV】计算两个向量的夹角,并使用 OpenCV 可视化弧线

背景 基于人体/动物&#xff0c;骨骼点数据&#xff0c;计算关节角度 1. 原理 计算两个向量的夹角&#xff0c;我们已三个点为例&#xff0c;BA 向量和BC向量&#xff0c;求 B 的角度。若为四个点&#xff0c;延长交叉即可。 2. 效果 效果图如下 3. 核心代码 def comput…

vue2源码解析之第一步(对数据进行劫持)

###环境搭建 第一步 创建项目&#xff1a; npm init -y 第二步 安装对应的插件&#xff1a; npm i rollup rollup-plugin-babel babel/core babel/preset-env --save-dev 第三步 全局下创建rollup配置文件 rollup.config.js import babel from rollup-plug…

JVM工作原理与实战(十一):双亲委派机制

专栏导航 JVM工作原理与实战 RabbitMQ入门指南 从零开始了解大数据 目录 专栏导航 前言 一、双亲委派机制 1.双亲委派机制详解 2.父类加载器 3.双亲委派机制的主要作用 二、双亲委派机制常见问题 总结 前言 ​JVM作为Java程序的运行环境&#xff0c;其负责解释和执行字…

CDN的介绍以及加速内容传输原理

目前在公司的开发过程中&#xff0c;发现很多存储在oss的静态资源&#xff08;图片&#xff0c;安装包&#xff09;的链接中域名都使用了cdn域名&#xff0c;后面了解到这个cdn域名的主要作用是加速资源的访问&#xff0c;于是抽空了解了一下CDN加速原理。 目前使用得比较多的是…

【大厂算法面试冲刺班】day0:数据范围反推时间复杂度

常见算法的时间复杂度 规定n是数组的长度/树或图的节点数 二分查找&#xff1a;O(logn) 双指针/滑动窗口&#xff1a;O(n) DFS/BFS&#xff1a;O(n) 构建前缀和&#xff1a;O(n) 查找前缀和&#xff1a;O(1) 一维动态规划&#xff1a;O(n) 二维动态规划&#xff1a;O(n^2) 回溯…

Java后端返回的MySQL日期数据在前端格式错误的解决方法,区分jackson和fastjson

写在前面 在写web项目的时候经常会遇到后端返回的MySQL日期数据(date)类型在前端显示不正确的情况&#xff0c;有的时候会出现一串数字的时间戳&#xff0c;有的时候显示为日期晚了一天。 这是因Json给前端返回数据的时候格式问题造成的 解决方法 其实总结起来就是一句话在…

【Docker】私有仓库

目录 1.搭建 2. 上传镜像 3.拉取镜像 1.搭建 1.拉取私有仓库的镜像 docker pull registry 2.创建私有仓库容器 docker run -id --nameregistry -p 5000:5000 registry 3.打开浏览器,输入地址&#xff08;http:私有仓库服务器ip:5000/v2/_catalog&#xff09; 出现如图表示私…

Python - 深夜数据结构与算法之 Two-Ended BFS

目录 一.引言 二.双向 BFS 简介 1.双向遍历示例 2.搜索模版回顾 三.经典算法实战 1.Word-Ladder [127] 2.Min-Gen-Mutation [433] 四.总结 一.引言 DFS、BFS 是常见的初级搜索方式&#xff0c;为了提高搜索效率&#xff0c;衍生了剪枝、双向 BFS 以及 A* 即启发式搜索…

1.1数算选择题(循环队列、二叉树、查找、堆、顺序表、生成树、哈夫曼树、排序)

循环队列 front&#xff1a;头指针 rear&#xff1a;尾指针 m&#xff1a;循环队列的长度 元素个数&#xff08;rear-frontm&#xff09;%m 19-114048%408 11-194032%4032 二叉树 入度出度&#xff0c;n-1n0n1n2-1n12n2,有n21n0,对于完全二叉树&#xff0c;度为1的节点要…

挑战Transformer的新架构Mamba解析以及Pytorch复现

今天我们来详细研究这篇论文“Mamba:具有选择性状态空间的线性时间序列建模” Mamba一直在人工智能界掀起波澜&#xff0c;被吹捧为Transformer的潜在竞争对手。到底是什么让Mamba在拥挤的序列建中脱颖而出? 在介绍之前先简要回顾一下现有的模型 Transformer:以其注意力机制而…

重学JavaScript高级(八):ES6-ES12新增特性学习

ES6-ES12新增特性学习 ES6–对象字面量增强 属性的简写方法的简写计算属性名 let name "zhangcheng" //我想让sum作为obj的key值 let objKey "sum" let obj {//属性名的简写name//等同于name:name//方法的简写running(){}//等同于running:function()…

RT-DETR 更换骨干网络之 MobileNetV3 | 《搜寻 MobileNetV3》

论文地址:https://arxiv.org/abs/1905.02244 代码地址:https://github.com/xiaolai-sqlai/mobilenetv3 我们展示了基于互补搜索技术和新颖架构设计相结合的下一代 MobileNets。MobileNetV3通过结合硬件感知网络架构搜索(NAS)和 NetAdapt算法对移动设计如何协同工作,利用互…

使用 Open3D 的 3D LiDAR 可视化:用于自动驾驶的 2D KITTI 深度框架-含数据集+源码

3D LiDAR传感器(或)3维 光探测和测距是一种先进的发光仪器,能够像我们人类一样在3维空间中感知现实世界。这项技术尤其彻底改变了地球观测、环境监测、侦察以及现在的自动驾驶领域。它提供准确和详细数据的能力有助于增进我们对环境和自然资源的理解和管理。 在这篇权威研究…

仿stackoverflow名片与b站名片实现(HTML、CSS)

目录 前言一、仿stackoverflow名片HTMLCSS 二、仿b站名片HTMLCSS 素材 前言 学习自ACwing - Web应用课 一、仿stackoverflow名片 HTML <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport&…

【hyperledger-fabric】使用couchDB

简介 本文章主要参考来自于官方文档使用CouchDB以及 https://www.bilibili.com/video/BV1Li4y1f7ex/?spm_id_frompageDriver&vd_source2c5f2831e1c63d3a20045b167ae044e6 B站视频&#xff0c;还是非常感谢up主提供了学习的思路。 为什么要使用couchDB&#xff1f; 原文…

如何将Redis、Zookeeper、Nacos配置为Windows系统的一个服务

说明&#xff1a;当我们在Windows上开发时&#xff0c;不可避免的会用到一些中间件&#xff0c;如Redis、Zookeeper、Nacos等等&#xff0c;当在项目中使用到本地的这些服务器时&#xff0c;我们需要把本地的服务器启动&#xff0c;会开启下面这样的一个窗口。 Redis服务器&am…

vscode使用npm安装element-UI并添加router路由

npm安装vue&#xff0c;添加淘宝镜像-CSDN博客 elementUI安装与配置 安装可以看我上一篇文章 vscode控制台输入指令 npm i element-ui -S 安装完成后在目录结构打开下图文件 可以看到多了一行elementui就代表安装成功了 下面是项目常用的结构 安装完成后需要启用elementU…

稀疏矩阵的三元组表示----(算法详解)

目录 基本算法包括&#xff1a;&#xff08;解释都在代码里&#xff09; 1.创建 2.对三元组元素赋值 3.将三元组元素赋值给变量 4.输出三元组 5.转置&#xff08;附加的有兴趣可以看看&#xff09; 稀疏矩阵的概念&#xff1a;矩阵的非零元素相较零元素非常小时&#xff…