跳转至

串口

我们通常说的串口,可以有两种意思:

  1. 一是指 UART 协议
  2. 二是泛指串行接口,与并行接口相对

我们接下来要讲的是第一种,也就是 UART 协议。由于英文比较拗口,所以我们通常称它为串口。

介绍

本文讲述的是 UART 协议的信号和波形。对于完成实验来说,只需要大概了解 UART 协议的原理,不需要深入理解其硬件的实现。

UART 协议在实验中的用途

我们为什么要学习 UART 呢?对于一台计算机来说,不能只有 CPU 和 内存,它还需要接收来自用户的输入。现实生活中,我们通常会用鼠标和键盘作为计算机的输入,但是这些对于实验来说,实现起来比较复杂。

让我们仔细想想,既然鼠标和键盘过于复杂了,我们至少需要什么?鼠标是不必要的,只需要键盘输入命令,可以看到结果就可以了。继续简化,我们不考虑同时按下多个按键,只考虑简单的输入,比如英文字母,数字,回车等等。很巧,这些输入正好都可以用 ASCII 码表示,那就可以很简单地把输入转换编码为一个个字节,然后设法传输给计算机即可。

同理,我们也可以用同样的方法进行输出:回忆一下,我们经常用的 printf/cout 等输出方式,不也是在输出 ASCII 码吗?正好,也是把一个一个字节从计算机输出到“显示器”上,就可以看到结果了。

所以为了实现我们自己造的计算机可以进行交互,只需要一个可以传输一个个字节的协议就可以了。答案到这里已经呼之欲出了:这就是 UART 协议的用途。

在今天,UART 协议在嵌入式开发、硬件调试和网络运维等场景中依然可以见到。

UART 协议

UART 协议的历史很长,但由于其简单和实用的特点,到现在还在使用。它的特点是只需要两条信号线就可以实现全双工,即两端可以同时收发。如果 UART 连接了 A 设备和 B 设备,那么这两条信号线,分别是从 A 发送到 B 和从 B 发送到 A。于是,根据收和发,我们一般把这两条信号线命名为:

  • rx/rxd:receive,接收
  • tx/txd:transmit,发送

UART 协议的设计

接下来,我们可以思考一下,如果我们要设计一个只用一根信号线发送数据的协议,我们可以怎么做。为了尽量简单,我们可以这样设计:

  1. 输出的信号只有 0 和 1
  2. 人为固定一个时间间隔,即把 1s 分成很多份,每个时间间隔内,信号一直是 0 或者 1 保持不变,这样发送比较简单
  3. 那么,如果要传输一个字节,最简单的方法就是用 8 个时间间隔,每个时间间隔传一个 bit;例如如果要传输 0x12 字节,转换为二进制,就是 0b00010010,然后分成 8 次,一个一个位传输
  4. 但是,上面的办法无法判断什么时候是一个字节的开始和结束
  5. 为了把传输的每个字节区分开,设定:不传输数据的时候一直输出 1,传输字节前输出一个时间间隔的 0,然后是字节的 8 个位,最后输出一个时间间隔的 1
  6. 这就是 UART 协议

如果我们规定,发送字节的时候,从最低位开始传,那么传输 0x12 就是如下的波形:

txabcdef
  • a 和之前:没有传输数据,所以一直是 1
  • b:即将传输一个字节,所以先输出一个 0
  • c 到 d:8 个时间间隔,输出 0, 1, 0, 0, 1, 0, 0, 0,即 0x12 从最低位到最高位
  • e:已经传输完字节,输出一个 1
  • f 和之后:没有传输数据,所以一直是 1

通讯的双方约定一个时间间隔的长度,然后都按照上面的方式进行发送。这样就实现了 UART 协议。我们通常把 UART 协议中 1s 时间间隔的个数记为波特率(Baud Rate)。常见的波特率有 9600 和 115200。


最后更新: 2022年8月23日
作者:Jiajie Chen