ESP32上的串口输出
ESP32上的串口输出
了解串口(UART/USART)
串口通信协议实例
串口通信协议是在计算机、微控制器或其他设备之间传输数据的一种方式。串口是指外设和处理器之间通过数据信号线、地线和控制线等,按位进行传输数据的一种通讯方式。尽管传输速度比并行传输低,但串口可以在使用一根线发送数据的同时用另一根线接收数据。 这种通信方式使用的数据线少,在远距离通信中可以节约通信成本。在Arduino项目中,串口通信非常常见也非常重要,可以用于设备间的数据传输、调试信息的输出,以及与计算机或其他串行设备的通信。
串口通信基本概念
串口通信使用TX(发送)和RX(接收)两个引脚来进行数据的发送和接收。Arduino和许多其他支持Arduino固件的板子都有内置的串行通信功能,可以通过USB接口与计算机通信,也可以使用数字引脚(如0和1)与其他设备进行串行通信。
串口通信介绍
串口通信协议定义了在串口上进行数据交换的规则和格式。常见的串口通信协议包括ASCII协议、Modbus协议、RS-232协议等。协议规定了数据的帧结构、数据格式、校验方式等,确保发送和接收双方按照相同的规则进行数据交换,从而实现数据的正确传输和解析。 串口通信是一位一位地传输,每传输一个字符总是以起始位开始,以停止位结束,字符之间没有固定的时间间隔要求。每一个字符的前面都有一位起始位(低电平),后面由 7 位数据位组成,接着是一位校验位,最后是停止位。停止位后面是不定长的空闲位,停止位和空闲位都规定为高电平。
串口通信参数包括波特率(Baud Rate)、数据位(Data Bits)、校验位(Parity Bits)、停止位(Stop Bits)等。这些参数描述了传输数据的基本规格。例如,波特率定义了数据传输的速率,数据位确定每个数据字节中包含的位数,校验位用于数据的差错检测,停止位表示数据传输结束的标志等。
- 波特率:衡量通信速度的参数,它表示每秒钟传送的 bit 的个数。
- 数据位:衡量通信中实际数据位的参数,表示一个信息包里包含的数据位的个数。
- 停止位:用于表示单个信息包的最后位,典型值为 1、1.5 和 2 位。由于数据是在传输线上传输的,每个设备都有自己的时钟,很有可能在通信过程中出现不同步,停止位不仅仅表示传输的结束,还能提供校正时钟同步的机会。停止位的位数越多,不同时钟同步的容忍程度越大,但是数据传输率也越慢。
- 奇偶检验位:表示一种简单的检查错误的方式。
串口工作模式

