串口理论
046.6.2 串口理论
一、串口理论
串口是一种让设备按照约定规则逐位交换数据的通信方式。电脑可以通过串口向单片机发送控制命令,单片机也可以向电脑回传状态、传感器数据和字符串;STC单片机下载程序时,下载工具同样会通过串口与芯片内部的引导程序通信。
理解串口需要把三个层次分开:
| 层次 | 解决的问题 | 本节对应内容 |
|---|---|---|
| 数据内容 | 要传什么 | 字节、字符、二进制数据 |
| UART帧格式 | 怎样划分每一帧 | 起始位、数据位、可选校验位、停止位、波特率 |
| 电气接口 | 用什么电压和线路传输 | TTL电平UART、RS-232、RS-485、USB转TTL |
“UART”规定串行帧和收发方式;“TTL、RS-232、RS-485”主要描述电气层。它们不是同一个维度,不能把UART和TTL当成完全相同的概念。
1.1 串口介绍
串口通信的核心是:发送方按照固定时间间隔改变信号线的逻辑电平,接收方按照相同速率和帧格式采样这些电平,从而还原出数据。
要发送的字节
│
▼
UART添加起始位、停止位等帧信息
│
▼
TX引脚随时间输出高、低电平
│
▼
接收方RX按约定时刻采样并还原字节
1.1.1 什么是时序
“时序”由“时间”和“顺序”共同构成。只知道某一瞬间是高电平还是低电平不够,还必须知道每个电平维持多久、从什么时刻开始采样、各位按什么顺序出现。UART用波特率确定每一位的持续时间,用起始位帮助接收器找到一帧的开头,用停止位确认一帧结束。
例如,波特率为9600时,一个位的时间为:
$ T_{bit}=\frac{1}{9600}\ \text{s}\approx104.167\ \mu\text{s} $
接收方若也按约104.167微秒一个位的节奏采样,就能把连续电压波形切分成一个个逻辑位。
1.1.1.1 单片机芯片发出来的信号是TTL电平的串口信号
单片机的UART引脚输出的是逻辑电平串口信号,工程中经常称为“TTL串口”。以本开发板的5V STC89C52为例,低电平接近0V,高电平接近5V;若换成3.3V的STM32,高电平通常接近3.3V。高、低电平是一个允许范围,不要求测量值恰好等于0.000V或5.000V,具体输入门限应查芯片数据手册。
| 逻辑状态 | 发送端典型电压 | UART线路含义 |
|---|---|---|
| 逻辑0 | 接近GND | 起始位以及值为0的数据位 |
| 逻辑1 | 接近VCC | 空闲状态、停止位以及值为1的数据位 |
两个TTL串口设备通信时,除TX和RX外还必须连接GND。电压是相对于地测量的,没有共同参考地,接收方无法可靠判断高、低电平。
设备A TX ─────────→ 设备B RX
设备A RX ←───────── 设备B TX
设备A GND ───────── 设备B GND
还要检查电压兼容性。5V输出直接接入只允许3.3V的输入端可能损坏芯片;3.3V输出能否被5V器件识别为高电平,也要看接收端门限,不能只看接口名称都叫“TTL”。
1.1.1.2 串口通信: 通过发送不同排列组合的高低电平
UART通过高、低电平随时间形成的排列组合传递二进制数据。8个二进制位组成1个字节,但一帧UART数据除了有效数据位,还包含起始位和停止位。
数字4作为一个数值字节时是0x04,按通常书写顺序D7...D0表示为:
位权:D7 D6 D5 D4 D3 D2 D1 D0
数值: 0 0 0 0 0 1 0 0 = 0x04
51单片机串口模式1采用低位先发,即在线路上依次发送D0、D1...D7。所以0x04的实际数据位顺序是:
发送顺序:D0 D1 D2 D3 D4 D5 D6 D7
线路数据: 0 0 1 0 0 0 0 0
完整8N1帧:空闲1 │ 起始0 │ 0 0 1 0 0 0 0 0 │ 停止1 │ 空闲1
“十进制数4”和“字符'4'”也不是同一个字节:
| 内容 | 字节值 | 按D7...D0书写 | UART线上D0...D7顺序 |
|---|---|---|---|
| 数值4 | 0x04 | 00000100 | 00100000 |
ASCII字符'4' | 0x34 | 00110100 | 00101100 |
因此串口助手选择HEX发送还是ASCII发送,会直接改变线路上的字节内容。
1.1.1.3 通信的时序: 不同的高低电平
通信时序不是随意输出一串0和1,而是按协议规定的时间、顺序和边界产生波形。UART接收器要完成三个动作:
- 在线路空闲为高电平时,检测到
1→0跳变,认为可能出现起始位。 - 按波特率产生采样时刻,在各数据位中部附近判断电平,依次还原
D0~D7。 - 检查停止位是否为高电平;若停止位不正确,可能产生帧错误。
视频、音频、文字和程序在数字系统中最终都可编码为二进制数据,但不同系统承载0和1的物理方式并不完全相同:UART使用单端电平时序,USB使用差分信号和复杂编码,硬盘则使用磁性或电荷状态。共同点是接收方都必须依据相应规则解释物理信号。
1.1.2 UART介绍
UART是Universal Asynchronous Receiver/Transmitter的缩写,即通用异步收发器。它是单片机内部完成串并转换、帧生成、采样和状态标记的硬件模块。
1.1.2.1 UART的基本概念
UART具有以下特征:
- 串行:一根发送线上按时间先后逐位发送数据。
- 异步:通信双方没有额外共享的时钟线,各自依靠本地时钟和约定波特率工作。
- 双向:通常具有独立的
TX和RX数据线。 - 全双工:TX和RX硬件彼此独立时,可以同时发送和接收。
最简全双工UART需要两根数据线和一根公共地线:
设备A UART 设备B UART
TX ─────────────────────────────────→ RX
RX ←───────────────────────────────── TX
GND ────────────────────────────────── GND
发送方向和接收方向可以同时工作
如果还启用RTS/CTS硬件流控,就会增加控制线;所以“UART只需要两根线”是针对不使用硬件流控的数据线数量而言,实际连接仍不能漏掉GND。
1.1.2.2 UART的通信方式
本实验使用的参数通常写成9600 8N1:
| 参数 | 取值 | 含义 |
|---|---|---|
| 波特率 | 9600 | 每秒9600个码元;二进制UART中数值等于9600 bit/s |
| 数据位 | 8 | 每帧传送8位有效数据 |
| 校验 | N / None | 不添加奇偶校验位 |
| 停止位 | 1 | 每帧末尾保持1个位时间的逻辑1 |
| 流控制 | None | 不使用RTS/CTS流控 |
COM端口号不是UART协议参数,只是操作系统为某个串口设备分配的本地名称。不同电脑、不同USB插口得到的编号可能不同。
全双工表示两个方向可同时传输,并不表示双方的参数可以不同。要可靠通信,发送方和接收方仍应使用相同波特率、数据位、校验方式和停止位。
1.1.2.3 UART的帧数据组成
常见UART帧由起始位、数据位、可选奇偶校验位和停止位组成:
线路空闲
1 ─────┐
└─ 起始位0 ─ D0 ─ D1 ─ D2 ─ D3 ─ D4 ─ D5 ─ D6 ─ D7 ─ [校验] ─ 停止位1 ── 1
有效数据,通常低位先发 可选
- 起始位:固定为逻辑0,使接收器从空闲高电平中识别一帧开始。它不是电话式“建立连接”,而是每一帧都要出现的同步标志。
- 数据位:真正承载字节内容。
- 奇偶校验位:可选的单比特错误检测信息。
- 停止位:固定为逻辑1,为本帧提供结束边界并让线路回到空闲电平。
奇偶校验位不是CRC。CRC通常包含多个比特并使用多项式计算,检错能力远强于一个奇偶校验位;二者不能混用名称。
对本开发板的STC89C52串口模式1而言,一帧固定为1位起始位、8位数据、1位停止位,没有由硬件自动插入的普通奇偶校验位,因此正好是10个位时间。
1.1.2.4 UART的数据位
通用PC串口控制器常允许选择5、6、7或8个数据位,但具体单片机支持哪些长度取决于UART硬件。STC89C52的模式1是固定8位UART;不能因为串口助手能选择5~8位,就认为单片机模式1也能任意选择。
以0xAC为例:
通常书写:D7 D6 D5 D4 D3 D2 D1 D0 = 1 0 1 0 1 1 0 0
UART发送:D0 D1 D2 D3 D4 D5 D6 D7 = 0 0 1 1 0 1 0 1
8N1线路:空闲1 │ 起始0 │ 0 0 1 1 0 1 0 1 │ 停止1 │ 空闲1
这里讨论的是UART帧内的位发送顺序,不是CPU存储多字节数据时所说的“大端序/小端序”。端序描述多个字节在内存中的排列;UART低位先发描述一个字节内部各位出现在串行线上的先后。
0xFF的8个数据位全是1,因此无论从哪一端书写都显示为11111111;这类数据不适合用来判断是否理解了低位先发。0x04、0xAC等不对称位型更适合练习。
1.1.2.5 UART的校验位
奇偶校验通过增加1个校验位,使一帧中逻辑1的总数满足约定:
| 校验方式 | 规则 | 0xAC含4个1时的校验位 |
|---|---|---|
| 偶校验 | 数据位与校验位中1的总数为偶数 | 0,总数仍为4 |
| 奇校验 | 数据位与校验位中1的总数为奇数 | 1,总数变为5 |
| 无校验 | 不发送校验位 | 无 |
奇偶校验只能发现一部分错误:奇数个位发生翻转时通常能检出,偶数个位同时翻转时可能漏检,而且它不能指出哪一位错了,也不能自动纠错。需要更强可靠性时,应在上层协议增加校验和或CRC、序号、确认和重传机制。
本实验选择None,所以使用8N1而不是带奇偶校验的8E1或8O1。
1.1.2.6 UART的停止位与空闲位
TTL电平UART在线路空闲时保持逻辑1。发送方先把线路拉低一个位时间形成起始位,发送数据后再输出逻辑1作为停止位。
上一帧数据 ── 停止位1 ── 空闲1……1 ── 起始位0 ── 下一帧数据
停止位和空闲状态电平相同,但含义不同:
- 停止位是帧格式的一部分,必须至少维持约定的位时间。
- 空闲状态是两帧之间没有数据时持续保持的状态,长度可以很长。
- 连续发送时,可以在一个停止位后立刻开始下一帧,不要求额外插入空闲位。
一些通用串口控制器允许选择1、1.5或2个停止位时间,其中1.5停止位通常只与特定数据长度组合使用;具体组合要看控制器手册。STC89C52的UART模式1固定使用1个停止位,因此本实验选择1停止位。
如果接收器应当采到停止位的位置仍是低电平,就可能报告帧错误。线路被持续拉低超过一帧时间通常称为Break状态,也不是正常数据0。
1.1.2.7 UART通信设置
收发双方必须匹配的设置如下:
| 设置项 | 不匹配时的常见现象 |
|---|---|
| 波特率 | 采样位置逐渐偏离,出现乱码、丢字节或完全收不到 |
| 数据位 | 字节边界和有效位解释不一致 |
| 奇偶校验 | 产生校验错误,或把校验位误当成其他内容 |
| 停止位 | 可能产生帧错误 |
| 电平标准 | 不能识别,严重时可能损坏接口 |
| TX/RX方向与GND | 无数据、单向通信或信号不稳定 |
51单片机教学实验常用9600,许多STM32工程和通信模块常用115200,但这只是常见选择,不是芯片类别强制规定的值。具体波特率应由通信双方能力、时钟误差、数据量、线路长度和噪声环境共同决定。
把串口助手改成与单片机不同的波特率后出现乱码,是因为接收器在错误时刻采样,而不是字符编码突然改变。恢复与单片机一致的9600后,接收器才能重新正确划分各个位。
1.1.2.8 波特率的概念
严格来说,波特率baud表示每秒传输多少个码元,单位是Bd;比特率bit/s表示每秒传输多少位。二进制UART的每个码元只有高、低两种状态,每个码元携带1bit,所以波特率和比特率在数值上相等:9600Bd对应9600bit/s。
常用波特率包括9600、19200、38400、57600和115200等。对8N1而言,一个有效字节需要1个起始位、8个数据位和1个停止位,共10个位时间:
$ \text{有效字节率}_{max}=\frac{baud}{10} $
| 波特率 | 单个位时间 | 8N1单帧时间 | 理论最大有效字节率 |
|---|---|---|---|
| 9600 | 104.167μs | 1.04167ms | 960byte/s |
| 115200 | 8.681μs | 86.806μs | 11520byte/s |
这里的“最大”假定连续发送且没有额外协议开销。实际应用还可能包含帧间隔、命令头、校验、应答和重传,因此有效业务数据率会更低。9600相对现代高速接口很慢,但对按键命令、调试日志和低速传感器仍可能完全够用。
1.1.2.9 实验演示&硬件接线
用示波器观察TTL UART时,应把探头尖端接发送端TXD,探头地夹接电路GND。不能只接探头尖端,也不能把示波器地夹随意接到带危险电压的节点。
单片机P3.1/TXD ───────── 示波器探头尖端
单片机GND ───────── 示波器地夹
示波器波形的纵轴是电压,横轴是时间。分析步骤如下:
- 先确认空闲段为高电平。
- 找到第一个
高→低跳变,它是起始位开始。 - 根据波特率计算一个位宽,例如9600波特约为104.167μs。
- 从起始位之后按等间隔读取
D0~D7。 - 确认最后的停止位回到高电平。
例如发送数值0x01时,8N1波形应为:
位名称:空闲 │ START │ D0 │ D1 │ D2 │ D3 │ D4 │ D5 │ D6 │ D7 │ STOP │ 空闲
逻辑值: 1 │ 0 │ 1 │ 0 │ 0 │ 0 │ 0 │ 0 │ 0 │ 0 │ 1 │ 1
这也说明示波器上从左到右看到的是低位先发后的顺序,不能直接照抄二进制数通常从D7到D0的书写顺序。
开发板与电脑之间还存在一层USB转换:
STC89C52 P3.1/TXD ─→ CH340N RXD ─→ USB D+/D- ─→ 电脑
STC89C52 P3.0/RXD ←─ CH340N TXD ←─ USB D+/D- ←─ 电脑
STC89C52 GND ──────────────── 公共参考地
示波器若要观察本节所讲的UART高低电平,应测量CH340与单片机之间的TXD/RXD侧;USB的D+、D-是差分信号,协议和波形完全不同,不能用同一套8N1方法直接逐位解释。
1.1.2.10 串口通信的深入理解
STC89C52的UART内部可以按发送通路和接收通路拆解:
发送通路
CPU内部总线 → 写SBUF → 发送移位寄存器 → 加入START/STOP → P3.1/TXD
▲
定时器1溢出 → 分频 → TX时钟
│
发送完成置TI
接收通路
P3.0/RXD → 起始跳变检测 → 按RX时钟采样 → 接收移位寄存器 → 接收SBUF → CPU读取
▲ │
定时器1溢出 → 分频 接收完成置RI
发送时,CPU向SBUF写入一个字节,硬件把数据装入移位寄存器,并自动按起始位→D0…D7→停止位送到TXD。最后一个停止位开始发送时,硬件置位TI通知软件发送完成。
接收时,UART在RXD上检测空闲高电平到起始低电平的跳变,再用本地接收时钟对每个位多次采样。STC89C52模式1使用16倍采样节拍,并在位中心附近判决电平,有助于避开跳变边沿。收满一帧后,数据进入接收SBUF并置位RI。
发送方不会把自己的时钟线传给接收方,所以两端波特率不可能绝对相同,只能保持在允许误差内。起始位让接收器每帧重新对齐,位中心采样提供一定误差余量;但误差过大时,采样点仍会逐位漂移,最终造成数据或停止位判断错误。
1.1.3 串口分类方式
通信方式可以从多个互相独立的维度分类:电气标准可分TTL、RS-232、RS-485;数据组织可分串行、并行;时钟关系可分同步、异步;方向能力可分全双工、半双工、单工。一个接口可以同时拥有多项属性,例如普通TTL UART是“单端电平、串行、异步、全双工”。
1.1.3.1 串口通信原理与TTL介绍
TTL电平UART通常用于同一块电路板、开发板与近距离模块之间的调试连接。TX是Transmit,表示本设备发送端;RX是Receive,表示本设备接收端,因此两台设备要交叉连接。
它使用相对于GND的单端信号,没有独立的时钟线:
逻辑高:TX相对GND接近VCC
逻辑低:TX相对GND接近0V
发送端TX ───────── 接收端RX
公共GND ────────── 公共GND
单端信号把GND当作基准,地电位差、外界干扰、线缆电容和信号反射都会影响可靠性,所以TTL UART更适合板级或短距离连接。可用距离没有一个对所有波特率、线材和环境都成立的固定“10米”上限;速率越高、线越长、环境越嘈杂,可靠性通常越差。
1.1.3.2 TTL的逻辑电平与USB转TTL模块
USB转TTL模块把电脑的USB协议与单片机的逻辑电平UART相互转换。以开发板上的CH340N为例:
电脑USB差分侧 单片机TTL UART侧
USB D+、D- ⇄ CH340N协议转换 ⇄ TXD/RXD ⇄ P3.0、P3.1
电脑USB地 ─────────────────── GND ───── 单片机GND
板载转换电路中的主要器件作用如下:
| 器件或网络 | 作用 |
|---|---|
CH340N | 完成USB设备枚举、USB数据与TTL UART数据转换 |
C5 100nF | 为CH340内部电源节点去耦,抑制高频电压波动 |
R1 300Ω | 串联在UART线路上,限制瞬态或冲突电流 |
D2 1N4148 | 对有关接收/下载控制信号进行单向隔离 |
RTS#、C7、R2、Q2 | 构成自动下载辅助控制网络 |
外接USB转TTL模块时一般连接:模块TXD→单片机RXD、模块RXD←单片机TXD、GND→GND。若开发板已经单独供电,通常不再接模块VCC,避免两个电源互相反灌。
“TTL”也不表示模块一定输出5V。有些USB转TTL模块输出3.3V,有些输出5V,还有些由跳帽选择。连接前应确认模块IO电平和目标芯片的耐压;VCC引脚标注的供电电压也不一定等于TXD输出高电平,必须看模块说明。
1.1.3.3 TTL的缺点与RS-232、RS-485的优势
TTL、RS-232和RS-485不能只用“谁更快”排序。传输距离和最高速率互相制约,还会受到线缆、终端匹配、收发器和电磁环境影响。
| 特性 | TTL电平UART | RS-232 | RS-485 |
|---|---|---|---|
| 信号方式 | 相对GND的单端逻辑电平 | 正负电压的单端信号,逻辑极性与TTL侧不同 | A/B两线电压差形成差分信号 |
| 典型拓扑 | 点对点 | 点对点 | 一条总线可挂多个节点 |
| 常见方向 | 独立TX/RX,全双工 | 独立TX/RX,全双工 | 两线制常见半双工,四线制可全双工 |
| 抗共模干扰 | 较弱 | 好于板级TTL,但仍是单端 | 较强,适合工业现场和长线 |
| 常见用途 | 板内、模块调试、短线 | 电脑和仪器的传统串口 | 工业总线、远距离多节点通信 |
RS-232在较低速率和合适线缆下可能工作到几十米,但不能把“30米”当成任何速率下都保证的固定结论;它还需要MAX232一类电平转换器,不能直接接入单片机TTL引脚。
RS-485的差分接收器关注A-B之间的电压差,共模干扰同时耦合到两根线上时更容易被抵消,因此更适合长距离。长总线通常还需要双绞线、两端终端电阻、合理偏置和正确拓扑,并不是仅换一个模块就一定稳定。
1.1.3.4 串口与并口的区别
串行传输在少量数据线上按时间先后逐位传输;并行传输使用多根数据线在同一时刻传输多位。
串行传输:
发送方 ──0──1──1──0──0──0──1──0──→ 接收方
同一根数据线依次传8位
并行传输:
发送方 D7 ───────── 0 ─────────→ 接收方
D6 ───────── 1 ─────────→
D5 ───────── 1 ─────────→
D4 ───────── 0 ─────────→
D3 ───────── 0 ─────────→
D2 ───────── 0 ─────────→
D1 ───────── 1 ─────────→
D0 ───────── 0 ─────────→
多根线在同一时刻传8位
| 对比项 | 串行 | 并行 |
|---|---|---|
| 数据线数量 | 少 | 多 |
| 连接器与布线 | 简单 | 占引脚、线缆宽 |
| 长距离高速难点 | 信号衰减和时钟恢复 | 各数据线到达时间不一致,即时序偏斜 |
| 常见示例 | UART、USB、CAN、SPI | 存储器总线、早期打印机口、并行显示接口 |
并行并不天然永远比串行快。现代高速串行接口可以用很高的码元速率和多条串行通道获得高吞吐量,同时避免宽并行总线严重的线间偏斜问题。
1.1.3.5 同步异步、全双工、半双工、单工
这些概念分别描述时钟关系和通信方向:
| 分类 | 含义 | 例子 |
|---|---|---|
| 同步 | 通常有共享时钟或从信号中持续恢复时钟,数据按时钟边沿传输 | SPI、I²C |
| 异步 | 没有逐位共享时钟,双方预先约定速率并用帧边界重新同步 | 普通UART |
| 全双工 | 两个方向可以同时传输 | 独立TX/RX的UART、电话 |
| 半双工 | 两个方向都能传,但同一时刻只能一个方向发送 | 两线RS-485、对讲机 |
| 单工 | 数据方向固定,只能从发送方到接收方 | 广播发送链路 |
全双工:A ─────→ B
A ←───── B 两个方向可同时
半双工:A ─────→ B 此时A发B收
A ←───── B 换方向后B发A收
单工: A ─────→ B 方向固定
串行/并行、同步/异步、全双工/半双工/单工是不同维度。例如SPI通常是同步串行接口;UART通常是异步串行接口;两线RS-485上承载的UART数据通常表现为异步串行半双工。
1.1.4 总结
学习UART时应先掌握以下主线:
- 串口通信用随时间变化的物理信号承载0和1,时序同时包含电平、持续时间和先后顺序。
- TTL电平UART的空闲和停止位为高电平,起始位为低电平,模式1的8个数据位按
D0→D7低位先发。 9600 8N1表示9600波特、8个数据位、无校验、1个停止位;8N1传1个字节需要10个位时间。- 收发双方必须匹配波特率和帧格式,并正确交叉连接TX/RX、连接公共GND、确认IO电压兼容。
- USB、TTL UART、RS-232和RS-485属于不同协议或电气层,不能直接互接,必须使用相应转换器件。
- UART、I²C、SPI和1-Wire等数字通信接口都有各自的时序规则;看懂时序图和示波器波形,是从“会调用接口”走向“能定位通信故障”的关键。
51单片机适合用来建立UART帧、波特率和寄存器的基础认识;进入STM32阶段后,还会接触USART、DMA、空闲中断、RS-485方向控制等内容。无论平台如何变化,先确认电气层,再确认帧格式,最后确认软件收发流程,始终是排查通信问题的有效顺序。