通用异步接收器/发送器(UART)是用于处理各种广泛适应的协议(RS232,RS485,RS422,…)的时序要求的组件。UART提供了一种广泛采用和廉价的方法来实现不同设备之间的全双工数据交换。
ESP32芯片上有三个UART控制器。它们与来自不同制造商的支持UART的设备兼容。集成在ESP32中的所有UART控制器都具有相同的寄存器组,便于编程和灵活性。在本文档中,这些控制器被称为UART0,UART1和UART2。
以下概述描述了用于在ESP32和其他UART设备之间建立通信的功能和数据类型。概述反映了编程ESP32的UART驱动程序时的典型工作流程,并分为以下几部分:
使UART工作的最低限度是完成前四个步骤,最后两个步骤是可选的。
驱动程序由标识uart_port_t,对应于树型UART控制器之一。这样的标识存在于以下所有函数调用中。
有两种方法可以设置UART的通信参数。一种是通过调用结构中的uart_param_config()
配置参数调用一次uart_config_t
。
另一种方法是通过调用专用函数分别配置特定参数:
波特率 - uart_set_baudrate()
传输比特数 - uart_set_word_length()
从uart_word_length_t
中选择
奇偶校验控制 - uart_set_parity()
从uart_parity_t
中选择
停止位数 - uart_set_stop_bits()
从uart_stop_bits_t
中选择
硬件流量控制模式 - uart_set_hw_flow_ctrl()
从uart_hw_flowcontrol_t
中选择
所有上述功能都有_get_
相同的功能来检索当前的设置,例如uart_get_baudrate()
。
下一步,在配置通信参数后,我们将设置另一个UART将要连接的物理GPIO管脚号。这是通过调用函数uart_set_pin()
并为其提供GPIO编号完成的,该驱动程序应该用于Tx,Rx,RTS和CTS信号。
代替GPIO引脚号,我们可以输入一个宏UART_PIN_NO_CHANGE
,而当前分配的引脚不会改变。如果某个引脚不被使用,应该输入相同的宏。
一旦驱动程序配置完成,我们可以通过调用来安装它uart_driver_install()
。结果,UART将需要分配几个资源。资源的类型/大小被指定为函数调用参数和关注点:
如果以上所有步骤都已完成,我们已准备好连接另一个UART设备并检查通信。
串行通信的过程受UART硬件FSM控制。要发送的数据应放入Tx FIFO缓冲区,FSM将它们串行化并发送出去。接收数据的过程与其相反。输入串行流由FSM处理并移至Rx FIFO缓冲区。因此,API功能仅限于写入和读取相应缓冲区中的数据。这反映在一些函数名称中,例如:uart_write_bytes()
写数据或uart_read_bytes()
读数据。
将数据写入Tx FIFO缓冲区的基本API函数是uart_tx_chars()
。如果缓冲区包含未发送的字符,则此函数将写入适合空白区域的内容并退出报告实际写入的字节数。
有一个“companion”功能uart_wait_tx_done()
等待,直到所有的数据都被发送出去并且Tx FIFO为空。
更容易与功能合作uart_write_bytes()
。它设置一个中间环形缓冲区并在将数据复制到此缓冲区后退出。当FIFO中有空闲空间时,通过ISR将数据从环形缓冲区移到后台。
有一个类似的功能,在发送数据后添加一个串行中断信号uart_write_bytes_with_break()
。’serial break signal’意味着将TX线保持低于一个数据帧的时间。
要检索由UART接收的数据并保存在Rx FIFO中,请使用函数uart_read_bytes()
。您可以通过调用事先检查Rx FIFO中可用的字节数uart_get_buffered_data_len()
。
如果Rx FIFO中的数据不是必需的,应该丢弃,请调用uart_flush()
。
当硬件流控被禁用时,请使用uart_set_rts()
和uart_set_dtr()
手动设置RTS和DTR信号的电平。
在UART的特定状态或检测到的错误上报告了19个中断。ESP32技术参考手册(PDF)介绍了可用中断的完整列表。要启用特定的中断请调用uart_enable_intr_mask()
,禁用它请调用uart_disable_intr_mask()
。所有可用的中断掩码为UART_INTR_MASK
。注册中断处理程序请调用uart_isr_register()
释放请调用uart_isr_free()
。一旦处理程序被调用,使用uart_clear_intr_status()
清除中断状态位。
API提供了一种方便的方式来处理上面讨论的特定中断,方法是将它们封装到专用函数中:
uart_event_type_t
可以使用FreeRTOS队列功能向用户应用程序报告定义的多个事件。uart_driver_install()
在驱动安装中描述的调用可以启用此功能。peripherals/uart_events演示了如何使用它uart_intr_config_t
结构并通过调用uart_intr_config()
来配置缓冲区长度和超时的相应阈值。然后通过uart_enable_rx_intr()
和uart_enable_tx_intr()
启用中断。通过uart_disable_rx_intr()
或uart_disable_tx_intr()
禁用中断。uart_enable_pattern_det_intr()
和uart_disable_pattern_det_intr
启用或禁用此中断。API提供了几个宏来定义配置参数,例如UART_FIFO_LEN
定义硬件FIFO缓冲区的长度,UART_BITRATE_MAX
给出UART支持的最大波特率等。
通过uart_driver_install()
建立通讯后,想要停止通讯,通过调用uart_driver_delete()
释放分配的资源。
配置UART设置并安装UART驱动程序以使用UART1接口读/写:peripherals/uart_echo.
演示如何报告各种通信事件以及如何使用模拟检测中断: peripherals/uart_events.
在两个独立的FreeRTOS任务中使用同一个UART发送和接收:peripherals/uart_async_rxtxtasks.
本文翻译自:https://esp-idf.readthedocs.io/en/latest/api-reference/peripherals/uart.html#using-interrupts