前面两篇文章我简单讲了一下在PCB板子上用于器件之间连接的SPI和I2C总线的一些基本特征以及优缺点,筒子们一眼就可以看出来这两种总线都有时钟信号线伴随着数据信号线的,在SPI中有SCLK,在I2C中有SCK,这种有时钟的传输方式叫同步传输,有时钟做参考可以方便接收端对接受数据的判决,但同时也带来一些限制,比如:

  1. 需要一根多余的连线用于时钟信号
  2. 因为需要时钟的边沿对数据进行采样判决,时钟的带宽至少要是数据带宽的2倍,因此也就限制了系统的数据传输速率
  3. 长距离传输的时候数据信号和时钟信号容易失去同步(即便俩人一起跑步,速度越快越不容易步调一致)

uart总线协议(几种最常用的串行数据传输总线)(1)

串行通信(同步)

所以,传输要往高速走,同步串行的传输方式就力不从心了,虽然可以在同样时钟频率的情况下靠增加数据线来提高传输的数据量(SD卡就这么干的),但信号线越多,也就越难同步,最后搞得跟并行传输一样了。

uart总线协议(几种最常用的串行数据传输总线)(2)

并行通信(PCB的布线在高速时将变得非常困难)

因此更高速的传输最好是采用异步的方式,也就是说不再有多余的时钟信号线跟着,传输的信号线中只有数据信号,异步传输不仅能够节省连线,同时还可以提高传输速度,比如USB、以太网。。。这种快到10Gbps的传输都只能靠异步的方式。

今天我们要讲的UART(通用异步接收/发送)就是一种异步的传输方式,不过它是相对低速的(最低1200bps),这是因为它生下来的时候人们的想象力还非常有限,能用9.6Kbps传传数据已经非常开心了,2000年前通过模拟电话线Modem传57.6Kbps的数据(收发邮件、网页浏览)已经感觉飞快了。

现在几乎每个MCU都标配UART,主要的功能是用来跟上位机连接的,以便让上位机对其进行调试或者执行简单的数据通信,比如显示一下状态、传递几个命令等。如果需要高速的数据传输?不是有USB了么!经过近20年的演进,USB 已经从最早的1.5Mbps一路升级到12Mbps、480Mbps、现在的10Gbps,USB已经承担了两个系统之间高速数据传输的主要重担。

uart总线协议(几种最常用的串行数据传输总线)(3)

UART虽然速率比较低,但却不可或缺,估计全世界的硬件工程师没有没和UART打过交道的。这个世界的科技发展变得再快,这种最简单、粗暴的数字通信方式也将像常青树一样一直陪伴着我们,一如过去的几十年。

UART的工作原理

UART(Universal Asynchronous Receiver/Transmitter,翻译过来叫通用异步收发) 其实不是像SPI和I2C这样的通信协议,而是MCU(微控制器)中的物理电路或独立的IC,它的主要用途是发送和接收串行数据。

在UART通信中,两个UART可以直接相互通信。 发送UART将来自CPU等控制设备的并行数据转换为串行格式,并将其串行发送到接收端的UART,接收UART将串行数据转换回接收设备的并行数据。 在两个UART之间传输数据只需要两根线, 数据流从发送UART的Tx引脚到接收UART的Rx引脚:

uart总线协议(几种最常用的串行数据传输总线)(4)

超简化的UART接口,左侧为并行,右侧为串行

通用异步接收器/发送器(UART)是负责实现串行通信的电路块。 本质上,UART充当并行和串行接口之间的中介。 UART的一端是八条左右数据线(加上一些控制引脚),另一条是两条串行线 - RX和TX。

uart总线协议(几种最常用的串行数据传输总线)(5)

两个设备可以发送和接收数据的串行接口是全双工半双工。 全双工意味着两个设备可以同时发送和接收。 半双工通信意味着串行设备必须轮流发送和接收。

UART以异步方式发送数据,也就是说没有时钟信号将发送UART的位输出与接收UART的位采样进行同步。 发送UART将“起始”和“停止”位添加到正在传输的数据包中, 这些位定义了数据包的开始和结束,接收UART基于这些位的信息知道何时开始读取输入的串行数据。

当接收UART检测到起始位时,它以特定的频率(也就是“波特率”)读取输入的串行数据。波特率是数据传输速度的度量,单位-每秒位数(bps)。 两个UART必须以相同的波特率运行。发送和接收UART之间的波特率相差不能超过10%,偏差太远就无法对数据进行正确的解读。

当然两个UART还必须配置为发送和接收相同的数据包结构。

