UART - 异步串行通信
一个通用的异步接收/发射器,简称为UART /ˈjuːɑːrt/, 是一种计算机硬件设备,它在计算机中的字符(通常是字节)之间转换数据,以及在起始位和停止位之间封装这些字符的异步串行通信格式, 其中数据格式和传输速度是可配置的。UART通常与通信标准结合使用,例如TIA(以前称为EIA)RS-232,RS-422或RS-485。 通用名称表示数据格式和传输速度是可配置的。 电信号电平和方法(例如差分信号等)由UART外部的驱动电路处理。
UART通常是用于通过计算机或外围设备串行端口进行串行通信的单独(或部分)集成电路(IC)。 UART现在通常包含在微控制器中。 双UART或DUART将两个UART组合成一个芯片。 八进制UART或OCTART将八个UART组合成一个封装,例如Exar XR16L788或NXP SCC2698。 相关设备,通用同步/异步接收器/发送器(USART)也支持同步操作。
UART采用字节数据并以顺序方式发送各个位。在目的地,第二个UART将这些位重新组合成完整的字节。每个UART都包含一个移位寄存器,它是串行和并行形式之间转换的基本方法。通过单线或其他介质的数字信息(比特)的串行传输比通过多条线的并行传输更便宜。
UART通常不直接生成或接收不同设备之间使用的外部信号。独立的接口设备用于将UART的逻辑电平信号转换为外部信号电平和从外部信号电平转换。外部信号可以有许多不同的形式。电压信号标准的示例是来自EIA的RS-232,RS-422和RS-485。历史上,电流电路中使用电流(电流环路)。一些信令方案不使用电线。其示例是其串行端口配置文件(SPP)中的光纤,IrDA(红外线)和(无线)蓝牙。一些信令方案使用载波信号的调制(有或没有线路)。例如,使用电话线调制解调器调制音频信号,使用数据无线电调制RF调制,以及使用DC-LIN进行电力线通信。
通信可以是单工的(仅在一个方向上,没有规定接收设备将信息发送回发送设备),全双工(两个设备同时发送和接收)或半双工(设备轮流发送和接收) )。
UART的工作原理
UART(Universal Asynchronous Receiver/Transmitter,翻译过来叫通用异步收发) 其实不是像SPI和I2C这样的通信协议,而是MCU(微控制器)中的物理电路或独立的IC,它的主要用途是发送和接收串行数据。
在UART通信中,两个UART可以直接相互通信。 发送UART将来自CPU等控制设备的并行数据转换为串行格式,并将其串行发送到接收端的UART,接收UART将串行数据转换回接收设备的并行数据。 在两个UART之间传输数据只需要两根线, 数据流从发送UART的Tx引脚到接收UART的Rx引脚:
超简化的UART接口,左侧为并行,右侧为串行
通用异步接收器/发送器(UART)是负责实现串行通信的电路块。 本质上,UART充当并行和串行接口之间的中介。 UART的一端是八条左右数据线(加上一些控制引脚),另一条是两条串行线 - RX和TX。
两个设备可以发送和接收数据的串行接口是全双工或半双工。 全双工意味着两个设备可以同时发送和接收。 半双工通信意味着串行设备必须轮流发送和接收。
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的速度 - 这对于大多数微控制器来说都很快。太高了,你会开始看到接收端的错误,因为时钟和采样周期无法跟上。
数据帧构成
发送的每个数据块(通常是一个字节)实际上是以比特或比特帧发送的。通过将同步和奇偶校验位附加到数据来创建帧。
- 起始位:先发出一个逻辑”0”信号,表示传输字符的开始。
- 数据位:可以是5~8位逻辑”0”或”1”。如ASCII码(7位),扩展BCD码(8位)。小端传输
- 校验位:数据位加上这一位后,使得“1”的位数应为偶数(偶校验)或奇数(奇校验)
- 停止位:它是一个字符数据的结束标志。可以是1位、1.5位、2位的高电平。
- 空闲位:处于逻辑“1”状态,表示当前线路上没有资料传送。
下面我们详细介绍一下每一部分。
数据块
每个串行数据包的真正有营养的是它携带的数据,我们且称之为“数据块”,它没有具体的大小限制。 每个数据包中的数据量可以设置为5到9位。 标准数据的大小一般是最基本的8位字节,但其它大小也有其用途,有时候7位数据能比8位更高效,比如只是用来传输7位ASCII字符。
在统一了字符长度后,两个串行设备也必须就其数据的字节顺序达成一致。 数据是最高位(msb)还是最低位先发送? 缺省设定为首先传输最低有效位(lsb)。
同步位
同步位是每个数据块传输的两个或三个特殊位。 它们是起始位和停止位,顾名思义,这些位标记了数据包的开头和结尾。 始终只有一个起始位,但停止位的数量可配置为一个或两个(通常情况下保留为一个)。
起始位始终是由从1到0的空闲数据线来指示,而停止位则将通过将该信号线保持为1而转换回空闲状态。
- 起始位:单字节UART发送的第一位。 它表示数据线正在离开其空闲状态。 空闲状态通常为逻辑高,因此起始位为逻辑低。起始位是开销位, 这意味着它有助于接收器和发射器之间的通信,但不会传输有意义的数据。
- 停止位: 单字节UART传输的最后一位。 其逻辑电平与信号的空闲状态相同,即逻辑高, 这是另一个开销。
奇偶校验位
奇偶校验是一种非常简单的低级错误检查方式,它分为两种方式:奇数或偶数。 为了产生奇偶校验位,数据字节的所有5-9位相加,并且求和的奇偶性决定该位是否置位。 例如,假设奇偶校验设置为偶数并且正被添加到数字字节(如0b01011101,这串数中有奇数(5)个1,奇偶校验位将被设置为1。相反,如果奇偶校验模式设置为奇数 ,奇偶校验位则为0。
同步和采样
下面我们来看看没有时钟信号的数据在接收端是如何被正确解读的。
没有时钟对数据做判决,这些数据毫无意义。 下图显示了原因:
同一串数据可以有不同的解读
典型的数据信号只是在逻辑低和逻辑高之间转换的电压。 只有当接收器知道何时采样信号时,接收器才能正确地将这些逻辑状态转换为数字数据。
这可以使用单独的时钟信号轻松完成 - 例如,发送器在时钟的每个上升沿更新数据信号,然后接收器在每个下降沿采样数据。但UART接口没有时钟信号来同步Tx和Rx器件,接收端如何知道何时采样发射端送来的数据信号呢?
发送端根据其时钟信号生成比特流,然后接收端的目标是使用其内部时钟信号在每个比特周期的中间对输入的数据流进行采样。虽然在比特周期的中间进行采样不是必要的但却是最佳的,因为接近比特周期的开始或结束的采样使得系统对接收端和发射端之间的时钟频率差异的鲁棒性较差。
接收端序列从起始位的下降沿开始,这是关键同步过程发生的时间。接收端的内部时钟完全独立于发送端的内部时钟 - 换句话说,第一个下降沿可以对应于接收端时钟周期中的任何点:
为了确保接收端时钟的有效边沿能够在比特周期的中间附近发生,发送到接收端模块的波特率时钟的频率要比实际波特率高得多(比8或16或甚至32倍)。
假设一个比特周期对应于16个接收端时钟周期。 在这种情况下,同步和采样可以按如下方式进行:
- 接收过程由起始位的下降沿启动。
- 接收端等待8个时钟周期,以便建立一个接近比特周期中间的采样点。
- 然后,接收端等待16个时钟周期,使其进入第一个数据位周期的中间。
- 第一个数据位被采样并存储在接收寄存器中,然后模块在采样第二个数据位之前等待另外16个时钟周期。
- 重复此过程直到所有数据位都被采样和存储,然后停止位的上升沿使UART接口返回其空闲状态。
UART的优点和缺点
没有任何一种通信方式和协议是完美的,因此没中方式都有其优点,也有其缺点,我们来看看UART的主要优缺点。
UART的优点:
- 只需要使用两根信号线就可以实现全双工的数据传输(不算电源线)
- 无需时钟信号
- 有一个奇偶校验位提供硬件级别的错误检查
- 数据包的结构可以通过两端之间的协调来改变,比较灵活
- 有丰富的文档且被广泛使用的通信方式
- 相对比较容易配置和运行
UART的缺点:
- 与并行通信以及USART相比,数据传输的速度较慢
- 帧的大小被限定为最多9位
- 不支持多个从设备或多个主设备的功能
- 收发两个器件UART的波特率差别不能超过10%
实际应用中的信号传输方式 将两个UART的设备进行连接有多种方式,取决于具体的应用场景,在这里我们仅看两种:TTL UART和RS-232。
TTL UART 当微控制器和其它器件进行串行通信时,通常以TTL电平进行通信。 TTL串行信号存在于微控制器的电源电压范围内 - 通常为0V至3.3V或5V。 VCC电平(3.3V,5V等)的信号表示空闲线,值1或停止位。 0V(GND)信号表示起始位或值为0的数据位。
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系列相反。
逻辑电平 | Logic-1 (High) | Logic-0 (Low) |
---|---|---|
电压 | +3 to +15v | -3 to -15v |
RS-232比TTL的UART有更多的引脚,用于PC和调制解调器之间的通信。 我们常用的DB-9的引脚排列及其功能如下所示。
最扑街的RS-232收发芯片 - MAX232
在两个串行信号标准之间,TTL更容易实现到嵌入式电路中。 然而,低电压电平更容易受到长传输线路的损耗的影响。 RS-232或更复杂的标准(如RS-485)更适合远程串行传输。当您将两个串行设备连接在一起时,确保其信号电压匹配是非常重要的。
PC和微控制器的连接
实际的项目中可以有多种方式来连接PC和MCU,最方便的是下面列出的几种方式中的最后一种。
全球创客界最火的WiFi模块ESP8266只需要UART接口和AT指令集进行操作
物美价廉的USB到TTL UART接口转换芯片CP2102(来自SiLabs),通过计算机的USB端口仿真UART通信
使用UART最容易碰到的问题:
RX-To-TX & TX-To-RX
波特率失配
如果数据以9600bps的波特率传输,并以19200bps的速率接收。 收到的数据将是一团垃圾! 波特率必须在发送端和接收端匹配,这是UART串行通信的经验法则,波特率的最大允许偏移趋于介于(1-2%)之间。 因此尝试在两端生成完全相同的波特率,以避免错配错误。
UART总线长度 vs 波特率
UART串行总线可以传输很长的距离,但传输的距离以及最高能够达到的波特率都取决于传输得越远,波特率也就会降低,它还取决于UART协议本身的硬件实现(物理层)。我们只提到TTL-UART和RS-232标准。
RS-232
TTL-UART
TTL电平的UART仅支持5V的电压摆幅,因此信号传输的距离以及能够支持到的波特率取决于下面的3个元素:
- 电缆的电阻 - 电缆越长电阻也就越高
- 电缆的电容:大家知道电容效应会阻碍信号电平的变化
- 噪声:任何环境中都会有噪声,带屏蔽的双绞线电缆对信号的传输会有帮助
UART的构成
一个UART一般包含了如下的一些组成部分:
- 一个时钟发生器,通常是比特率的整数倍,以便能够在一个bit周期的中间进行采样
- 输入和输出移位寄存器
- 发送/接收控制
- 读/写控制逻辑
- 发送/接收缓存(可选)
- 系统数据总线缓存(可选)
- 先进先出(FIFO)缓存(可选)
- 第三方DMA控制器需要的信号(可选)
- 掌管DMA控制器的集成化总线(可选)