这篇文章主要内容是对Basics of UART Communication的翻译。
UART,即Universal Asynchronous Receiver/Transmitter。UART并非类似于SPI和I2C的通信协议,而是微控制器中的一个物理电路或者一块独立的集成电路元器件。UART的主要用途是传输和接收串口数据。
1. UART通信介绍
在UART通信中,两个UARTs直接和对方通信。UART的数据传输方将控制设备(例如:CPU)中的并行形式数据转换为串行形式,然后通过串口传输给接收方UART。接收方UART再将串行形式的数据转换为并行形式并交给接收设备。在两个UARTs之间的传输只需要使用到两条线。数据从传输方UART的Tx引脚流向接收方UART的Rx引脚。
UARTs以异步方式传输数据,因而不需要额外的时钟信号同步发送方UART的输出和接收方UART对数据的取样。这种异步方式的实现依赖于在UART在数据包中添加起始位(start bits)和停止位(stop bits)。这两种数据位定义了数据包的开始和结束。UART也从而知道从什么时候开始读取数据。
当接收方UART检测到一个起始位时,它就开始以固定的频率读取到来的数据位,这个频率被称为波特率(baud rate)。波特率是数据传输速率的一种计量方式,记为位每秒(bits per second, bps)。若表示成Baud则是(bytes per second, Bps,通常用这个,例如:115200)。UARTs双方需要被配置为使用相同的波特率。传输方和接收方UARTs在数据位的时序偏离太大之前仅能有最多10%的波特率差异。
同时,UARTs传输和接收双方也必须被配置为使用相同的数据包结构。
2. 波特率计算举例
对于rpi3b+,其内部的mini uart采用8倍过采样(8-times oversampling,根据设备文档)。波特率计算公式如下:
\[baudrate = \frac{system\_clock\_freq}{8*(baudrate\_reg+1)}\]若系统时钟为250MHz且波特率寄存器为0,则波特率为31.25M波特(25Mbits/sec或3.125Mbytes/sec)。250MHz系统下最低波特率为476 Baud(此时波特率寄存器有效的16位每一位均为1)。
250MHz系统中若希望使用115200的波特率,可以列出如下等式
\[115200 = \frac{250*10^6}{8(x+1)}\]计算得
\[x=\frac{250*10^6}{8*115200}-1=270.26736\]因而波特率寄存器应当写入270。
3. UART是如何工作的
UART的发送方从数据总线接收(需要被发送的)数据。数据总线被用于从另一个设备例如CPU,内存或微控制器给UART发送数据。数据以并行的形式被发送给UART。在UART从数据总线获取到并行数据之后,它会在其上加上一个起始位(start bit),一个奇/偶校验位以及一个停止位(stop bit),以构成数据包。接着,数据包被发送方UART从Tx引脚串行输出。
接收方UART从Rx引脚按位读入数据包。接收方UART之后将数据转换为并行形式、移出起始位、奇/偶校验位和停止位。最后,接收方UART将数据包以并行形式从数据总线发送给接收端设备。
UART传输的数据被组织成数据包(packets)。每一个数据包含有1个起始位,5~9个数据位(取决于UART的配置),一个可选的奇偶校验位以及1或两个停止位如下:
3.1. Start Bit起始位
当UART数据传输线不在传输数据时,通常维持在高电压。为启动数据的传输,发送方UART将输出线从高电平拉低到低电平,并维持一个时钟周期。当接收方UART检测到传输线的电平改变,就会开始以设置的波特率读取数据帧中的数据位。
3.2. Data Frame数据帧
数据帧包含了实际传输的数据。若使用了奇偶校验位,数据帧最少5位,最多8位。若没有使用奇偶校验位,则最多可以有9位。多数情况下,数据的least significant位被首先发送。(即小端首先发送)
3.3. Parity奇/偶校验
奇偶校验位描述了一个数字为奇数或是偶数。使用奇偶校验位是检测数据在传输中是否改变的一种方式。数据位可能被电磁辐射、不匹配的波特率或是长距离的数据传输所改变。当接收方UART收到数据帧后,它会计算帧中值为1的位的数量并检验总数是奇数或是偶数。若奇偶校验位是0,则帧中应当含有偶数个1。反之,帧中则应含有奇数个1。当奇偶校验位和数据匹配,UART就知道传输不存在错误。反之,UART就知道数据在传输中发生了改变。
3.4. Stop Bits停止位
为表明数据包的结束,发送方UART将数据传输线从低电平拉升到高电平并持续至少两位的时间。
4. UART传输的步骤
- 发送方UART从数据总线收到并行的数据
- 发送方UART向数据帧中加入起始位、奇偶校验位和停止位(可能2个)。
- 整个数据包以串行的方式发给接收方UART。接收方UART以配置的波特率对数据线取样。
- 接收方UART丢弃起始位、奇偶校验位和停止位
- 接收方UART将串行数据转换为并行模式然后通过数据总线传递给接收方
5. UARTs传输的优势和劣势
显然,目前这个世界上不存在完美的通信协议,但是UARTs非常擅长处理串行通信。下面是使用UARTs的一些优劣势:
5.1. 优势
- 仅使用了两条线
- 不需要时钟信号(clock signal)
- 存在一个奇/偶校验位
- 只要通信双方配置正确,传输的数据包的结构能够随意改变
- 文档化良好并且被广泛使用
5.2. 劣势
- 数据帧的大小被限制在最多9位
- 不支持多个slave或者多个master节点的系统
- UART在同步之前波特率差异必须小于10%