第七章:串行总线与接口技术

总线 是微型计算机系统、嵌入式系统、智能仪器内部及相互之间传递信息的公共通道,微控制器系统内部及微机系统之间信息的传递都是通过总线进行的 。利用总线技术,能够简化系统结构,增加系统的兼容性、开放性、可靠性和可维护性,便于系统的模块化、标准化设计。总线包括芯片总线、系统总线、通信总线。
通信 是计算机与微机系统或智能系统之间信息交互的主要方式(使用通信总线,下面会具体介绍)。目前,大量串行接口芯片的产生使得微机系统的串行扩展成为一种发展趋势。串行总线占用微控制器的 I/O 接口资源少,可直接与许多外围器件连接,结构简单。

总线概念与分类

总线概念: 总线是指微控制器系统、智能仪器内部以及相互之间传递信息的公共通道,是芯片内部模块之间系统内部器件之间 以及两个或多个系统之间 的实际连线。
总线协议: 保证信息可靠交换,对总线信号、传递规则以及传输的物理介质等作出的一系列规定。 用于规范组件之间的数据传输、命令交互、时序同步及错误处理等行为
总线标准: 被某个标准化组织批准或推荐的总线协议。以确保不同厂商、不同类型的硬件能高效、可靠 地协同工作。(相当于组件间的 "通信语言")
**标准总线:**符合某种总线标准的总线。RS232、RS485、I2C、SPI等都是标准总线

总线按其使用范围或者连接对象不同,可分为芯片总线、系统总线和通信总线 ;按照信号传送的方式不同,又可分为并行总线和串行总线

  • 芯片总线: 芯片总线是连接芯片内部各功能模块的通道,用于模块之间的信息传输 。如微控制器内部有连接存储器、I/O 端口等的数据总线 DB、地址总线 AB 和控制总线 CB。芯片总线常采用分时复用方式 ,即在不同时刻传送不同类型的信息(如地址信息、数据信息和控制信息分时复用同一组总线),这种总线结构称为单总线结构 。微控制器的片内总线大多采用并行的单总线结构。例如,8051 单片机内部的芯片总线用来连接 CPU 内核、寄存器(THx/TLx、TMOD 等)、RAM、ROM、I/O 端口这些内部模块,比如 CPU 读取 TH0 寄存器的数值时,就是通过芯片总线来完成数据传输的
  • 系统总线:系统总线 是指由多个器件 组成的智能系统内部各器件 之间传送信息的通道,是将器件或模块构建成系统需要采用的总线,也称为内总线 。系统总线分为并行系统总线 (如 PCI 总线、VXI 总线等)和串行系统总线(如 I²C、SPI、1-Wire 等)两类。本章主要介绍串行系统总线。例如,电脑主板的系统总线如早期的 PCI 总线、现在的 PCIe 总线,用来连接主板上的显卡、声卡、网卡等扩展设备。
  • 通信总线:通信总线两个或多个系统之间 (如多个计算机或智能系统之间)传送信息的通道,是系统间信息交互或多系统构建网络采用的总线,也称为外总线。通信总线也分为并行通信 总线(如 IEEE488 总线)和串行通信 总线(如 RS232、RS485 总线等)两类。
    并行通信是指数据字节的各位同时被传送或接收的通信方式,其特点是传输速度快,但当传输距离远、位数多时,会提高硬件成本、降低通信成功率,除此之外,并行通信的多根数据线间距近,相邻线路信号易产生 "串扰" ,且传输距离越长、速度越快,串扰越严重,因此实际速率会大幅下降。串行通信 是指数据字节的各位按顺序逐位发送和接收的通信方式,其特点是只需 2~3 根传输线,线路简单、成本低,特别适合远距离通信,但其传输速度相对并行通信要慢。"并行通信的理论传输速度高于串行通信"这一结论受传输距离、成本和干扰等实际因素制约,在长距离传输场景下串行通信反而更具优势。

在下图中,集成芯片(如芯片 A 和芯片 B)内部的各个模块通过芯片总线 交互信息,通常为并行总线 。由多个芯片组成的系统(如系统 A),内部多个芯片之间采用系统总线(内总线) 进行信息交互,系统总线有串行的 I²C、SPI 等和并行的 PCI、VXI 等。系统与系统之间(如系统 A 和系统 B)的信息交互称为通信 ,包括串行通信和并行通信 ;串行通信总线主要有 RS232、RS485、CAN、USB 等,并行通信总线主要有 IEEE488 等。在微控制器系统中已很少使用并行总线

注意,串行通信和并行通信一般指通信总线的串行和并行传输方式。但是,串行和并行是数据的传输方式,不特指某一总线,也就是说芯片总线和系统总线也存在串行和并行,只是很少会被称为"串行通信"或者"并行通信"。对于串行与并行的定义和串行通信与并行通信的定义是一样的,分别是逐位传输与同时传输。

芯片内部总线都是并行总线,因为芯片内部的空间足够,并行传输可以获得更高的速度,比如 8051 内部的芯片总线是 8 位并行的,用来同时传输 1 字节的数据。系统总线有并行和串行的类型,并行的系统总线比如 8051 的外部扩展总线(P0+P2 的地址数据总线)是并行的,早期电脑的 PCI 总线也是并行的;串行的系统总线比如单片机开发板上的 SPI 总线,也以作为系统总线连接板载的芯片。

通信总线的串行通信有UART、I2C、SPI、USB、以太网等,并行总线有并行打印机协议(早期打印机通信协议)、IDE(早期硬盘的通信协议)等;串行的系统总线有I2C、SPI、PCIe,并行的系统总线有PCI、8051 外部扩展总线协议等。

通信双方按数据传送方向有三种形式:即单工方式、半双工方式和全双工方式。

  • 单工传送方式通信双方只有一条单向传输线,一方发送,另一方接收。
  • 半双工传送方式通信双方只有一条双向传输线,但同一时刻只能有一方发送,另一方接收。 是一种能够切换传送方向的单工方式。
  • 全双工传送方式通信双方有两条传输线,允许数据同时双向传送。

