ESP32 Uart串口控制器

前言

嵌入式应用通常要求一个简单的并且占用系统资源少的方法来传输数据。通用异步收发传输器 (UART) 即可以满足这些要求,它能够灵活地与外部设备进行全双工数据交换。ESP32 芯片中有3个UART控制器可供使用,并且兼容不同的UART设备。另外,UART还可以用作红外数据交换 (IrDA) 或 RS-485 调制解调器。

主要特性
  • 支持3路UART,发送与接收FIFO共享RAM
  • 支持5/6/7/8位数据长度
  • 支持RS485、IrDA协议
  • 支持DMA高速通信
  • 支持UART唤醒模式
UART架构

在这里插入图片描述

  • 架构图中主要分为发送模块与接收模块,发送接收FIFO缓存数据,FIFOCtrl用于控制FIFO的读写,为了提高数据的传输效率,可以使用DMA方式进行数据发送和接收
    注意:UART处于睡眠Light-Sleep状态时,会通过Wakeup_Ctrl计算rxd_in的脉冲个数,当Rxd边沿变化次数大于阈值时,传输给RTC模块来唤醒UART控制器;目前仅UART0UART1具备Light-Sleep功能,且rxd_in不能通过GPIO交换矩阵,只能通过IO_MUX输入
功能描述
UART共享RAM图
  • 3路UART控制器FIFO共享1K的RAM空间,可以通过配置UART_RX_SIZE对指定UART的FIFO进行扩展【最大1024Byte】,提高整体的利用率;当UART控制器不使用时,可以通过配置UART_MEM_PD来使RAM进入低功耗状态

在这里插入图片描述

波特率自检测
  • 通过置位UART_AUTOBAUD_EN使能波特率自动检测,接收端连续检测多个数据包,获取最小的高低H/L电平脉冲宽度,来确认发送方的波特率
    在这里插入图片描述

注意:UART2 没有 Tx_FIFO 以及 Rx_FIFO 的复位寄存器。UART1 的 UART1_TXFIFO_RST 和 UART1_RXFIFO_RST 会影响 UART2 的工作。因此,只有在 UART2 的 Tx_FIFO 和 Rx_FIFO 中没有数据时,才可以置位这两个寄存器。

数据帧
  • 数据一桢从起始位START开始,并以停止位STOP结束;STOP位可以通过UART_STOP_BIT_NUM、UART_DL1_EN 和 UART_DL0_EN来配置1/1.5/2/3位宽;数据位通过UART_BIT_NUM可配置5-8位;UART_PARITY 选择奇校验或偶校验;
  • TX_FIFO中数据发送完成后会产生UART_TX_DONE_INT中断;置位UART_TXD_BRK寄存器可设置发送完成后可继续发送NULL数据帧;数据帧可通过UART_TX_IDEL_NUM配置最小间隔
    在这里插入图片描述
流控

UART 控制器有两种数据流控方式:硬件流控和软件流控。硬件流控主要通过输出信号 rtsn_out 以及输入信号dsrn_in 进行数据流控制。软件流控主要通过在发送数据流中插入特殊字符以及在接收数据流中检测特殊字符来实现数据流控功能。

UART DMA(UDMA)控制器
  • ESP32的3个UART接口共用2个UDMA控制器,通过UHCI×_UART_CE寄存器选择配置。

在这里插入图片描述

