UART - Universal Asynchronous Receiver/TransmitterUART - Universal Asynchronous Receiver/Transmitter概述嵌入式应用通常要求一个简单的并且占用系统资源少的方法来传输数据.通用异步收发传输器(UART) 即可以满足这些要求,它能够灵活地与外部设备进行全双工数据交换.ESP32 芯片中有 3 个UART 控制器可供使用,并且兼容不同的 UART 设备.另外,UART 还可以用作红外数据交换(IrDA) 或 RS-485 调制解调器. 3 个 UART 控制器有一组功能相同的寄存器.本文以 UARTn 指代 3 个 UART 控制器,n 为0、1、2. 主要特性
功能描述UART 是一种以字符为导向的通用数据链,可以实现设备间的通信.异步传输的意思是不需要在发送数据上添加时钟信息.这也要求发送端和接收端的速率、停止位、奇偶校验位等都要相同,通信才能成功. 一个典型的 UART 帧开始于一个起始位,紧接着是有效数据,然后是奇偶校验位(可有可无),最后是停止位.ESP32 上的 UART 控制器支持多种字符长度和停止位.另外,控制器还支持软硬件流控和 DMA,可以实现无缝高速的数据传输.开发者可以使用多个 UART 端口,同时又能保证很少的软件开销. UART 有两个时钟源:80-MHz APB_CLK 以及参考时钟 REF_TICK (详情请参考章节复位和时钟).可以通过配置 UART_TICK_REF_ALWAYS_ON 来选择时钟源.时钟中的分频器用于对时钟源进行分频,然后产生时钟信号来驱动 UART 模块.ART_CLKDIV_REG 将分频系数分成两个部分:UART_CLKDIV 用于配置整数部分,UART_CLKDIV_FRAG 用于配置小数部分. UART 控制器可以分为两个功能块:发送块和接收块. 发送块包含一个发送 FIFO 用于缓存待发送的数据.软件可以通过 APB 总线写 Tx_FIFO,也可以通过 DMA 将数据搬入 Tx_FIFO.Tx_FIFO_Ctrl 用于控制 Tx_FIFO 的读写过程,当 Tx_FIFO 非空时,Tx_FSM 通过 Tx_FIFO_Ctrl读取数据,并将数据按照配置的帧格式转化成比特流.比特流输出信号 txd_out 可以通过配置 UART_TXD_INV 寄存器实现取反功能. 接收块包含一个接收 FIFO 用于缓存待处理的数据.输入比特流 rxd_in 可以输入到 UART 控制器.可以通过 UART_RXD_INV 寄存器实现取反.Baudrate_Detect 通过检测最小比特流输入信号的脉宽来测量输入信号的波特率.Start_Detect 用于检测数据的 START 位,当检测到 START 位之后,RX_FSM 通过 Rx_FIFO_Ctrl 将帧解析后的数据存入 Rx_FIFO 中. 软件可以通过 APB 总线读取 Rx_FIFO 中的数据.为了提高数据传输效率,可以使用 DMA 方式进行数据发送或接收. HW_Flow_Ctrl 通过标准 UART RTS 和 CTS(rtsn_out 和 ctsn_in)流控信号来控制 rxd_in 和 txd_out 的数据流.SW_Flow_Ctrl 通过在发送数据流中插入特殊字符以及在接收数据流中检测特殊字符来进行数据流的控制.当 UART 处于 Light-sleep(详情请参考章节低功耗管理)状态时,Wakeup_Ctrl 开始计算 rxd_in 的脉冲个数,当脉冲个数大于 UART_ACTIVE_THRESHOLD 时产生 wake_up 信号给 RTC 模块,由 RTC 来唤醒 UART 控制器. 应用示例配置 UART 设置并使用 UART1 接口安装 UART 驱动程序进行读/写:peripherals/uart_echo. 演示如何报告各种通信事件以及如何使用模式检测中断:peripherals/uart_events. 在两个独立的 FreeRTOS 任务中使用相同的 UART 进行发送和接收:peripherals/uart_async_rxtxtasks. 对 UART 文件描述符使用同步 I/O 多路复用:peripherals/uart_select. 设置 UART 驱动程序以半双工模式通过 RS485 接口进行通信:peripherals/uart_echo_rs485. 此示例类似于 uart_echo,但通过连接到 ESP32 引脚的 RS485 接口芯片提供通信. API ReferenceHeader FileAPI 使用以下概述描述了用于在 ESP32 和某些其他 UART 设备之间建立通信的功能和数据类型. 概述反映了编程 ESP32 的UART驱动程序时的典型工作流程,并分为以下几个部分:
使 UART 能开始工作是完成前面的四个步骤,后两个步骤是可选的. 驱动程序由 设置通信参数有两种方法可以设置 UART 的通信参数. 一种是通过调用 另一种方法是通过调用函数单独配置特定参数:
const int uart_num = UART_NUM_2; 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 parameters ESP_ERROR_CHECK(uart_param_config(uart_num, &uart_config)); 设置通信引脚通过调用函数 // Set UART pins(TX: IO16 (UART2 default), RX: IO17 (UART2 default), RTS: IO18, CTS: IO19) ESP_ERROR_CHECK(uart_set_pin(UART_NUM_2, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE, 18, 19)); 驱动程序安装完成驱动程序配置后,我们可以通过调用
// Setup UART buffered IO with event queue const int uart_buffer_size = (1024 * 2); QueueHandle_t uart_queue; // Install UART driver using an event queue here ESP_ERROR_CHECK(uart_driver_install(UART_NUM_2, uart_buffer_size, uart_buffer_size, 10, &uart_queue, 0)); 如果上述所有步骤均已完成,我们就可以连接其他 UART 设备并开始通信. 运行 UART 通信串行通信的过程受 UART 硬件 FSM 的控制. 要发送的数据应放入 Tx FIFO 缓冲区, FSM 将序列化并发送出去. 完成类似的过程,但是以相反的顺序,接收数据. 传入的串行流由 FSM 处理并移至 Rx FIFO 缓冲区. 因此, API 的通信功能的任务仅限于向/从相应缓冲区写入和读取数据. 这反映在一些函数名称中,例如: 使用中断报告了 UART 的特定状态或检测到的错误有 19 个中断. ESP32 技术参考手册(PDF)中介绍了可用中断的完整列表. 要启用特定中断,请调用 删除驱动程序如果与 |
|