异步通信与同步通信

串行通信可分为异步通信和同步通信。异步通信没有专门的时钟信号线,收发双方提前约定好传输的节奏(波特率),依靠数据本身的格式来判断传输的时机;同步通信有专门的时钟信号线,收发双方依靠时钟信号的跳变来同步数据传输的节奏,工作逻辑是收发双方共用同一个时钟信号,发送方会在时钟信号的特定跳变沿(比如上升沿、下降沿)发送数据,接收方会在同样的跳变沿读取数据,其数据是连续传输的,不需要像异步通信一样在每一组数据都加起始位和停止位,只需要在数据开头加上同步字符,用来告诉接收方 "数据传输开始了"。

异步通信ASYNC (asynchronous data communication)

数据帧格式

在异步通信中,由于没有专门时钟信号线,通信双方也不会提前约定数据的发送时间(波特率只是约定了一个数据位的时长,而不是发送的频率),发送方可以在任意的空闲时刻发送数据,接收方是处于 "随时等待" 的状态,接收方平时只会监测传输线的电平状态,只有当检测到「空闲高电平→低电平」的跳变(也就是起始位)时,才会确定 "对方现在开始发送数据了",然后才会按照波特率约定的节奏,去读取后续的数据位、校验位和停止位。

数据或字符是逐帧(frame)发送的。数据帧是 1 个字符完整的通信格式,也称为 "帧格式"。数据帧由起始位、数据位、奇偶校验位和停止位 4 部分组成。

数据帧中各部分的作用如下:

  • 起始位:通信线上在不传送数据时(即空闲时),为高电平(逻辑 "1");当要发送数据时,首先要发 1 个低电平信号(逻辑 "0")。此信号称为 "起始位",表示将开始一帧数据的传送。
  • 数据位:起始位之后要发送的数据位。数据位可以是 5~8 位(常用 8 位)。异步传送规定低位在前、高位在后。
  • 奇偶校验位:数据位之后发送奇偶校验位。奇偶校验位可用于判别字符传送的正确性。用户可根据需要选择奇校验、偶校验或不用校验位,须通信双方事先约定。
  • 停止位:校验位后是停止位,表示一帧数据通信结束。停止位是 1~2 位的高电平(逻辑 "1")。

异步通信的特点

  • 异步通信是以字符(数据帧)为单位进行传输的,帧与帧之间的时间间隔可任意,即帧与帧之间是异步的,通过起始位控制通信双方正确收发。
  • 每个数据帧内的各位要以固定间隔传送,且通信双方要设置相同的波特率,控制数据帧收发的同步。
  • 由于在数据帧中插入了为实现收发同步的起始位、停止位等附加位,因此降低了有效数据位的传送效率。
  • 异步通信的数据帧有固定格式,通信双方只需按约定的帧格式收发数据,硬件结构比同步通信方式简单。异步通信常用作串行通信总线(外总线),如 RS232、RS485 等。

通信波特率

波特率是异步通信的一个重要指标,反映了数据传送的速率 ,用每秒传送的二进制位数 b/s 或 bps (bit per second) 表示。

例如,每秒要传送 120 个字符,设每个字符为 10 位(1 个起始位、8 个数据位和 1 个停止位),则其波特率为:10b×120/s=1200bps。每位数据的传送时间Td​为波特率的倒数,当波特率 = 1200bps 时,Td​=1/1200=0.833ms。接收方在接收一帧数据的起始位后,依照这个波特率约定在之后的每 104 微秒依次读取数据位、校验位、停止位的电平。

同步通信SYNC (synchronous data communication)

数据帧格式

同步通信是一种连续串行传送数据的通信方式,要求发送端和接收端采用同一个时钟信号,依靠时钟信号的跳变来精准对齐数据的发送和接收时机,发送方什么时候发、接收方什么时候读,完全由时钟信号来控制。时钟信号由发起通信的主机发出,称为同步时钟信号。同步时钟信号控制通信双方收发的同步,其频率决定通信的速率。同步通信需要三线制:数据线 (SDA)、同步时钟线 (SCL)、公共地 (GND)。同步通信以 "数据序列" 为单位进行通信,其格式如图所示,包括以下三部分

数据帧中各部分介绍如下:

  • 同步字符 :数据开始传送的同步字符(常约定为 1 至若干字节),以实现发送端和接收端的同步。同步通信虽然有共用的时钟线,但是在数据传输刚开始的时候,收发双方的时钟可能会有微小的相位偏差,或者接收方可能没有准备好接收数据,此时同步字符可以让接收方校准自己的时钟采样时机,和发送方的时钟完全对齐并告诉接收方正式的有效数据马上就要开始传输了。
    同步字符是一个提前约定好的、具有特殊二进制规律的字节(一般是 1 字节),比如最常用的同步字符是0xAA(二进制1010 1010)或者0x55(二进制0101 0101),这些数据的电平跳变很规律,方便接收方校准时钟
    不是所有的同步通信协议都需要同步字符:比如 SPI 协议因为有片选信号来标记帧的开始,一般不需要;而像 SDI、以太网的同步传输部分,会需要同步字符
  • 数据块:要通信的数据内容。发送方和接收方在同步字符结束后,连续、顺序地发送和接收。
  • 校验字符:为检测通信数据的正确性,在数据块发送完毕后,通常要按约定发送数据块的校验码。校验方式和校验码长度,按通信双方约定的通信协议进行。关于校验字符的具体校验方式会在下面介绍。

下面我们以"主机(单片机)向从机(SPI 闪存芯片)发送0x31(二进制0011 0001,对应 ASCII 字符的 "1")"为例说明同步传输的过程: 由于SPI并没有介绍过,而且由于SPI 主要用在同一个电路板上的芯片之间通信(比如单片机和板载的闪存、ADC、OLED),传输距离非常短,电磁干扰的概率很低,数据出错的概率本身就很小,所以没有设置校验字符,这里只需要结合下面的过程对同步传输有一个大体的了解即可。先对SPI进行一个简要介绍,SPI 是典型的主从式同步通信,必须有一个主机(产生时钟)和至少一个从机,硬件连接有 4 根线:
SCLK(Serial Clock) :时钟线,由主机产生,用来同步收发节奏
MOSI(Master Output Slave Input) :主机发、从机收的数据线
MISO(Master Input Slave Output) :从机发、主机收的数据线(本次只讲主机发数据,这条线暂时不用)
CS(Chip Select):片选线,由主机控制,用来选择要通信的从机