异步通信以一个字符为传输单位,通信中两个字符间的时间间隔多少是不固定的,然而在同一个字符中的两个相邻位间的时间间隔是固定的。两个相邻位间的时间间隔与UART通信的波特率有关,波特率用来表征UART通信中数据传输的速率,即每秒钟传送的二进制位数。例如数据传送速率为120字符/秒,而每一个字符为10位(1个起始位,7个数据位,1个校验位,1个结束位),则其传送的波特率为10×120=1200字符/秒=1200波特。

我们在调试种最比较常见的波特率是9600bps,其它的“标准”波特还有1200、2400、4800、19200、38400、57600和115200。

以9600bps传输为例,将每个位高或低保持的时间为1 /(9600 bps)或每位104μs,对于发送的每个数据字节,实际上发送了10位:起始位,8个数据位和一个停止位。 因此,在9600bps时,我们实际上每秒发送9600位或每秒960(9600/10)字节。

波特率越高,发送/接收的数据越快,但数据传输的速度有限。您通常不会看到超过115200的速度 - 这对于大多数微控制器来说都很快。太高了,你会开始看到接收端的错误,因为时钟和采样周期无法跟上。

uart总线协议(几种最常用的串行数据传输总线)(6)

数据帧构成

发送的每个数据块(通常是一个字节)实际上是以比特或比特帧发送的。通过将同步和奇偶校验位附加到数据来创建帧。

uart总线协议(几种最常用的串行数据传输总线)(7)

下面我们详细介绍一下每一部分。

数据块

每个串行数据包的真正有营养的是它携带的数据,我们且称之为“数据块”,它没有具体的大小限制。 每个数据包中的数据量可以设置为5到9位。 标准数据的大小一般是最基本的8位字节,但其它大小也有其用途,有时候7位数据能比8位更高效,比如只是用来传输7位ASCII字符。

在统一了字符长度后,两个串行设备也必须就其数据的字节顺序达成一致。 数据是最高位(msb)还是最低位先发送? 缺省设定为首先传输最低有效位(lsb)。

同步位同步位是每个数据块传输的两个或三个特殊位。 它们是起始位和停止位,顾名思义,这些位标记了数据包的开头和结尾。 始终只有一个起始位,但停止位的数量可配置为一个或两个(通常情况下保留为一个)。

起始位始终是由从1到0的空闲数据线来指示,而停止位则将通过将该信号线保持为1而转换回空闲状态。

奇偶校验位

