什么是UART?
通用异步接收器/发送器,通常称为UART,是一种广泛应用于嵌入式领域的串行、异步、全双工通信协议。
串口连接
UART 通道有两条数据线。每个设备上都有一个 RX 引脚和一个 TX 引脚(RX 用于接收,TX 用于发送)。每个设备的 RX 引脚都连接到另一个设备的 TX 引脚。请注意,没有共享时钟线!这是通用异步接收方发送方的“异步”方面。
UART作为一种异步串行通信协议,其工作原理是逐位传输传输数据的每个二进制位。在UART通信协议中,当信号线上的状态为高时,代表“1”,当信号线上的状态为低时,代表“0”。
例如,当采用UART通信协议传输一字节数据时,信号线上会产生八种高低电平组合。
- 串行通信是指利用一根传输线逐位依次传输数据,也可以用两根信号线组成全双工通信,如rs232。特点是通信线路简单,使用简单的电缆即可实现通信,成本降低,适合远距离通信的应用,但传输速度慢。
- 异步通信以一个字符为传输单位。通信中两个字符之间的时间间隔不固定,但同一字符中两个相邻位之间的时间间隔是固定的。一般来说,两个UART设备之间的通信不需要时钟线。此时,需要在两个UART设备上指定相同的传输速率,以及空闲位、起始位、奇偶校验位和结束位,即遵循相同的协议。
- 数据传输速率以波特率表示,即每秒传输的位数。例如,如果数据传输速率为120个字符/秒,每个字符为10位(1个起始位、7个数据位、1个校验位、1个停止位),则其传输的波特率为10×120 = 1200 个字符/秒 = 1200 波特率。
数据通讯格式如下:
起始位
每次通信开始时,发送方发送一个逻辑“0”信号(VOL),表示传输字符的开始。由于总线空闲时为高电平,因此在开始通信时先发送一个与空闲状态明显不同的信号,即VOL。
数据位
起始位之后是我们要传输的数据。数据位可以是5、6、7、8、9位等组成一个字符(通常是8位)。如ASCII码(7位)、扩展BCD码(8位)。首先发送最低位,最后发送最高位。用低电平 表示“0”,高电平表示“1”,完成数据位的传输。
奇偶校验位
将该位添加到数据位后,“1”位的个数应为偶数(偶校验)或奇数(奇校验),以验证数据传输的正确性。校验位实际上就是调整数,串口校验分为几种方式:
无奇偶校验
奇校验:如果数据位中“1”的个数为偶数,则奇偶校验位为“1”,如果“1”的个数为奇数,则奇偶校验位为“0”。
偶校验:如果数据中“1”的个数为偶数,则奇偶校验位为“0”,如果数据中“1”的个数为奇数,则奇偶校验位为“1”。
标记奇偶校验:校验位始终为1(不常用)。
奇偶校验:奇偶校验位始终为0(不常用)。
停止位
它是字符数据的结束标记。它可以是 1 位、1.5 位或 2 位 VOH。由于数据在传输线上是定时的,并且每个设备都有自己的时钟,所以在通信时两个设备之间很可能会出现小的不同步。因此停止位不仅表示传输的结束,而且还为计算机提供了纠正时钟的机会。停止位越多,数据传输越稳定,但数据传输速度越慢。
协议层
在协议层中,规定了数据包的内容,由起始位、主要数据、校验位和停止位组成。双方的数据包格式必须约定一致,才能正常发送和接收数据。
例如mavlink协议
波特率
由于异步通信中没有时钟信号,因此两个通信设备需要就波特率达成一致。常见的有4800、9600、115200等。
通讯起始和停止信号:串行通讯的数据包从起始信号开始,以停止信号结束。数据包的起始信号用逻辑0的数据位表示,数据包的停止信号可以用0.5、1、1.5或2个逻辑1的数据位表示,只要双方同意即可。
数据校验:有效数据后有一个可选的数据校验位。由于数据通信比较容易受到外界干扰,导致传输数据出现倾斜,可以在传输过程中添加校验位来解决这个问题。校验方式有奇校验、偶校验、0校验(空格)、1校验(标记)、无奇偶校验。
奇校验要求有效数据和奇偶校验位中“1”的数量为奇数。
例如,8位有效数据为01101001,共有4个“1”。如果校验位为“1”,则最后发送的数据为8位有效数据加1位校验位,共9位。偶校验和奇校验的要求正好相反。要求帧数据中“1”的个数和奇偶校验位均为偶数,如数据帧:11001010,此时数据帧中“1”的个数为4个,因此偶校验位为“0”。0校验表示无论有效数据的内容是什么,校验位始终为“0”,1校验表示校验位始终为“1”。
错误状态
以下是您在使用 UART 时可能遇到的一些错误
帧错误
UART 状态和控制寄存器将指示各种状态条件,包括与传输相关的错误状态。了解此协议可以更轻松地理解错误状态。其中包括帧错误,当接收器在预期位时间没有看到停止位时就会发生帧错误。如果在预期停止位时数据线未处于预期的高状态(取决于设置 UART 的数据和奇偶校验位的数量),则 UART 将发出帧错误信号。
奇偶校验错误
仅当 UART 处于奇偶校验模式时才会引发奇偶校验错误。在奇偶校验模式下,会发送一个额外位来保存所有传输数据位的奇偶校验(偶数或奇数)。如果数据位有错误(1 代表 0 或 0 代表 1),则奇偶校验位将错误,并且将抛出指定错误的错误。
溢出错误
当接收器在下一个字符到达之前不进行处理(从输入缓冲区中删除一个字符)时,就会发生溢出错误。
中断条件
中断条件不一定是错误。当接收器输入处于逻辑低状态超过一定持续时间(通常超过一个字符时间)时,就会发生这种情况。对于接收者来说,它看起来像是一个带有帧错误的全零字符。这是针对软件复位电路的黑客攻击。在python代码中,可以看到reset是通过发送break来触发的。这会将数据线拉低足够长的时间,以便将 MCLR 拉低并使电路板复位。
这是 UART、I2c 和 SPI 之间的区别
协议 | 复杂度 | 传输速度 | 设备数量 | 线数 | 复式 | 主从数量 |
UART | 简单的 | 最慢 | 最多 2 台设备 | 1 | 全双工 | 单对单 |
I2C | 轻松链接多个设备 | 比 UART 更快 | 最多 127 个,但变得复杂 | 2 | 半双工 | 多个从机和主机 |
SPI | 随着设备的增加而复杂 | 最快的 | 很多,但变得复杂 | 4 | 全双工 | 1个主站,多个从站 |
您可能想知道,这三种通信方式中哪一种最好?是 UART、I2C 还是 SPI?
不幸的是,不存在“最好的”通信外围设备。每个通信外设都有其自身的优点和缺点。
因此,用户应该选择最适合自己项目的通信外设。例如,如果您想要最快的通信外设,SPI 将是理想的选择。另一方面,如果用户想要连接多个设备而又不想太复杂,I2C将是理想的选择,因为它最多可以连接127个设备并且易于管理。