下图为一主多从的同步通信,可以看到,每个从机的MISO、MOSI、SCLK分别连接到主机的MISO、MOSI、SCLK,即共用数据线和时钟线,如果从设备同时往MISO上发送数据或者同时从MOSI接收数据,由于线是共用的必然会造成干扰,所以必须保证同一时间只有一个从设备和主设备进行通信,从而有了片选线CS(图中为/SS)。

  • **准备阶段:**主机的 SPI 控制器已经完成初始化:设置了时钟频率(比如 1MHz)、采样规则、数据传输顺序,此时 SCK、MOSI、/SS 都处于高电平的空闲状态,从机处于等待被选中的状态。
  • **选中从机:**主机把 从设备#1 的/SS引脚的电平从高拉到低,从设备#1检测到自己的 /SS 引脚被拉低之后,会激活内部的 SPI 接收电路,进入 "等待接收数据" 的状态
  • 主机产生时钟,逐位发送数据: 主机要发送的0x31,二进制是0011 0001,从最高位开始的每一位依次是:0→0→1→1→0→0→0→1。主机会按照约定的时钟频率产生 SCLK 信号,每一个时钟周期完成 1 位数据的发送。
    第一个SCLK周期,主机在 SCLK 上升沿到来前,把第 1 位(最高位)的0放到 MOSI 线上,主机产生 SCLK 上升沿,从机检测到上升沿后,准备读取数据,主机产生 SCLK 下降沿,从机在这个下降沿读取 MOSI 线上的0,把这个位存入自己的接收寄存器的最高位
    第二个SCLK周期,主机在 SCLK 上升沿到来前,把第 2 位的0放到 MOSI 线上,主机产生 SCLK 上升沿,从机准备读取,主机产生 SCLK 下降沿,从机读取 MOSI 线上的0,存入接收寄存器的第 6 位
    以此类推,直到完成 8 位数据的全部传输,从机的接收寄存器里会存入完整的0x31
  • 取消片选: 主机把CS 引脚的电平从低拉高,从机检测到 CS 拉高之后,会关闭内部的 SPI 接收电路,结束本次通信。同时从机会把接收寄存器里的0x31,送到对应的功能模块(比如闪存的命令寄存器,执行对应的操作)

同步通信的特点

  • 由于同步通信的数据帧不需要加入起始位和停止位,因此在相同传输速率下,其传送效率高于异步通信。
  • 同步通信需要同步时钟信号,以保证发送方和接收方的同步。
  • 同步通信常用于串行系统总线(内总线),如 I²C、SPI、USB 等

通信协议与校验方式

通信协议

通信协议是通信双方进行数据传输时的一些约定,包括数据帧格式、波特率、校验方式和握手方式等。为保证准确、可靠的通信,通信前双方要制定通信协议,约定双方应采用相同的数据帧格式、波特率和校验方式;通信时双方必须遵循该协议。

校验方式

  1. 字节的奇偶校验: 奇偶校验是以字符为单位进行的,通过在数据帧的校验位上,设置 "0" 或者 "1",使得数据帧中有效数据位的 "1" 的个数为奇数个(称奇校验)或偶数个(称偶校验)。(数据帧中的有效数据位不包括起始位和停止位)

    以0x31为例,x31的二进制是0011 0001,其中共有三个1。
    奇校验 要求总 1 的个数是奇数,当前已经有 3 个 1(是奇数),所以校验位需要是0(0 个 1),这样总个数是 3+0=3(奇数),满足要求
    偶校验 要求总 1 的个数是偶数,当前已经有 3 个 1(是奇数),所以校验位需要是1(1 个 1),这样总个数是 3+1=4(偶数),满足要求
    发送方要发送的字节是0x31,计算出它的奇校验位是0,主机先发送0x31,再发送校验位0(即发送数据为0011 0001 0),接收方先接收0x31,自己统计其中 1 的个数,得到 3 个,再接收校验位0,统计校验位的 1 的个数,得到 0 个,把两个数相加:3+0=3,是奇数,和约定的奇校验规则一致,判定数据传输正确;如果相加的结果是偶数,就判定数据传输出错,会请求主机重新发送
    如果数据帧有两个bit发生错误,不影响1的奇偶个数,这时奇偶校验就失效了。因此奇偶校验只能检测出数据帧中发生的奇数个bit错误,无法检出偶数个bit错误的情况。

  2. **数据块的累加和检验:**设传送的数据块有n个字节,发送方在数据块传送之前或在传送过程中,对这n个字节发送数据进行累加运算,形成n个数的 "累加和",并把该 "累加和" 附在n个字节后面传送。接收方在接收过程或接收到n个字节后,对n个字节接收数据进行累加运算,形成n个数的 "累加和"。接收方把对方发送的 "累加和" 与自己产生的 "累加和" 进行比较,若相等,表示整个数据块传送正确,否则表示数据块中有数据出错。

  3. **数据块的循环冗余校验CRC:**将整个数据块看成是一个很长的二进制数(如将n字节的数据块看成8×n位的二进制数),然后用一个特定的数去除它,其余数就是 CRC 校验码,附在数据块后面发送。接收方在接收到数据块和校验码后,对接收的数据块进行同样的运算,得到的 CRC 校验码若与发送方的 CRC 校验码相等,表示数据传送正确,否则表示传送出错。

奇偶校验与累加和校验虽然使用较为方便,但校验功能有限。奇偶校验对字符中的奇数个 bit 错误能够检出,对发生偶数个 bit 错误的情况,则不能检出。累加和校验可以发现几个连续字节改变的差错,但不能检出数字之间的顺序错误(因为数据交换位置累加和不变)。循环冗余校验具有极高的检出率,通常高达 99.9999%。因此,循环冗余校验 CRC 是常用的数据块校验方式。

