UART
UART,即通用异步收发传输器(Universal Asynchronous Receiver/Transmitter),是一种异步收发传输器,是电脑硬件的一部分,它将要传输的资料在串行通信与并行通信之间加以转换。作为把并行输入信号转成串行输出信号的芯片,UART通常被集成于其他通讯接口的连接上。
UART用于异步通信,异步通信以一个字符为传输单位,通信中两个字符之间的时间间隔是不固定的,然而在同一个字符中的两个相邻位之间的时间间隔是固定的。因此,异步通信的特点就是:字符间异步,字符内部各位同步。
UART是一种接口,连接CPU和串行设备,以实现两者间的串行通信。UART既可作为接收器,也可作为发送器。UART在发送数据前,先发送起始位,然后发送数据位,数据位可以是5~8位,在发送完数据位后,可以发送可选的奇偶校验位,最后发送停止位。如果在字符发送过程中发生错误,则通过停止位来通知对方。
以上介绍来自文心一言。
在我们之前的文章中也有介绍UART,总之我们知道串口通信最主要的就是统一通信双方的配置:波特率,数据位,停止位,校验位这几个。
常用的配置就是9600的波特率,8位数据位,1位停止位,无校验。
使用UART
我们来看看编程指南中的UART使用流程。
首先先配置通信的参数。
有两种配置方法,一种是一次性全部配完,另一种是分开一个个配置。
我们先看一次性配置。
#include "driver/uart.h"
根据上面的示例,我们按照顺序看看这个结构体的成员分别代表什么意思。
第一个是波特率,直接传入数字即可。
第二个数据位,可选的有UART_DATA_5_BITS
、UART_DATA_6_BITS
、UART_DATA_7_BITS
、UART_DATA_8_BITS
这几个。
第三个是校验位,一般就是上面示例中的无校验。
第四个是停止位,可选的有UART_STOP_BITS_1
(1 个停止位)、UART_STOP_BITS_1_5
(1.5 个停止位,仅适用于 5 数据位)和 UART_STOP_BITS_2
(2 个停止位)这几个。
第五个是硬件流控制,一般不使用,选择UART_HW_FLOWCTRL_DISABLE
(禁用流控制)即可。
第六个是RTS的阈值(我也不懂干啥的),不配置就行。
有了配置的结构体之后我们就可以使用下面的函数进行配置了。
然后在官方手册里我们得知,一共有三个UART。
然后我手上这款ESP32-S3是用UART_NUM_0来烧录程序的,因此我能用的是UART_NUM_1和UART_NUM_2。
除了一次性配置,还可以分开来一个个配置。
配置完后下一步是分配管脚。
一般来说我们最后两个参数是不需要的,给-1就行。
下一步是安装驱动程序。
它这个函数的参数还蛮复杂的。
第一个参数就是端口号UART_NUM_n。
第二个和第三个就根据我们通信的数据的大小填写就行,不确定的话一般填个1024。
第四个给个0就行。
第五个给个NULL。
第六个也给个0。
上面都配置完之后我们就可以开始发送与接收了。
使用这个函数就可以发送数据了。
读取数据用下面这个函数。
发送数据其实还好说,啥时候发送都行。
问题在于接收数据,我们得等有数据才能接收,那么最好的办法就是用中断的方法,等有数据发来的时候我们就进入中断读取数据。
但是遗憾的是我没有找到一接收到数据就中断的中断掩码。
因此我们使用别的方法来检测中断。
那就是询问检测,我们不断的读取数据,如果读取的数据长度大于0,则表示有数据发来。
这样又有问题,如果我们在主循环里这样询问,会影响我们其他逻辑的进行。
但是别忘了,我们的ESP-IDF天然支持FreeRTOS,因此我们可以直接创建一个任务,在这个任务里执行不断读取数据的死循环。
知道该怎么办之后我们就开始敲代码吧。
完整示例代码
#include <stdio.h>
#include "driver/uart.h"
#include <unistd.h>
#include <string.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
void UART_GetDate(void){
uint8_t data[1024]={0};
while(1){
int size = uart_read_bytes(UART_NUM_1, data, 1024, 10 / portTICK_PERIOD_MS); //接收数据,等待超时时间为10ms
if( size > 0 ){
data[size] = 0; //将串口数据的最后一个设置为0,形成字符串
uart_write_bytes(UART_NUM_1,data,size); //把收到的数据再发送出去
uart_flush(UART_NUM_1); //清空缓冲区
}
}
}
void app_main(void){
printf("Hello world\r\n");
uart_config_t uart_initer={
.baud_rate=9600, //波特率9600
.data_bits=UART_DATA_8_BITS, //8位数据位
.flow_ctrl=UART_HW_FLOWCTRL_DISABLE, //无硬件流控制
.parity=UART_PARITY_DISABLE, //无校验位
.stop_bits=UART_STOP_BITS_1 //1位停止位
};
uart_param_config(UART_NUM_1,&uart_initer);
uart_set_pin(UART_NUM_1,8,9,-1,-1); //设置引脚,tx为8,rx为9
uart_driver_install(UART_NUM_1,1024,1024,0,NULL,0); //安装驱动
xTaskCreate(UART_GetDate, "UART_GetDate", 1024*2, NULL, configMAX_PRIORITIES, NULL); //FreeRTOS创建UART接收数据的任务
const char* data="hello world\r\n";
while(1){
uart_write_bytes(UART_NUM_1, data, strlen(data)); //每隔3s发送一次hello world
sleep(3);
}
}
可以正常的接收和发送数据。
这个串口助手随便百度就能搜到下载使用即可。
也可以参考我之前的文章,自己动手写一个串口助手。