寄存器列表
配置寄存器描述
UART_CONF0_REG配置寄存器0,选择配置时钟源
UART_CONFIG1_REG配置寄存器1,设置接收超时与流控功能
UART_CLKDIV_REG时钟分频配置寄存器
UART_FLOW_CONF_REG软件流控配置寄存器
UART_SWFC_CONF_REG软件流控字符配置
UART_SLEEP_CONF_REG休眠模式配置,设置RXD延边次数阈值
UART_IDEL_CONF_REG帧空闲配置寄存器,设置帧间隔与空帧数量
UART_RS485_CONF_REGRS485模式配置寄存器
状态寄存器描述
UART_STATUS_REG串口状态寄存器,读取TXRX电平状态与FIFO有效数
波特率自检寄存器描述
UART_AUTOBAUD_REG自检波特率寄存器,配置自检使能与滤波门限
UART_LOWPULSE_REG自检波特率最小低脉冲寄存器,读取最小低电平脉冲宽度
UART_HIGHPULSE_MIN_CNT自检波特率最小高脉冲寄存器,读取最小高电平脉冲宽度
UART_POSPULSE_REG自检波特率高脉冲寄存器,检测上升沿次数
UART_NEGPULSE_REG自检波特率低脉冲寄存器,检测下升沿次数
UART_RXD_CNT_REG接收边沿计数寄存器,存储边沿变化次数
FIFO配置寄存器描述
UART_FIFO_REGFIFO数据寄存器,读取RX接收数据
UART_MEM_CONF_REGFIFO阈值设置与RAM空间分配
UART_MEM_CNT_STATUS_REG收发FIFI有效个数状态寄存器
中断寄存器描述
UART_INT_RAW_REG原始中断状态寄存器,获取相关的状态位
UART_INT_ST_REG隐藏中断状态寄存器
UART_INT_ENA_REG中断使能寄存器,配置相关中断使能位
UART_INT_CLR_REG清中断标志寄存器,置位清空相关中断
代码实例
API与数据结构

设置通信参数:接口esp_err_t uart_param_config(uart_port_t uart_num, const uart_config_t *uart_config)

  • 接口uart_param_config通过数据结构uart_config_t来配置串口参数,返回ESP_OK表明配置成功
const int uart_num = UART0;
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_CTS_RTS//使能流控
    .rx_flow_ctrl_thresh = 122,//接收流控阈值
   };// Configure UART parametersESP_ERROR_CHECK(uart_param_config(uart_num, &uart_config));

参数也可以单独调用接口配置

接口描述
uart_set_baudrate配置波特率
uart_set_word_length设置数据位
uart_set_parity设置校验模式
uart_set_stop_bits设置停止位
uart_set_sw_flow_ctrl设置流控
uart_set_mode设置模式

设置通信引脚:接口esp_err_t uart_set_pin(uart_port_t uart_num, int tx_io_num, int rx_io_num, int rts_io_num, int cts_io_num)

  • 关联收发以及流控引脚,不使用或想保持当前配置的可以调用宏UART_PIN_NO_CHANGE
// 设置串口引脚(TX: IO16  RX: IO17 RTS: IO18(UART2 default), , CTS: IO19(UART2 default), )
ESP_ERROR_CHECK(uart_set_pin(UART_NUM_2, 16, 17, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE));

驱动安装:接口esp_err_t uart_driver_install(uart_port_t uart_num, int rx_buffer_size, int tx_buffer_size, int queue_size, QueueHandle_t *uart_queue, int intr_alloc_flags)
安装串口驱动,分配缓存的大小与事件队列的深度;传入参数参数分别为

  • uart_num:串口号【0 - 2】
  • rx_buffer_size:硬件接收缓存大小,串口接收数据会自动缓存到BUFF中
  • tx_buffer_size:发送缓存大小,设为0时,发送的数据会进入堵塞状态等待发送完成
  • queue_size:串口事件的队列大小
  • uart_queue:串口事件的队列句柄,用于串口事件触发时数据同步
  • intr_alloc_flags:中断分配的标识,默认填0

驱动删除:接口esp_err_t uart_driver_delete(uart_port_t uart_num)

  • 释放原先分配的资源

通信发送:接口int uart_write_bytes(uart_port_t uart_num, const void *src, size_t size)

  • 指定UART口发送给定长度的数据,如果配置的tx_buffer_size大于0,会将数据拷贝到FIFI缓冲器中并立即返回

数据接收:接口int uart_read_bytes(uart_port_t uart_num, void *buf, uint32_t length, TickType_t ticks_to_wait)

  • 指定ticks_to_wait超时时间内,读取最大长度为length的数据