8051微控制器的UART

8051 MCU 有一个全双工异步串行通信接口,它可用作 UART(universal asynchronous receiver/transmitter,通用异步接收发送设备),也可作为同步移位寄存器。

UART组成结构

UART 的结构如下图所示,由发送数据缓冲器 SBUF(serial data buffer,地址为 99H,只写)、发送控制器、并入串出移位寄存器,接收数据缓冲器 SBUF(地址为 99H,只读)、接收控制器、串入并出移位寄存器,以及串行口控制寄存器 SCON、电源控制寄存器 PCON 等组成。因为发送 SBUF 和接收 SBUF 在物理上是完全独立的,因此可以同时进行数据的接收和发送,即是一个全双工通信口。

串行口控制寄存器SCON(serial control)

SCON 用于串行通信的方式选择、接收和发送的控制,存放接收和发送中断标志,以及发送和接收的第 8 位信息(数据位的 D7~D0,是第 7~0 位)。SCON 位地址为 98H,既可字节寻址,也可位寻址。SCON 各位的功能说明见下表 。各位定义如下:

7 6 5 4 3 2 1 0
位符号 SM0 SM1 SM2 REN TB8 RB8 TI RI
英文注释 serial mode bit 0 serial mode bit 1 serial mode bit 2 receive enable transmit bit 8 receive bit 8 transmit interrupt flag receive interrupt flag
位符号 功能说明
SM1、SM0 串行口工作方式选择位,功能如下: 关于工作方式的具体过程将在下面介绍
SM2 SM2 是串行口多机通信控制位,主要用于在模式 2/3 下区分 "地址帧" 和 "数据帧",实现主机对特定从机的精准通信,模式 1 下仅用于校验帧错误,模式 0 下无效。 关于SM2在四种工作模式下的作用,涉及内容解释较多,在表格下方。
REN 接收允许控制位。由软件置 1 或清 0。REN=1,表示允许串行模块接收数据;REN=0,则禁止接收
TB8 方式 2 和方式 3 时,数据帧中要发送的第 8 位数据 (或奇偶校验位),须事先用软件写入该位
RB8 方式 2 和方式 3 时,数据帧中接收到的第 8 位数据 (或奇偶校验位)
TI 发送中断标志位。发送完一帧数据时,硬件置位 TI。TI 必须由软件清 0
RI 接收中断标志位。接收到一帧数据时,根据 SM2 的值决定是否置位 RI。RI 必须由软件清 0

关于SM2在工作方式0下的具体介绍: 当工作在方式 0 时,SM2 必须置为"0",否则无法正常工作(硬件逻辑限制)。
关于SM2在工作方式1下的具体介绍: 当工作在方式 1 时,SM2 通常置 0,此时只要接收到 1 帧数据(8 位 + 起始 / 停止位),就会将数据送入 SBUF,并置位 RI(接收中断标志)。

若 SM2=1,只有当接收到的停止位为 1 时,才会触发 RI;若停止位为 0,数据会被丢弃,RI 清0。实际应用中,模式 1 下 SM2 主要用于简单的帧错误检测,绝大多数场景都会把 SM2 设为 0。"在SM2=1时 只有当接收到的停止位为 1 时,才会触发 RI" 这种设计实际上是8051 硬件层面为异步通信的帧完整性校验设计的极简容错机制,早期 8051 设计时(1980 年代),单片机的资源极其有限(ROM/RAM 以 KB 为单位,无复杂外设),无法像现代 MCU 那样做 CRC、奇偶校验等复杂校验,而停止位是异步帧的最后一位,正常通信中,停止位必须是高电平(1);如果停止位为 0,说明这一帧数据大概率是噪声干扰(比如串口线受电磁干扰)或帧同步错误(波特率不匹配、发送方异常)导致的无效帧,SM2=1 时的逻辑,本质是让硬件自动 "过滤无效帧":只有停止位为 1(帧结构完整),才认为数据有效,触发 RI 通知 CPU 处理;停止位为 0 则直接丢弃,避免 CPU 处理错误数据。
关于SM2在工作方式2/3下的具体介绍(包括TB8、RB8的介绍):

当工作在方式 2 或 3 (SM2 最核心的应用场景,专门用于多机通信),在模式2/3下UART为11位,包括1 位起始位(0)、8 位数据位 、1 位第 8 位(TB8/RB8)(数据帧的第一个数据为第0位,第8位为第9个数据)、 1 位停止位(1)。

首先,要知道在UART多机通信中,所有设备的 RXD 接在一起、TXD 接在一起,主机发的每一个字节,所有从机都能接收到(相当于 "广播"),必须解决 "从机怎么知道这帧数据是发给自己的" 问题,对于上面介绍的SPI而言它有独立的片选线来选择从机,但是对于8051MCU的UART而言,它只有RX和TX引脚,没有独立的片选引脚,所以主机要选择从机必须先发送一帧地址数据(每个从机都有唯一的地址),从机收到地址数据才知道选中的是自己,然后开始与主机通信。但是有一个问题就是从机发送数据帧是连续发送的,从机怎样才能知道哪一帧是地址帧哪一帧是数据帧呢,其中第8位TB8(即SCON中的TB8位)就可以解决这个问题,第8位TB8为帧类型标识位,可以用来标记地址 / 数据,如果发出的一帧数据的第8位为1,则表示这是地址帧,否则为数据帧。

模式 2/3 的每一次发送,都是固定的 11 位结构:起始位 + 8 位数据 + 第 8 位 + 停止位,每帧的第 8 位都需要单独设置:发地址帧时,提前把 TB8 设为 1,这一帧的第 8 位就是 1;发数据帧时,提前把 TB8 设为 0,这一帧的第 8 位就是 0。