奇偶校验是一种非常简单的低级错误检查方式,它分为两种方式:奇数或偶数。 为了产生奇偶校验位,数据字节的所有5-9位相加,并且求和的奇偶性决定该位是否置位。 例如,假设奇偶校验设置为偶数并且正被添加到数字字节(如0b01011101,这串数中有奇数(5)个1,奇偶校验位将被设置为1。相反,如果奇偶校验模式设置为奇数 ,奇偶校验位则为0。

同步和采样

下面我们来看看没有时钟信号的数据在接收端是如何被正确解读的。

没有时钟对数据做判决,这些数据毫无意义。 下图显示了原因:

uart总线协议(几种最常用的串行数据传输总线)(8)

同一串数据可以有不同的解读

典型的数据信号只是在逻辑低和逻辑高之间转换的电压。 只有当接收器知道何时采样信号时,接收器才能正确地将这些逻辑状态转换为数字数据。

这可以使用单独的时钟信号轻松完成 - 例如,发送器在时钟的每个上升沿更新数据信号,然后接收器在每个下降沿采样数据。但UART接口没有时钟信号来同步Tx和Rx器件,接收端如何知道何时采样发射端送来的数据信号呢?

发送端根据其时钟信号生成比特流,然后接收端的目标是使用其内部时钟信号在每个比特周期的中间对输入的数据流进行采样。虽然在比特周期的中间进行采样不是必要的但却是最佳的,因为接近比特周期的开始或结束的采样使得系统对接收端和发射端之间的时钟频率差异的鲁棒性较差。

接收端序列从起始位的下降沿开始,这是关键同步过程发生的时间。接收端的内部时钟完全独立于发送端的内部时钟 - 换句话说,第一个下降沿可以对应于接收端时钟周期中的任何点:

uart总线协议(几种最常用的串行数据传输总线)(9)

为了确保接收端时钟的有效边沿能够在比特周期的中间附近发生,发送到接收端模块的波特率时钟的频率要比实际波特率高得多(比8或16或甚至32倍)。

假设一个比特周期对应于16个接收端时钟周期。 在这种情况下,同步和采样可以按如下方式进行:

  1. 接收过程由起始位的下降沿启动。
  2. 接收端等待8个时钟周期,以便建立一个接近比特周期中间的采样点。
  3. 然后,接收端等待16个时钟周期,使其进入第一个数据位周期的中间。
  4. 第一个数据位被采样并存储在接收寄存器中,然后模块在采样第二个数据位之前等待另外16个时钟周期。
  5. 重复此过程直到所有数据位都被采样和存储,然后停止位的上升沿使UART接口返回其空闲状态。

uart总线协议(几种最常用的串行数据传输总线)(10)

UART的优点和缺点

没有任何一种通信方式和协议是完美的,因此没中方式都有其优点,也有其缺点,我们来看看UART的主要优缺点。

UART的优点:

UART的缺点:

实际应用中的信号传输方式

将两个UART的设备进行连接有多种方式,取决于具体的应用场景,在这里我们仅看两种:TTL UART和RS-232。

TTL UART

当微控制器和其它器件进行串行通信时,通常以TTL电平进行通信。 TTL串行信号存在于微控制器的电源电压范围内 - 通常为0V至3.3V或5V。 VCC电平(3.3V,5V等)的信号表示空闲线,值1或停止位。 0V(GND)信号表示起始位或值为0的数据位。

uart总线协议(几种最常用的串行数据传输总线)(11)

RS-232 UART

RS-232(推荐标准232)是连接数据终端设备(DTE)和数据通信设备(DCE)的串行二进制数据信号的标准。 它通常用于计算机的老式串口。 TTL电平UART和RS-232的主要区别就是电压电平。 RS-232中的数字信号为±3至 - ±15V,无论如何都不会检测到接近0V的信号。

RS-232,可以在一些更古老的计算机和外围设备上找到,就像TTL串口翻转一样。 RS-232信号通常介于-13V和13V之间,但规格允许从 /- 3V到 /- 25V。 在这些信号上,低电压(-5V,-13V等)表示空闲线,停止位或值为1的数据位。一个高的RS-232信号表示起始位或0- 值数据位。 这与TTL系列相反。

uart总线协议(几种最常用的串行数据传输总线)(12)

RS-232比TTL的UART有更多的引脚,用于PC和调制解调器之间的通信。 我们常用的DB-9的引脚排列及其功能如下所示。

uart总线协议(几种最常用的串行数据传输总线)(13)

最扑街的RS-232收发芯片 - MAX232

在两个串行信号标准之间,TTL更容易实现到嵌入式电路中。 然而,低电压电平更容易受到长传输线路的损耗的影响。 RS-232或更复杂的标准(如RS-485)更适合远程串行传输。当您将两个串行设备连接在一起时,确保其信号电压匹配是非常重要的。

PC和微控制器的连接

实际的项目中可以有多种方式来连接PC和MCU,最方便的是下面列出的几种方式中的最后一种。

uart总线协议(几种最常用的串行数据传输总线)(14)

uart总线协议(几种最常用的串行数据传输总线)(15)

全球创客界最火的WiFi模块ESP8266只需要UART接口和AT指令集进行操作

uart总线协议(几种最常用的串行数据传输总线)(16)

物美价廉的USB到TTL UART接口转换芯片CP2102(来自SiLabs),通过计算机的USB端口仿真UART通信

使用UART最容易碰到的问题:

RX-To-TX & TX-To-RX

工程师经常犯的错误就是将RX和TX线错误连接,因此在遇到连接不通的时候一定要先检查确定一下是否存在这方面的问题。

uart总线协议(几种最常用的串行数据传输总线)(17)

波特率失配

如果数据以9600bps的波特率传输,并以19200bps的速率接收。 收到的数据将是一团垃圾! 波特率必须在发送端和接收端匹配,这是UART串行通信的经验法则,波特率的最大允许偏移趋于介于(1-2%)之间。 因此尝试在两端生成完全相同的波特率,以避免错配错误。

uart总线协议(几种最常用的串行数据传输总线)(18)

UART总线长度 vs 波特率

UART串行总线可以传输很长的距离,但传输的距离以及最高能够达到的波特率都取决于传输得越远,波特率也就会降低,它还取决于UART协议本身的硬件实现(物理层)。我们只提到TTL-UART和RS-232标准。

RS-232

RS-232的最大电缆长度为50英尺。 但实际上它取决于波特率、电缆的等效电容和环境噪声。 下表是TI多年前通过实验总结的一些经验法则。

uart总线协议(几种最常用的串行数据传输总线)(19)

TTL-UART

TTL电平的UART仅支持5V的电压摆幅,因此信号传输的距离以及能够支持到的波特率取决于下面的3个元素:

  1. 电缆的电阻 - 电缆越长电阻也就越高
  2. 电缆的电容:大家知道电容效应会阻碍信号电平的变化
  3. 噪声:任何环境中都会有噪声,带屏蔽的双绞线电缆对信号的传输会有帮助
,