串口工作模式分为三种:单工、全双工模式和半双工模式。
- 单工:在通信的任意时刻,信息只能由 A 传到 B,或B传到A;
- 半双工:在通信的任意时刻,信息即可由 A 传到 B,又能由 B 传到 A,但同时只能有一个方向上的传输存在;
- 全双工:在通信的任意时刻,通信线路上存在 A 到 B 和 B 到 A 的双向信号传输;
串口通信的作用及优势
串口是计算机和外部设备之间最常见的通信接口之一,具有重要的作用和广泛的应用。在计算机领域,串口的重要性体现在以下几个方面:
- 数据传输:串口是一种常用的数据传输接口。通过串口,计算机可以与各种外部设备进行数据交换和通信。无论是传感器、执行器、显示器、打印机还是其他外部设备,串口通信都可以实现数据的传输和控制。
- 远程控制和监控:串口通信被广泛应用于远程控制和监控领域。通过串口,计算机可以远程控制设备的动作,并实时监测设备的状态和数据信息。这在工业控制、自动化系统、远程监控等场景中具有重要的作用。
- 调试和故障排查:串口通信是调试和故障排查的重要工具。通过串口,计算机可以与嵌入式系统、单片机等进行通信,实时监控和调试程序,输出调试信息,进行错误定位和排查,并对系统进行状态监测和故障诊断。
- 硬件连接:串口可以作为计算机与各种外部设备之间的连接桥梁。通过串口,可以连接和控制各类外部设备,如传感器、执行器、外围设备等。串口能够提供稳定的数据传输和双向通信功能。
- 通信协议:串口通信协议是计算机与外部设备之间数据传输的规范和约定。通过定义不同的协议,可以实现不同设备之间的数据交互和通信。常见的串口通信协议有UART、RS-232、RS-485等。
总之,串口对于计算机和外部设备之间的通信具有重要的作用。它是数据传输、远程控制和监控、调试和故障排查的关键工具,是计算机与外部设备连接和通信的桥梁。
函数讲解
在软件层面,Arduino固件提供了Serial
库,用于实现串行通信。这个库提供了多种方法来发送和接收数据。
初始化串口
ESP32S3有三个串口,分别是Serial,Serial1, Serial2,其中Serial用作串口下载和调试,在串口充足的情况下应当优先使用Serial1和Serial2。 使用Serial.begin(baudRate)
方法初始化串行通信,baudRate
指定了数据传输的速率(比特率),例如9600、115200等。这个速率必须和接收方保持一致。
还有一个比较常用的是Serial.begin(unsigned long baud, uint32_t config, int8_t rxPin, int8_t txPin)
#define RX1 12
#define TX1 13
void setup()
{
Serial.begin(115200); // 设置波特率为115200
Serial.begin(460800, SERIAL_8N1, RX1, TX1);
}
发送数据
可以使用Serial.print()
和Serial.println()
发送数据。print
方法发送数据但不添加换行符,而 println
会在数据末尾添加换行符。
void loop()
{
for(int i=0; i<=100; i++)
{
Serial.println("Hello, world!"); // 发送字符串并自动换行
Serial.println(i);
Serial.println("当前的i是"+String(i))
delay(1000); // 每秒发送一次
}
}
也可以使用Serial.write(const uint8_t *buffer, size_t size)
来发送byte类型的数组
uint8_t send_data[] = {0x55, 0x55, 0x01, 0x12};
void loop()
{
Serial1.write(send_data, sizeof(send_data));
}
接收数据
使用Serial.available()
检查是否有数据可读,如果此函数返回0,表示没有数据可读。如果有,Serial.read()
可以用来读取一个字节的数据.
void loop()
{
if (Serial1.available() > 0)
{
char received = Serial.read(); // 读取并存储一个字节的数据
Serial1.print("Received: ");
Serial1.println(received); // 显示接收到的数据
}
}
而Serial.readbytes()
则可以直接把读取到的数据存放到数组中
void ProcessOPiData()
{
uint8_t data[11];
Serial2.readBytes(data, sizeof(data));
......
}
高级读取
Serial.readString()
: 读取串口接收到的字符,直到遇到超时。这个方法依赖于setTimeout()
设定的超时时间。Serial.readStringUntil(terminator)
: 读取串口数据,直到遇到指定的终止字符或超时。Serial.parseInt()
: 从串口读取数据并解析为int
类型。这对于接收数字类型的数据非常方便。Serial.parseFloat()
: 从串口读取数据并解析为float
类型。适用于需要处理浮点数的情况。
串口使用实例(一)
不太建议使用这板子的串口中断
#define RX
#define TXPIN 10
uint8_t dataSent[100];
//Serial、Serial1、Serial2 分别对应了 UART0、UART1 和 UART2。
void setup()
{
// 初始化串口通信波特率
//串口0初始化
Serial.begin(115200);
//初始化串口1,波特率115200,SERIAL_8N1=8数据位无校验位1停止位 RX引脚为9 TX引脚为10
Serial1.begin(115200, SERIAL_8N1, RXPIN, TXPIN);
//为串口1设置回调函数
Serial1.onReceive(onReceiveFunction);
//串口1发送数据 hello LCKFB,发送12个字节
Serial1.write("hello LCKFB", 12);
}
串口使用实例(二)
收发数组,移位,合并,数据包
见视频