SCON中的RB8和TB8是一样的,也是帧类型标识位,只不过是接收到数据的第8位,如果主机开启了接收(REN=1),会把接收到的从机回复的第 8 位存入 RB8(比如从机回复主机时,也可以用第 8 位做标签)。MCU在作为从机时常使用RB8,用来判断主机是否选中了自己,MCU作为从机时SM2=1,此时如果RB8=1意味着主机发了地址帧,是从机需要处理的,所以会触发 RI(接收中断),通知 CPU 来处理。

当MCU为主机时通常设置SM=0,表示关闭 "帧类型筛选功能"(不需要筛选帧,主机发送的帧是自己主动控制的,接收的帧是从机回复给自己的,),当前 MCU 的串行口会接收所有的帧(不管第 9 位是 1 还是 0),只要接收到完整的 11 位帧,就会触发 RI(接收中断),把数据存入 SBUF。

当MCU为从机时设置SM=1,此时MCU会不断接收主机数据,一旦是地址帧且和自己地址匹配,则置SM=0,意味着 "已经被主机选中,准备接收数据帧"。

除此之外,TB8和RB8还可以作为奇偶校验位。TB8/RB8不是用作帧类型筛选位吗,还能同时用于奇偶吗?对于点对点通信不需要地址帧,所以TB8和RB8可以直接用于奇偶校验;对于多机通信,地址帧固定TB8为1,所以在地址帧中肯定不能作为奇偶校验位,但是地址帧发送完成后的数据帧是不是就可以将TB8作为奇偶校验位?实际上是可行的,但是其他从机此时正在持续接收地址帧,所以将TB8作为数据帧的奇偶校验可能会导致其他从机错误认为这是自己的地址帧。解决方法也有很多,这里就不作过多介绍了。

电源控制寄存器PCON (power control)

7 6 5 4 3 2 1 0
位符号 SMOD --- --- --- GF1 GF0 PD IDL
英文注释 serial mode --- --- --- general flag 1 general flag 0 power down bit idle mode bit

SMOD:波特率选择位。SMOD=1,表示波特率加倍,否则不加倍。

数据缓冲器 SBUF (serial data buffer)

串行模块中有两个地址相同(均为 99H)但物理空间独立的数据缓冲器 SBUF,一个为发送 SBUF,另一个为接收 SBUF。发送 SBUF 只写,接收 SBUF 只读。发送时,MCU 写一个数据到 SBUF(如 MOV SBUF,A),是向发送 SBUF 写入数据;接收时,MCU 读一次 SBUF(如 MOV A,SBUF),是从接收 SBUF 读取串行口接收到的数据。

下面关于并入串出移位寄存器、串入并出移位寄存器、发送/接收控制寄存器涉及串行口更详细的工作过程,建议在看完"UART的工作方式"后再回来学习。

并入串出移位寄存器(发送移位寄存器)

一个 8 位的同步移位寄存器,作用是将并行数据转为串行数据。不管是方式 0 还是方式 1/2/3,发送数据时,都是先把并行数据(从 SBUF 写入,可以看到从SBUF到发送移位寄存器之间是连有8跟线的)加载到这个移位寄存器中,再逐位移出到 TXD 引脚。

发送移位寄存器工作过程如下:

  • 软件将 8 位数据写入发送 SBUF(只写寄存器);
  • 硬件自动将发送 SBUF 中的并行数据并行加载到并入串出移位寄存器中;
  • 根据工作方式的不同,由发送控制器提供移位时钟,每产生一个有效的时钟脉冲(通常是时钟的上升沿),发送移位寄存器就会把 1 位数据移位输出到 TXD(或方式 0 的 RXD)引脚上,8 位数据需要 8 个时钟脉冲完成发送:
    • 方式 0:移位时钟是fosc/12(内部机器周期时钟),从 TXD 输出;
    • 方式 1/2/3:移位时钟是波特率时钟(由定时器 1/2 或晶振分频得到);
  • 移位寄存器按照时钟脉冲,将数据低位在先逐位移出到 TXD 引脚(方式 0 时是 RXD,方式 1/2/3 时是 TXD)。

串入并出移位寄存器(接收移位寄存器)

一个 8 位(方式 0/1)的同步移位寄存器,作用是将串行数据转为并行数据。接收数据时,将 RXD 引脚输入的串行数据逐位移入,积累为完整的 8 位并行数据后,存入接收 SBUF

接收移位寄存器工作过程如下:

  • 接收控制器检测到 RXD 引脚的起始位(方式 1/2/3)或同步时钟(方式 0)后,启动移位;
  • 按照移位时钟(方式 0 是fosc/12,方式 1/2/3 是波特率时钟),将 RXD 引脚的串行数据逐位移入串入并出移位寄存器;
  • 积累满 8 位数据后,硬件自动将移位寄存器中的并行数据并行加载到接收 SBUF(只读寄存器),同时置位 RI(接收中断标志);
  • 软件读取接收 SBUF 中的并行数据。

发送/接收控制器

发送控制器是一个硬件状态机,负责控制发送的时序、生成帧的同步信号(方式 0 的时钟、方式 1/2/3 的起始位 / 停止位)、发送完成后置位 TI。其工作过程如下:

  • 检测到发送 SBUF 被写入后,启动发送过程;
  • 根据工作方式,提供移位时钟给并入串出移位寄存器:
    • 方式 0:直接使用内部机器周期时钟,从 TXD 输出同步时钟;
    • 方式 1/2/3:使用波特率发生器(定时器 1)的时钟;
  • 组装帧结构:
    • 方式 0:仅移位 8 位数据,无起始 / 停止位;
    • 方式 1:自动添加 1 位起始位(0)、1 位停止位(1);
    • 方式 2/3:自动添加 1 位起始位(0)、1 位停止位(1),并将 TB8 作为第 9 位插入;
  • 8 位数据移位完成后,置位 TI(发送中断标志),通知 CPU 发送完成。