中断使用:串口状态或检测到错误时,可使能指定中断触发

  • 事件检测:数据结构uart_event_type_t定义了相关的事件,可通过uart_driver_install接口分配队列,利用FreeRtos进行数据传递,可参考peripherals/uart/uart_events代码
  • FIFO溢出或收发超时:接收发送buff溢出或发送接收数据超时可触发中断,可通过接口uart_intr_config配置,查看数据结构uart_intr_config_t选择事件绑定
  • 字符检测:通过接口uart_enable_pattern_det_intr进行使能,主要应用AT命令应用中,单硬件检测到连续相同的字符时,触发中断,可参考peripherals/uart/uart_events代码
例程代码

例程可参考idf目录下的test_uart.c,路径esp-idf\components\driver\test

#define UART_NUM1        	(UART_NUM_1)//端口
#define BUF_SIZE               (256)//缓存,大于128byte
#define UART1_RX_PIN      	(17)//关联引脚
#define UART1_TX_PIN      	(16)
#define UART1_RTS_PIN  		(UART_PIN_NO_CHANGE)
#define UART1_CTS_PIN  		(UART_PIN_NO_CHANGE)
static void test_task(void *pvParameters)
{
	uint8_t recvbuf[BUF_SIZE];
	int len;
	
    uart_config_t uart_config =
    {
        .baud_rate = 115200,//波特率
        .data_bits = UART_DATA_8_BITS,//8位数据
        .parity    = UART_PARITY_DISABLE,//不校验
        .stop_bits = UART_STOP_BITS_1,//1位停止位
        .flow_ctrl = UART_HW_FLOWCTRL_DISABLE,//禁用流控
        .source_clk = UART_SCLK_APB,//apb时钟源
    };
    uart_driver_install(UART_NUM1, BUF_SIZE, 0, 0, NULL, 0);//驱动安装
    uart_param_config(UART_NUM1, &uart_config);//配置参数
    uart_set_pin(UART_NUM1, UART1_TX_PIN, UART1_RX_PIN, UART1_RTS_PIN, UART1_CTS_PIN);//配置引脚
	
	while(1)
	{
		len = uart_read_bytes(UART_NUM1, recvbuf, BUF_SIZE, 100 / portTICK_RATE_MS);//读取数据
		if(len)
		{
			uart_write_bytes(UART_NUM1, (const char *) recvbuf, len);//返回接收数据
		}
	}
}

在这里插入图片描述

UART0使用

当引脚不够时,考虑使用UART0时,只需要在app_mian里面重新配置下UART0即可

参考API
  • 5
    点赞
  • 42
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
树莓派(Raspberry Pi)和ESP32都是流行的微型计算机平台,它们各自有独特的用途,但都支持串行通信,如UART(Universal Asynchronous Receiver/Transmitter),用于设备间的数据传输。 树莓派是一个基于Linux的单板电脑,广泛用于教育、物联网开发和原型设计。它的GPIO(General Purpose Input/Output)接口中就包含UART端口,可以用来连接其他硬件设备,如传感器或简单的控制模块,通过串口进行通信。 ESP32是Espressif Systems开发的一款嵌入式微控制器,它内置了Wi-Fi和蓝牙功能,特别适合物联网项目。ESP32同样具有多个UART端口,如TX/RX接口,用于与其他设备,如Arduino、PC或其他ESP32模块进行串口通信,或者作为微控制器之间的通信媒介。 在使用树莓派和ESP32UART通信时,通常的步骤包括配置端口参数(波特率、数据位数等)、编写发送和接收代码,以及可能的软件驱动设置。比如,如果你想要让树莓派和ESP32通过UART交换信息,你可能会: 1. 配置树莓派的GPIO UART设置,并启用相应的服务(如python的RPi.GPIO或picotcp)。 2. 使用Python的`serial`库在树莓派上创建串口连接。 3. 在ESP32上,通过SDK(如Micropython)配置串口并编写发送和接收函数。 4. 确保数据格式匹配,例如,是否需要添加校验和或者帧头。 相关问题: 1. ESP32UART接口如何配置? 2. 如何在树莓派上使用Python的`serial`库连接ESP32? 3. 什么是UART通信中的波特率和数据位数?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值