接收控制器一个硬件状态机,负责检测 RXD 引脚的帧同步信号(方式 0 的时钟、方式 1/2/3 的起始位)、验证帧的有效性(停止位、SM2+RB8)、接收完成后置位 RI。其工作过程如下:

  • 当 REN=1(接收允许)时,持续检测 RXD 引脚的电平:
    • 方式 0:检测到 TXD 的同步时钟后,启动移位;
    • 方式 1/2/3:检测到起始位(0)后,启动移位;
  • 根据工作方式,提供移位时钟给串入并出移位寄存器:
    • 方式 0:使用内部机器周期时钟;
    • 方式 1/3:使用波特率发生器的时钟;
    • 方式 2:使用fosc/32fosc/64的固定时钟;
  • 验证帧的有效性:
    • 方式 1:验证停止位是否为 1(SM2=1 时);
    • 方式 2/3:验证 SM2+RB8 的组合(决定是否触发 RI);
  • 8 位数据移位完成后,将数据存入接收 SBUF,置位 RI(接收中断标志),通知 CPU 接收完成。

需要注意的是,8051 的发送 / 接收移位寄存器都是固定 8 位的,只负责处理 8 位的有效数据;而串行帧的额外位(起始位、停止位、TB8 位)是直接从硬件逻辑输出到 TXD/RXD 引脚,或者直接从 RXD 引脚检测,不经过移位寄存器(由发送 / 接收控制器单独处理)。

UART的工作方式

8051 MCU 的 UART 有四种工作方式,由 SCON 的 SM0 和 SM1 决定;SM2 在串行口多机通信时使用,非多机通信时,置为 0。

UART的四种工作方式中,方式0为同步移位寄存器输入/输出模式,8位数据为一帧,没有起始位、停止位,TXD输出同步时钟信号实现帧同步(时钟信号由8051的内部硬件逻辑自动产生,不需要软件或定时器配置,时钟频率固定为一个机器周期),RXD输出串行数据(低位在先)。而方式123为异步UART,依靠起始位、停止位实现帧同步,不需要外部时钟,波特率由定时器或晶振决定。

方式0

方式 0 为同步移位寄存器输入/输出方式 。8 位数据为一帧(无起始位和停止位),先发送或接收最低位,其波特率固定为fosc​/12,即每个机器周期发送或接收 1 位数据。引脚 RXD (P3.0) 是数据的输入 / 输出端,引脚 TXD (P3.1) 是同步移位脉冲输出端(输出同步时钟信号),为外围芯片(如 "串入并出" 或 "并入串出" 移位寄存器)提供同步移位信号。该方式实际为 UART 的同步串行通信方式,常用于 I/O 接口的扩展。

**方式0的发送过程:**在 TI=0 情况下,将数据写入发送 SBUF 时,串行口开始发送。数据从 RXD 端串行输出(低位在前),TXD 端输出同步移位脉冲。8 位数据发送完毕由硬件将 TI 置 "1"(表示一个字节数据发送完毕)。在软件清除 TI 后,可发送下一个数据。

**方式0的接收过程:**在 RI=0 条件下,将 REN 置 "1",便启动了串行口的接收。数据从 RXD 端串行输入(低位在前),TXD 端输出同步移位脉冲。当 UART 接收到 8 位数据后存入接收 SBUF,并将 RI 置 "1"(表示接收到一个字节数据)。CPU 读取接收数据后,用软件清除 RI,UART 模块准备接收下一个数据。

若串行口中断允许,则发送完一个字节数据后,置位发送中断标志 TI 并向 MCU 请求中断;在中断程序中,要软件清除 TI,并发送下一个数据。接收到一个字节数据时,置位接收中断标志 RI 并向 MCU 请求中断;在中断程序中,读取接收数据,并软件清除 RI。

方式1~3

方式 1~方式 3 是异步串行通信方式。通过设置 SCON 中的 SM0、SM1,可进行方式选择。方式 1 为 10 位异步通信方式,无校验位(第 8 位);方式 2 和方式 3 是 11 位异步通信方式,两者的波特率设置有所不同。下面以工作方式 2、3 为例,说明 UART 的收发过程。

**发送过程:**在 TI=0 时,向发送 SBUF 写入一个数据即启动了串行口的发送,发送 SBUF 的内容被自动送到内部的并入串出移位寄存器,并在内部发送移位脉冲 (TX-clk) 的控制下,按设定的波特率从 TXD 端依次发送起始位 (=0,硬件自动插入)、SBUF 中的 8 位数据位 (发送次序为先低后高)、1 位校验位或可编程位 (即第 8 位,SCON 的 TB8)、1 位停止位 (=1,硬件自动插入)。发送完毕后,TI 置 1,通知 CPU 可以发送下一字节或请求中断,同时维持 TXD 引脚为高电平状态。

**接收过程:**数据从 RXD 端输入。首先令接收使能 REN=1,UART 开始接收数据。接收步骤:

  • 起始位检测:在内部接收脉冲 (RX-clk) 的控制下,以 16 倍波特率的速率检测 RXD 端的电平,当检测到有效的 "0" 后,即认为检测到起始位。
  • 然后开始接收数据位到串入并出移位寄存器,接收校验位存放到 RB8,再接收停止位。
  • 数据移入、连续接收到一帧 11 位数据后,并满足 RI=0(接收 SBUF 已空,即上次数据已被取走)和接收到的停止位 = 1,则将移位寄存器中的数据送入接收 SBUF,中断标志 RI 置 1。否则,所有接收信息将丢失。

发送时,数据移位脉冲 (TX-clk) 的频率即为波特率。发送的每位信息在 TXD 端上保持的时间为波特率对应的时间。如波特率 = 9600bps,则每个 bit 数据的持续时间是 1000/9600≈104μs。

接收时数据的采样与确定方法:以 16 倍波特率的速率 (RX-clk) 检测 RXD 端的电平,即 1 位数据要检测 16 次,并取中间三次(第 7、8、9 次)的检测结果,把其中两次相同的电平确定为有效的数据电平(即按少数服从多数的规则确定出该 bit 的电平)。

UART的波特率

8051 MCU 只有 T0、T1 两个定时器,当选择 UART 工作于方式 1 或方式 3 时,默认定时器 T1 作为波特率发生器。对于不同型号的 MCU,用作波特率发生器的定时器 / 计数器有相应的说明。

定时器 T1 作波特率发生器时,选择为定时模式、工作方式 2(8 位初值重装载方式),禁止中断。设定时初值为X,则 T1 的定时时间即溢出周期T为(设 MCU 的晶振频率为fosc​):

8051 MCU 常用的波特率有 1200、2400、4800、9600、19200、38400、115200 等。T1 定时初值X与波特率的关系列于下表。

常用波特率 fosc​/MHz SMOD 定时初值X
115200 11.0592 1 FFH
38400 11.0592 1 FEH
19200 11.0592 1 FDH
9600 11.0592 0 FDH
4800 11.0592 0 FAH
2400 11.0592 0 F4H
1200 11.0592 0 E8H

假设 8051 MCU 的振荡频率fosc​为 11.0592MHz,定时器 T1 作波特率发生器,采用工作方式 2,波特率为 2400,则T1 的定时初值经过上面的计算可以得到X=244=F4H,即分别向TH1、TL1写入F4H。

如果晶振频率为 12MHz,上述的计算结果为 242.979≈243=F3H。由于不是整数,用 F3H 初值定时时,产生的波特率是 2404,与 2400 的误差为 0.11%。当两个微控制器的波特率误差超过 ±2.5% 时,就会引起通信错误。所以对于需要通信的微机系统,通常采用 11.0592MHz、22.1184MHz 等频率的晶振

UART的应用

UART 的应用通常包括:利用方式 0 扩展并行 I/O 接口、运用方式 1~方式 3 进行点对点双机通信,以及利用 RS485 驱动芯片将 UART 转为 RS485 总线后进行多机通信。

利用方式0扩展I/O口

利用串行口的方式 0,结合外围移位寄存器可以扩展并行的输入输出接口。如利用并入串出移位寄存器 74HC165,可以扩展输入接口。利用串入并出移位寄存器 74HC164,可以扩展输出接口。

74HC164 是串入并出移位寄存器(也可选用其他相同功能的器件,功能和串行口的接收移位寄存器相同),Q0~Q7 为并行输出端 ,A、B 为串行输入端 ,/CLR为清除 / 移位控制端 ,CLK 为移位脉冲输入端。8051 MCU 利用 2 个 74HC164 扩展 16 位输出接口的电路如图 7-5 所示。MCU 的 RXD 连接串行数据输入端 A、B,TXD 输出移位脉冲到 CLK,P1.0 连接到/CLR。

74HC164的串行输入数据 = A AND B,也就是说,只有当 A 和 B 的电平一致时,才能输入有效的串行数据,这是为了实现输入使能功能,74HC164 把与门集成在内部,通过两个输入引脚实现使能:A 接串行数据,B 接使能信号,当 B=1 时接收数据,B=0 时禁止接收;不过一般我们用不到使能信号直接将AB接到一起即可。

上图还实现了74HC164的级联,74HC164 是 8 位串入并出移位寄存器,单颗只能扩展 8 位并行输出;通过级联多颗 74HC164,可以扩展并行输出的位数(比如 2 颗扩展 16 位、3 颗扩展 24 位),用来控制更多的外设(比如 16 位 LED 阵列、16 位数码管等)。级联过程如下,以发送数据是0x1234(二进制0001 0010 0011 0100)为例(74HC164(1)用U1表示,74HC164(2)用U2表示):

  • 第 1~8 个时钟脉冲(低 8 位数据0x34
    • 8051 的 RXD 输出低 8 位数据0011 0100,逐位移入 U1;
    • 第 1 个时钟:RXD输出0(第 1 位)到U1 Q7位
    • 第 2 个时钟:RXD输出0(第 2 位)到U1 Q7,Q7原来位右移到Q6
    • 以此类推
    • 第 8 个时钟:RXD输出0(第 8 位)到U1 Q7,Q7原来位右移到Q6,Q1原来的位0移入Q0。同时 U1 的 Q0~Q7 输出完整的低 8 位0011 0100
  • 第 9~16 个时钟脉冲(高 8 位数据0x12
    • 8051 的 RXD 输出低 8 位数据0001 0010,逐位移入 U1;
    • 第 1 个时钟:RXD输出0(第 1 位)到U1 Q7位,Q7原来的位右移到Q6位,Q1位原来的位右移到Q0,此时移入Q0原来的位通过接线右移到U2的Q7
    • 以此类推
    • 第 16 个时钟:RXD输出0(0x12最高位)到U1 Q7位,Q7原来的位右移到Q6位,Q1位原来的位右移到Q0,此时移入Q0原来的位通过接线右移到U2的Q7。
    • 此时 U1 的 Q0~Q7 输出高 8 位0001 0010,U2 的 Q0~Q7 输出低 8 位0011 0100,合起来是 16 位数据0001 0010 0011 01000x1234)。

利用串行口进行双机通信

对于甲、乙两个系统的双机异步通信,其信号连接方式为:甲机的 TXD 与乙机的 RXD 相连,甲机的 RXD 与乙机的 TXD 相连,地线与地线相连。

利用串行口进行多机通信

RS232

UART 作为 8051 MCU 的异步串行通信口,可用于微机系统之间的双机通信。但在某些应用场合下,微机系统需要与 PC 机或具有 RS-232C 标准接口的设备进行通信,此时可运用电平转换电路将 UART 转换为 RS-232C 通信标准电平。
区分通信协议、通信标准和UART: 一个串行通信可分为三层,第一层为硬件层 ,也就是UART,它是硬件模块,是实现串行通信的 "物理硬件",它本身不是协议,是实现协议的硬件,而我们前面讲的通信过程只是通过UART实现的异步串行协议;第二层时是物理标准层 ,RS232 是物理层的标准,规定了电气特性(逻辑 1/0 的电平范围)、接口的引脚定义(比如 DB9 的 9 个引脚);第三层是通信协议,通信协议是指通信双方的 "数据交互规则",比如波特率(比如 9600bps)、数据位长度(比如 8 位)、停止位长度(比如 1 位)、校验位(比如无校验、偶校验)等,除此之外,I2C、SPI均为完整的通信协议。

RS232,全称EIA RS-232-C(Electronic Industry Association Recommended Standard)是一种串行通信的电气标准,核心作用是规定异步串行协议通信的 "物理层细节"(电平、引脚):

  1. 电平标准 :定义了逻辑 1 和逻辑 0 对应的电压范围;RS232 采用负逻辑电平,和 8051 的 TTL 电平完全不同,逻辑 1(高电平)为-3V ~ -15V,逻辑 0(低电平):+3V ~ +15V
  2. 引脚定义:规定了通信接口的引脚数量、功能(比如 DB9 接口的 9 个引脚);

8051 的 UART 输出的是 TTL 电平,和 RS232 的负逻辑电平不兼容,所以需要通过MAX232(最常用的 RS232 电平转换芯片,如下图所示)来实现 TTL 和 RS232 电平的转换(MAX232 的 TTL 侧:接 8051 的 TXD/RXD 引脚;MAX232 的 RS232 侧:接 RS232 设备(比如 PC 的串口)):

最常用的RS232通信系统是3线制和5线制。3线制通信系统没有使用硬件握手信号,若一方发起通信时,另一方没有准备就绪,就会造成数据丢失、误传等 错误,一般需要增加软件握手;5线制加入了RTS和CTS握手信号(也可使用DSR和DTR),在数据传输之前,先向对方发出"请求发送",待 对方返回"准备好接收"后,才开始数据的传送,保证通信可靠性。所以说异步串行协议实现的硬件并不只有UART,UART只是8051MCU实现此协议的硬件

RS485

RS485通信标准适用于多机通信,可用于构建多个微机系统监测网络或智能传感器 网络,如 10-32 个温湿度传感器、监控仪表等。RS485已成为一种简单实用的现场总线,广泛应用于工业测控系统中。与RS-32总线相比,RS485在通信速率、传输距离、多机连接等方面均有很大提高。

RS485 总线采用两条平衡传输线(通常为双绞线),传输的是差分信号,因此具有抗共模干扰能力强、可靠性高等特点。采用 + 5V 电源时,信号定义如下:

当两线之间的差分电压为 - 2500~-200mV 时,定义为逻辑 "0";当差分电压为 + 200~+2500mV 时,定义为逻辑 "1";当差分电压为 - 200~+200mV 时,定义为高阻状态。

RS485 收发器(如下图)是完成 TTL/CMOS 电平与 RS485 差分信号之间转换的集成电路,用以实现RS485 通信协议,让设备能在长距离、多节点的总线网络中稳定通信。

RO连接MCU的RXD;DI 连接MCU的TXD;RE和DE连接MCU的P1.0(可以用其他端口控制); 主机MCU通过控制P1.0进行数据发送和接收的切换(也可以是其他引脚,一个引脚控制发送和接收意味着RS485的发送和接收不能同时进行,所以它是半双工通信总线)。A、B之间的压差决定总线的逻辑电平。

  • RO:驱动器输出端(TTL/CMOS)。2500mV>UA-UB >200mV,R0=1;-2500mV<UA-UB <-200mV,R0=0
  • /RE:输入使能。/RE=0:允许接收。/RE=1:不允许,R0高阻态。
  • DE:输出使能(驱动器输出允许)。DE=1:允许发送;DE=0:不允许;
  • DI: 驱动器输入端。
  • A: 接收器(R)正向输入和驱动器(D)正向输出。
  • B: 接收器(R)反向输入和驱动器(D)反向输出

RS485总线网络:RS485 总线的典型应用是组建工业现场的测控网络,网络结构如图所示。通常在 RS485 总线电缆的始端和末端并接一个 120Ω 左右的终端匹配电阻(为避免 "死区",设计时必须通过终端电阻(匹配阻抗)和偏置电阻(空闲时将总线拉到确定 状态)来防止信号落入 ±200mV 的不确定区域)。RS485 总线网络通常采用一主多从的方式,主机可以为 PC 机或一个微机系统,其余总线上的节点称为从机。主机通过寻址与各从机进行通信,任何时刻只能有一对主从机在通信。

关于多机通信的过程前面已经介绍过了,这里再简要说明一下这个过程:

  1. 主、从机均初始化为方式 2 或方式 3,且 SM2=1,允许多机通信。
  2. 当主机要与某从机通信时,发出该从机的地址(此时 TB8=1)。由于各从机的 SM2=1,所以均能接收到该地址信息,并与本机地址比较。
  3. 对于地址比较相等的从机(表示被寻址),置 SM2=0,以进入接收数据状态;而其余地址比较不符的从机(没有被寻址),继续保持 SM2=1 不变。
  4. 然后主机与被寻址的从机进行数据通信,由于数据信息的 TB8 均为 0,因此只有被寻址的从机(SM2=0)能接收到,而其他从机(SM2=1)均接收不到,直至发来新的地址。由此实现了主从机一对一的通信。
  5. 主从机一次通信结束后,主从机重置 SM2=1,主机可再次寻址并开始新的一次通信。

RS232和RS485对比如下:

相关推荐
anghost1502 小时前
基于MSP430单片机的老人睡眠质量监测系统设计
单片机·嵌入式硬件
一杯原谅绿茶2 小时前
单片机的软件串口通信
单片机·嵌入式硬件
d111111111d2 小时前
在STM32中,中断服务函数的命名有什么要求?
笔记·stm32·单片机·嵌入式硬件·学习·c#
易水寒陈2 小时前
MultiTimer源码分析
stm32·单片机
白羽陌3 小时前
STM32入门教程
stm32·单片机·嵌入式硬件
高工智能汽车3 小时前
车规MCU,开启“巨变”
单片机·嵌入式硬件
TEL136997627504 小时前
PTCB818A说明书 配套PL27A1芯片MCU参数说明
网络·单片机·嵌入式硬件
客家元器件4 小时前
LPDDR5选型参数
嵌入式硬件
✎ ﹏梦醒͜ღ҉繁华落℘4 小时前
实际项目开发单片机—Flash错误
单片机