20_串口通信基础与USART流程

串口通信基础与 USART 收发流程

对应课程:9-1 USART 串口协议的理论部分

课堂录音:2026-09-07 10:02《记录 串口通讯》

芯片:STM32F103C8T6

开发方式:标准外设库

整理日期:2026-09-09

资料补全:老师 PPT、师兄笔记、《STM32F10xxx参考手册(中文)》《STM32F103x8B数据手册(中文)》

本节边界:本节重点是串口协议和 STM32 USART 硬件原理;发送、接收、重定向 printf 的逐行代码在下一小节正式讲解。

1. 老师的整条思路

老师先演示"STM32 向电脑发送"和"电脑发给 STM32 后回传"两个程序,让我们看到串口能传十六进制字节,也能把字节按字符编码显示。随后从通信的目的和协议出发,比较通信接口特征,再逐步讲串口接线、电平标准、数据帧、实测波形,最后进入 STM32 USART 的发送器、接收器、标志位、16 倍采样和波特率发生器。
#mermaid-svg-tISj1OsqTv5dRS6a{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-tISj1OsqTv5dRS6a .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-tISj1OsqTv5dRS6a .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-tISj1OsqTv5dRS6a .error-icon{fill:#552222;}#mermaid-svg-tISj1OsqTv5dRS6a .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-tISj1OsqTv5dRS6a .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-tISj1OsqTv5dRS6a .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-tISj1OsqTv5dRS6a .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-tISj1OsqTv5dRS6a .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-tISj1OsqTv5dRS6a .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-tISj1OsqTv5dRS6a .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-tISj1OsqTv5dRS6a .marker{fill:#333333;stroke:#333333;}#mermaid-svg-tISj1OsqTv5dRS6a .marker.cross{stroke:#333333;}#mermaid-svg-tISj1OsqTv5dRS6a svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-tISj1OsqTv5dRS6a p{margin:0;}#mermaid-svg-tISj1OsqTv5dRS6a .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-tISj1OsqTv5dRS6a .cluster-label text{fill:#333;}#mermaid-svg-tISj1OsqTv5dRS6a .cluster-label span{color:#333;}#mermaid-svg-tISj1OsqTv5dRS6a .cluster-label span p{background-color:transparent;}#mermaid-svg-tISj1OsqTv5dRS6a .label text,#mermaid-svg-tISj1OsqTv5dRS6a span{fill:#333;color:#333;}#mermaid-svg-tISj1OsqTv5dRS6a .node rect,#mermaid-svg-tISj1OsqTv5dRS6a .node circle,#mermaid-svg-tISj1OsqTv5dRS6a .node ellipse,#mermaid-svg-tISj1OsqTv5dRS6a .node polygon,#mermaid-svg-tISj1OsqTv5dRS6a .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-tISj1OsqTv5dRS6a .rough-node .label text,#mermaid-svg-tISj1OsqTv5dRS6a .node .label text,#mermaid-svg-tISj1OsqTv5dRS6a .image-shape .label,#mermaid-svg-tISj1OsqTv5dRS6a .icon-shape .label{text-anchor:middle;}#mermaid-svg-tISj1OsqTv5dRS6a .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-tISj1OsqTv5dRS6a .rough-node .label,#mermaid-svg-tISj1OsqTv5dRS6a .node .label,#mermaid-svg-tISj1OsqTv5dRS6a .image-shape .label,#mermaid-svg-tISj1OsqTv5dRS6a .icon-shape .label{text-align:center;}#mermaid-svg-tISj1OsqTv5dRS6a .node.clickable{cursor:pointer;}#mermaid-svg-tISj1OsqTv5dRS6a .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-tISj1OsqTv5dRS6a .arrowheadPath{fill:#333333;}#mermaid-svg-tISj1OsqTv5dRS6a .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-tISj1OsqTv5dRS6a .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-tISj1OsqTv5dRS6a .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-tISj1OsqTv5dRS6a .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-tISj1OsqTv5dRS6a .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-tISj1OsqTv5dRS6a .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-tISj1OsqTv5dRS6a .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-tISj1OsqTv5dRS6a .cluster text{fill:#333;}#mermaid-svg-tISj1OsqTv5dRS6a .cluster span{color:#333;}#mermaid-svg-tISj1OsqTv5dRS6a div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-tISj1OsqTv5dRS6a .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-tISj1OsqTv5dRS6a rect.text{fill:none;stroke-width:0;}#mermaid-svg-tISj1OsqTv5dRS6a .icon-shape,#mermaid-svg-tISj1OsqTv5dRS6a .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-tISj1OsqTv5dRS6a .icon-shape p,#mermaid-svg-tISj1OsqTv5dRS6a .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-tISj1OsqTv5dRS6a .icon-shape .label rect,#mermaid-svg-tISj1OsqTv5dRS6a .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-tISj1OsqTv5dRS6a .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-tISj1OsqTv5dRS6a .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-tISj1OsqTv5dRS6a :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 观察发送和回传现象
通信目的与通信协议
串口硬件接线
TTL RS232 RS485电平
数据帧与波特率
示波器观察真实波形
USART发送器和接收器
TXE TC RXNE和错误标志
16倍采样和BRR计算
为下一节代码建立配置思路

课堂时间线:00:05~03:16 两个程序现象与 HEX/文本显示;03:16~07:38 通信目的、协议和接口特征;07:38~12:38 串口用途、接线和电平;12:38~18:05 数据帧、波特率和奇偶校验;18:05~约 25:00 实测时序;之后讲 USART 框图、发送接收流程、标志位、引脚和基本结构;35:36~42:41 数据帧细节、16 倍采样和 BRR;42:41~47:37 USB 转串口模块与手册索引。

2. 通信的本质

图 1 老师 PPT 第 108 页:通信的目的和通信协议。

通信解决的是"设备 A 如何把信息可靠地交给设备 B"。双方必须同时约定:

  • 电气层:哪根线、什么电压表示 0 和 1;
  • 时序层:每一位持续多久,何时开始和结束;
  • 帧格式:数据位数、先发哪一位、是否校验、停止位长度;
  • 上层含义:收到的字节代表字符、数值、命令还是数据包。

串口线路传输的始终是 0/1 比特。所谓"发送字符 A",实际是发送编码值 0x41;串口助手选择文本模式后把 0x41 映射并显示为 A。HEX 模式和文本模式只改变软件的解释与显示,不改变线路上的比特。

3. 串口属于哪类通信

特性 基础 UART/USART 异步串口
方向 TX 与 RX 分开时为全双工;只接单方向可退化为单工
时钟 异步,没有单独时钟线,双方预先约定波特率
信号 基础 TTL 串口为单端信号,必须共地
拓扑 通常点对点
位序 低位先行 LSB first
空闲电平 高电平
优点 线路少、成本低、便于连接电脑和模块

USART 比 UART 多一个同步模式能力,可输出 CK 时钟;但课程当前使用的是最常见的异步 UART 方式,所以实际只使用 TX、RX 和 GND。

4. 硬件接线:为什么 TX 和 RX 要交叉

图 2 老师 PPT 第 110 页:双向串口交叉连接。

双向通信的基本连接:

设备 A 设备 B 原因
TX RX A 的输出送到 B 的输入
RX TX B 的输出送到 A 的输入
GND GND 两端用同一个 0 V 参考判断高低电平

VCC 不是必需的通信线。只有设备 B 没有独立供电,并且其允许的供电电压与设备 A 提供的电源一致时,才连接 VCC。不要把"通信电平电压"和"模块供电电压"混为一谈。

4.1 单向发送怎样接

STM32 只向电脑发送时,只需:STM32 TX → USB 转串口 RX,再连接 GND。电脑不向 STM32 发数据时,反向线路可不接。

4.2 STM32F103C8T6 默认 USART 引脚

外设 TX RX 所在总线
USART1 PA9 PA10 APB2,通常 PCLK2=72 MHz
USART2 PA2 PA3 APB1,通常 PCLK1=36 MHz
USART3 PB10 PB11 APB1,通常 PCLK1=36 MHz

具体封装与复用/重映射必须查《STM32F103x8B数据手册(中文)》PDF 第 17~20 页,以及参考手册 AFIO 重映射章节。不能把任意 GPIO 当作 USART 引脚。

5. 电平标准:TTL 串口不等于 RS-232

图 3 老师 PPT 第 111 页:TTL、RS-232 与 RS-485 的电气定义不同。

标准 逻辑表达 信号方式 常见场景
TTL/CMOS UART 约 0 V 为 0,约 3.3 V 或 5 V 为 1 单端 MCU、传感器、USB 转串口模块
RS-232 负电压表示 1,正电压表示 0,极性与 TTL 相反 单端 传统电脑和工业设备
RS-485 由 A/B 两线电压差表示 0/1 差分 长距离、多节点、强干扰环境

三者可能承载相似的异步串口帧,但电压和驱动方式不同。STM32 的 USART 引脚不能直接连接真正的 RS-232 电压,也不能直接充当 RS-485 差分收发器;必须使用 MAX232、MAX3485 等匹配的电平/收发器芯片。

安全原则: 本课程 STM32 工作在 3.3 V,应让 USB 转串口模块的 TTL 侧选择 3.3 V 电平。即使某个输入脚在数据手册中标为 5 V tolerant,也不能据此认为整块模块的所有连接和输出状态都安全。

6. 一帧串口数据由什么组成

图 4 老师 PPT 第 112 页:一帧包含起始位、数据位、可选校验位和停止位。

典型的 9600 8N1 表示:

  • 波特率 9600 bit/s;
  • 8 个有效数据位;
  • N:无奇偶校验;
  • 1 个停止位。

它在线路上的顺序是:
#mermaid-svg-Q3KWt7nK7Zm1PnEA{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-Q3KWt7nK7Zm1PnEA .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-Q3KWt7nK7Zm1PnEA .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-Q3KWt7nK7Zm1PnEA .error-icon{fill:#552222;}#mermaid-svg-Q3KWt7nK7Zm1PnEA .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-Q3KWt7nK7Zm1PnEA .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-Q3KWt7nK7Zm1PnEA .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-Q3KWt7nK7Zm1PnEA .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-Q3KWt7nK7Zm1PnEA .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-Q3KWt7nK7Zm1PnEA .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-Q3KWt7nK7Zm1PnEA .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-Q3KWt7nK7Zm1PnEA .marker{fill:#333333;stroke:#333333;}#mermaid-svg-Q3KWt7nK7Zm1PnEA .marker.cross{stroke:#333333;}#mermaid-svg-Q3KWt7nK7Zm1PnEA svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-Q3KWt7nK7Zm1PnEA p{margin:0;}#mermaid-svg-Q3KWt7nK7Zm1PnEA .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-Q3KWt7nK7Zm1PnEA .cluster-label text{fill:#333;}#mermaid-svg-Q3KWt7nK7Zm1PnEA .cluster-label span{color:#333;}#mermaid-svg-Q3KWt7nK7Zm1PnEA .cluster-label span p{background-color:transparent;}#mermaid-svg-Q3KWt7nK7Zm1PnEA .label text,#mermaid-svg-Q3KWt7nK7Zm1PnEA span{fill:#333;color:#333;}#mermaid-svg-Q3KWt7nK7Zm1PnEA .node rect,#mermaid-svg-Q3KWt7nK7Zm1PnEA .node circle,#mermaid-svg-Q3KWt7nK7Zm1PnEA .node ellipse,#mermaid-svg-Q3KWt7nK7Zm1PnEA .node polygon,#mermaid-svg-Q3KWt7nK7Zm1PnEA .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-Q3KWt7nK7Zm1PnEA .rough-node .label text,#mermaid-svg-Q3KWt7nK7Zm1PnEA .node .label text,#mermaid-svg-Q3KWt7nK7Zm1PnEA .image-shape .label,#mermaid-svg-Q3KWt7nK7Zm1PnEA .icon-shape .label{text-anchor:middle;}#mermaid-svg-Q3KWt7nK7Zm1PnEA .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-Q3KWt7nK7Zm1PnEA .rough-node .label,#mermaid-svg-Q3KWt7nK7Zm1PnEA .node .label,#mermaid-svg-Q3KWt7nK7Zm1PnEA .image-shape .label,#mermaid-svg-Q3KWt7nK7Zm1PnEA .icon-shape .label{text-align:center;}#mermaid-svg-Q3KWt7nK7Zm1PnEA .node.clickable{cursor:pointer;}#mermaid-svg-Q3KWt7nK7Zm1PnEA .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-Q3KWt7nK7Zm1PnEA .arrowheadPath{fill:#333333;}#mermaid-svg-Q3KWt7nK7Zm1PnEA .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-Q3KWt7nK7Zm1PnEA .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-Q3KWt7nK7Zm1PnEA .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-Q3KWt7nK7Zm1PnEA .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-Q3KWt7nK7Zm1PnEA .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-Q3KWt7nK7Zm1PnEA .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-Q3KWt7nK7Zm1PnEA .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-Q3KWt7nK7Zm1PnEA .cluster text{fill:#333;}#mermaid-svg-Q3KWt7nK7Zm1PnEA .cluster span{color:#333;}#mermaid-svg-Q3KWt7nK7Zm1PnEA div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-Q3KWt7nK7Zm1PnEA .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-Q3KWt7nK7Zm1PnEA rect.text{fill:none;stroke-width:0;}#mermaid-svg-Q3KWt7nK7Zm1PnEA .icon-shape,#mermaid-svg-Q3KWt7nK7Zm1PnEA .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-Q3KWt7nK7Zm1PnEA .icon-shape p,#mermaid-svg-Q3KWt7nK7Zm1PnEA .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-Q3KWt7nK7Zm1PnEA .icon-shape .label rect,#mermaid-svg-Q3KWt7nK7Zm1PnEA .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-Q3KWt7nK7Zm1PnEA .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-Q3KWt7nK7Zm1PnEA .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-Q3KWt7nK7Zm1PnEA :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 空闲 高电平
起始位 低电平
D0最低位
D1到D6
D7最高位
可选奇偶校验位
停止位 高电平
继续空闲或下一帧

6.1 起始位为什么固定为 0

总线空闲时保持 1。起始位拉低,产生清晰的下降沿,接收器据此知道新帧到来并对齐内部采样节奏。没有起始位,一串连续的 1 无法区分"空闲"还是"正在发送数据"。

6.2 为什么低位先行

USART 硬件规定先发送 D0,再发送 D1......最后发送最高位。程序写入的是完整字节,硬件移位寄存器自动完成位序转换,无需软件手动倒序。

6.3 停止位为什么固定为 1

停止位把线路恢复到空闲高电平,同时给下一帧的起始下降沿创造条件。接收器若在预期停止位处没有采到高电平,会置位帧错误 FE

7. 用 0x55 看懂真实波形

图 5 老师 PPT 第 113 页:不同数据、波特率、停止位和校验配置的实测波形。

0x55 = 0101 0101₂。因为低位先行,D0~D7 依次仍是 1,0,1,0,1,0,1,0,所以示波器上出现交替高低电平。

9600 波特时每位时间:

Tbit=19600≈104.17 μsT_{bit}=\frac{1}{9600}\approx104.17\ \mu sTbit=96001≈104.17 μs

8N1 一帧共 10 位:1 起始 + 8 数据 + 1 停止,因此:

Tframe=10×104.17 μs≈1.0417 msT_{frame}=10\times104.17\ \mu s\approx1.0417\ msTframe=10×104.17 μs≈1.0417 ms

连续发送时理论有效载荷上限:

960010=960 字节/秒\frac{9600}{10}=960\ \text{字节/秒}109600=960 字节/秒

所以"9600 bit/s"不等于"每秒传 9600 个有效数据字节",帧开销也占时间。

8. 奇偶校验到底校验什么

模式 目标
无校验 不添加校验位
偶校验 数据位与校验位中 1 的总数为偶数
奇校验 数据位与校验位中 1 的总数为奇数

奇偶校验可以发现奇数个位翻转,无法保证发现两个位同时翻转,也不能纠正错误。需要更强错误检测时,应在上层数据包使用 CRC 等算法。

8.1 STM32 的"8/9 位字长"容易误解

STM32F1 的 USART_CR1.M 定义硬件数据字总长度,启用校验后,最高位会被校验位占用:

M PCE 有效载荷 线路中的数据/校验部分
0(8 位字长) 0 8 位 8 个数据位
0 1 7 位 7 个数据位 + 1 校验位
1(9 位字长) 0 9 位 9 个数据位
1 1 8 位 8 个数据位 + 1 校验位

所以常见"8 个有效数据位 + 奇偶校验"在 STM32F1 上应选择 9 位字长并开启校验。参考手册 PDF 第 518、542~543 页。

9. USART 外设替 CPU 做了什么

图 6 老师 PPT 第 114 页:USART 能自动生成和解析串口帧。

如果完全使用 GPIO 模拟串口,CPU 必须按精确时间改变 TX、定时采样 RX、检测起始位并拼装字节。USART 硬件把这些工作自动化:

  • 发送:CPU 写一个数据字,硬件自动添加起始位、校验位、停止位并按波特率输出;
  • 接收:硬件检测下降沿、过采样每一位、恢复数据并把完整数据字交给 CPU;
  • 状态:通过 TXE、TC、RXNE 和错误标志告诉程序当前进度;
  • 扩展:可配合中断、DMA、同步时钟、硬件流控制、LIN、IrDA 等。

STM32F103C8T6 有 USART1、USART2、USART3。参考手册对整个系列还会描述 UART4/5,但它们不属于本型号资源。

10. 从完整框图缩成学习主线

图 7 老师 PPT 第 115 页:官方 USART 完整框图。

完整框图包含异步收发、同步 CK、唤醒、多处理器、LIN、IrDA、智能卡、流控制、中断和 DMA。当前只抓住四条主线:

  1. PCLK → BRR → 波特率时钟
  2. CPU写DR → TDR → 发送移位寄存器 → TX
  3. RX → 接收移位寄存器 → RDR → CPU读DR
  4. SR状态标志 → 轮询或NVIC中断

图 8 老师 PPT 第 116 页:用于编程理解的 USART 简化结构。

11. 发送流程:TXE 和 TC 为什么不是一回事

TX引脚 发送移位寄存器 发送数据寄存器TDR CPU TX引脚 发送移位寄存器 发送数据寄存器TDR CPU #mermaid-svg-qbKFrjR3Ev4pvQba{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-qbKFrjR3Ev4pvQba .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-qbKFrjR3Ev4pvQba .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-qbKFrjR3Ev4pvQba .error-icon{fill:#552222;}#mermaid-svg-qbKFrjR3Ev4pvQba .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-qbKFrjR3Ev4pvQba .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-qbKFrjR3Ev4pvQba .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-qbKFrjR3Ev4pvQba .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-qbKFrjR3Ev4pvQba .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-qbKFrjR3Ev4pvQba .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-qbKFrjR3Ev4pvQba .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-qbKFrjR3Ev4pvQba .marker{fill:#333333;stroke:#333333;}#mermaid-svg-qbKFrjR3Ev4pvQba .marker.cross{stroke:#333333;}#mermaid-svg-qbKFrjR3Ev4pvQba svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-qbKFrjR3Ev4pvQba p{margin:0;}#mermaid-svg-qbKFrjR3Ev4pvQba .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-qbKFrjR3Ev4pvQba text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-qbKFrjR3Ev4pvQba .actor-line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-qbKFrjR3Ev4pvQba .innerArc{stroke-width:1.5;stroke-dasharray:none;}#mermaid-svg-qbKFrjR3Ev4pvQba .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-qbKFrjR3Ev4pvQba .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-qbKFrjR3Ev4pvQba #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-qbKFrjR3Ev4pvQba .sequenceNumber{fill:white;}#mermaid-svg-qbKFrjR3Ev4pvQba #sequencenumber{fill:#333;}#mermaid-svg-qbKFrjR3Ev4pvQba #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-qbKFrjR3Ev4pvQba .messageText{fill:#333;stroke:none;}#mermaid-svg-qbKFrjR3Ev4pvQba .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-qbKFrjR3Ev4pvQba .labelText,#mermaid-svg-qbKFrjR3Ev4pvQba .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-qbKFrjR3Ev4pvQba .loopText,#mermaid-svg-qbKFrjR3Ev4pvQba .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-qbKFrjR3Ev4pvQba .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-qbKFrjR3Ev4pvQba .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-qbKFrjR3Ev4pvQba .noteText,#mermaid-svg-qbKFrjR3Ev4pvQba .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-qbKFrjR3Ev4pvQba .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-qbKFrjR3Ev4pvQba .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-qbKFrjR3Ev4pvQba .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-qbKFrjR3Ev4pvQba .actorPopupMenu{position:absolute;}#mermaid-svg-qbKFrjR3Ev4pvQba .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-qbKFrjR3Ev4pvQba .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-qbKFrjR3Ev4pvQba .actor-man circle,#mermaid-svg-qbKFrjR3Ev4pvQba line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-qbKFrjR3Ev4pvQba :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} TXE清0 TDR空,TXE置1 loop按波特率逐位输出 最后停止位发完且TXE=1,TC置1 写USART_DR硬件装载数据起始位 数据位 校验位 停止位

标志 含义 应该什么时候等待
TXE TDR 已空,可以写入下一个数据而不覆盖上一个 连续发送数组时,每写下一个字节前
TC TDR 和移位寄存器都空,最后一帧的停止位已经真正发完 关闭 USART、切换半双工方向或进入低功耗前

USART_DR 会清 TXE;数据从 TDR 搬到移位寄存器后,硬件又置 TXE。此时上一帧可能仍在 TX 引脚上发送,因此 TXE=1 不表示线路已经全部发送完。参考手册 PDF 第 519~521、540 页。

11.1 连续发送为什么需要 TDR 缓冲

移位寄存器发送当前帧时,CPU 可以提前把下一字节写进 TDR。当前帧完成后,硬件立即把下一字节装入移位寄存器,减少帧间空隙,提高吞吐率。

12. 接收流程:RXNE 为什么必须及时处理

CPU 接收数据寄存器RDR 接收移位寄存器 RX引脚 CPU 接收数据寄存器RDR 接收移位寄存器 RX引脚 #mermaid-svg-eESG5ACE3uGVRvrg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-eESG5ACE3uGVRvrg .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-eESG5ACE3uGVRvrg .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-eESG5ACE3uGVRvrg .error-icon{fill:#552222;}#mermaid-svg-eESG5ACE3uGVRvrg .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-eESG5ACE3uGVRvrg .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-eESG5ACE3uGVRvrg .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-eESG5ACE3uGVRvrg .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-eESG5ACE3uGVRvrg .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-eESG5ACE3uGVRvrg .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-eESG5ACE3uGVRvrg .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-eESG5ACE3uGVRvrg .marker{fill:#333333;stroke:#333333;}#mermaid-svg-eESG5ACE3uGVRvrg .marker.cross{stroke:#333333;}#mermaid-svg-eESG5ACE3uGVRvrg svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-eESG5ACE3uGVRvrg p{margin:0;}#mermaid-svg-eESG5ACE3uGVRvrg .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-eESG5ACE3uGVRvrg text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-eESG5ACE3uGVRvrg .actor-line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-eESG5ACE3uGVRvrg .innerArc{stroke-width:1.5;stroke-dasharray:none;}#mermaid-svg-eESG5ACE3uGVRvrg .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-eESG5ACE3uGVRvrg .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-eESG5ACE3uGVRvrg #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-eESG5ACE3uGVRvrg .sequenceNumber{fill:white;}#mermaid-svg-eESG5ACE3uGVRvrg #sequencenumber{fill:#333;}#mermaid-svg-eESG5ACE3uGVRvrg #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-eESG5ACE3uGVRvrg .messageText{fill:#333;stroke:none;}#mermaid-svg-eESG5ACE3uGVRvrg .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-eESG5ACE3uGVRvrg .labelText,#mermaid-svg-eESG5ACE3uGVRvrg .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-eESG5ACE3uGVRvrg .loopText,#mermaid-svg-eESG5ACE3uGVRvrg .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-eESG5ACE3uGVRvrg .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-eESG5ACE3uGVRvrg .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-eESG5ACE3uGVRvrg .noteText,#mermaid-svg-eESG5ACE3uGVRvrg .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-eESG5ACE3uGVRvrg .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-eESG5ACE3uGVRvrg .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-eESG5ACE3uGVRvrg .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-eESG5ACE3uGVRvrg .actorPopupMenu{position:absolute;}#mermaid-svg-eESG5ACE3uGVRvrg .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-eESG5ACE3uGVRvrg .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-eESG5ACE3uGVRvrg .actor-man circle,#mermaid-svg-eESG5ACE3uGVRvrg line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-eESG5ACE3uGVRvrg :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} RXNE置1 altRXNEIE=1轮询 RXNE清0 侦测起始位并逐位采样拼成完整数据字并检查错误一帧完成后转入RDR请求USART中断查询RXNE读USART_DR

RXNE=1 表示 RDR 中已有未读数据。软件读取 USART_DR 后,RXNE 清零,硬件才能安全地把下一帧交给 RDR。

如果下一帧已经收完,而上一个 RXNE 仍未清除,会发生溢出错误 ORE:RDR 中的旧数据仍可读,但接收移位寄存器中新到的数据会丢失。高速或持续接收不应在主循环中长时间阻塞,应使用 RXNE 中断或 DMA。依据参考手册 PDF 第 522~523 页。

13. 接收器如何在没有时钟线时找到采样点

图 9 老师 PPT 第 119 页:通过 16 倍采样确认起始位。

异步串口双方没有共享时钟。接收器用波特率的 16 倍频率观察 RX:

  1. 空闲时持续看到高电平;
  2. 发现下降趋势后,不立即认定为起始位;
  3. 在预定的多个采样点检查低电平,排除短噪声脉冲;
  4. 确认起始位后,将后续位的采样中心对齐在第 8、9、10 个采样点附近。

图 10 老师 PPT 第 120 页:一个数据位中心连续采样三次。

正常数据位在中心采样 3 次:

  • 000 判为 0,111 判为 1,数据有效;
  • 结果不一致时按 2:1 多数表决恢复 0 或 1,同时置噪声标志 NE

这能抵抗短暂噪声,但不能弥补严重的波特率不匹配、长期干扰或错误电平标准。

14. 波特率发生器与 BRR 计算

图 11 老师 PPT 第 121 页:PCLK 经 USARTDIV 分频后形成 16 倍采样时钟。

STM32F1 默认 16 倍过采样时:

Baud=fPCLK16×USARTDIVBaud=\frac{f_{PCLK}}{16\times USARTDIV}Baud=16×USARTDIVfPCLK

USART_BRR 的高 12 位保存 USARTDIV 整数部分,低 4 位保存小数部分乘 16 后的编码。

14.1 USART1 配置 9600 波特示例

假设 PCLK2 = 72 MHz

USARTDIV=72,000,00016×9600=468.75USARTDIV=\frac{72,000,000}{16\times9600}=468.75USARTDIV=16×960072,000,000=468.75

  • 整数部分:468 = 0x1D4
  • 小数部分:0.75×16=12=0xC
  • 因此 BRR:0x1D4C

标准外设库的 USART_Init(..., USART_BaudRate=9600) 会根据外设时钟自动计算 BRR,通常不需要手算固定常量。但理解公式可以帮助排查:系统时钟配置错误、USART1/2 总线选错或串口助手乱码。

14.2 为什么 USART1 与 USART2 的公式输入时钟不同

  • USART1 挂 APB2,使用 PCLK2;
  • USART2、USART3 挂 APB1,使用 PCLK1。

在常见 72 MHz 配置下,USART1 通常输入 72 MHz,USART2/3 通常输入 36 MHz。不能把 CPU 主频无条件直接代入所有 USART。

15. USART 核心寄存器地图

寄存器 作用 本节重点字段 参考手册 PDF
USART_SR 状态和错误 TXE、TC、RXNE、IDLE、ORE、NE、FE、PE 540~541
USART_DR 软件统一访问的数据寄存器,内部实际分 TDR/RDR DR8:0 541~542
USART_BRR 波特率分频 DIV_Mantissa、DIV_Fraction 542
USART_CR1 基本使能、字长、校验、中断 UE、M、PCE、PS、TXEIE、TCIE、RXNEIE、TE、RE 542~544
USART_CR2 停止位、同步时钟、节点地址、LIN STOP、CLKEN、CPOL、CPHA、ADD 544~545
USART_CR3 DMA、流控制、半双工和错误中断 DMAT、DMAR、CTSE、RTSE、HDSEL、EIE 545~546
USART_GTPR 智能卡保护时间与 IrDA/智能卡预分频 GT、PSC 546~547

15.1 USART_SR 的常用标志

标志 硬件含义 常见清除方式
7 TXE TDR 空,可以写下一数据 写 DR
6 TC 最后一帧发送完成 读 SR 后写 DR;特定场景可写 0
5 RXNE RDR 非空,有数据可读 读 DR
4 IDLE 检测到总线空闲 先读 SR,再读 DR
3 ORE 未读旧数据时又收到新数据 先读 SR,再读 DR
2 NE 接收采样出现噪声 先读 SR,再读 DR
1 FE 停止位无效或失步 先读 SR,再读 DR
0 PE 奇偶校验错误 等 RXNE 后先读 SR,再读 DR

15.2 USART_CR1 的最小异步配置

作用 典型 9600 8N1
UE 整个 USART 使能 1
M 字长 0:8 位
PCE/PS 校验使能/奇偶选择 PCE=0,无校验
TE 发送器使能 需要发送则为 1
RE 接收器使能 需要接收则为 1
RXNEIE 接收非空中断 中断接收时为 1

TERE 独立:只发送可只开 TE,只接收可只开 RE,全双工则两者都开。UE 是整个外设总开关。

15.3 USART_CR2 的 STOP 编码

STOP1:0 停止位
00 1 位
01 0.5 位
10 2 位
11 1.5 位

普通异步串口通常使用 1 或 2 位。0.5/1.5 主要与智能卡模式有关,不是普通 UART 的常用配置。

16. 从目标推导下一节初始化顺序

虽然这节没有正式逐行编写代码,但从硬件结构已经能推出基础 USART1 的初始化路线:
#mermaid-svg-jTAbOAK77UgqGxzc{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-jTAbOAK77UgqGxzc .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-jTAbOAK77UgqGxzc .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-jTAbOAK77UgqGxzc .error-icon{fill:#552222;}#mermaid-svg-jTAbOAK77UgqGxzc .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-jTAbOAK77UgqGxzc .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-jTAbOAK77UgqGxzc .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-jTAbOAK77UgqGxzc .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-jTAbOAK77UgqGxzc .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-jTAbOAK77UgqGxzc .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-jTAbOAK77UgqGxzc .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-jTAbOAK77UgqGxzc .marker{fill:#333333;stroke:#333333;}#mermaid-svg-jTAbOAK77UgqGxzc .marker.cross{stroke:#333333;}#mermaid-svg-jTAbOAK77UgqGxzc svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-jTAbOAK77UgqGxzc p{margin:0;}#mermaid-svg-jTAbOAK77UgqGxzc .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-jTAbOAK77UgqGxzc .cluster-label text{fill:#333;}#mermaid-svg-jTAbOAK77UgqGxzc .cluster-label span{color:#333;}#mermaid-svg-jTAbOAK77UgqGxzc .cluster-label span p{background-color:transparent;}#mermaid-svg-jTAbOAK77UgqGxzc .label text,#mermaid-svg-jTAbOAK77UgqGxzc span{fill:#333;color:#333;}#mermaid-svg-jTAbOAK77UgqGxzc .node rect,#mermaid-svg-jTAbOAK77UgqGxzc .node circle,#mermaid-svg-jTAbOAK77UgqGxzc .node ellipse,#mermaid-svg-jTAbOAK77UgqGxzc .node polygon,#mermaid-svg-jTAbOAK77UgqGxzc .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-jTAbOAK77UgqGxzc .rough-node .label text,#mermaid-svg-jTAbOAK77UgqGxzc .node .label text,#mermaid-svg-jTAbOAK77UgqGxzc .image-shape .label,#mermaid-svg-jTAbOAK77UgqGxzc .icon-shape .label{text-anchor:middle;}#mermaid-svg-jTAbOAK77UgqGxzc .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-jTAbOAK77UgqGxzc .rough-node .label,#mermaid-svg-jTAbOAK77UgqGxzc .node .label,#mermaid-svg-jTAbOAK77UgqGxzc .image-shape .label,#mermaid-svg-jTAbOAK77UgqGxzc .icon-shape .label{text-align:center;}#mermaid-svg-jTAbOAK77UgqGxzc .node.clickable{cursor:pointer;}#mermaid-svg-jTAbOAK77UgqGxzc .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-jTAbOAK77UgqGxzc .arrowheadPath{fill:#333333;}#mermaid-svg-jTAbOAK77UgqGxzc .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-jTAbOAK77UgqGxzc .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-jTAbOAK77UgqGxzc .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-jTAbOAK77UgqGxzc .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-jTAbOAK77UgqGxzc .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-jTAbOAK77UgqGxzc .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-jTAbOAK77UgqGxzc .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-jTAbOAK77UgqGxzc .cluster text{fill:#333;}#mermaid-svg-jTAbOAK77UgqGxzc .cluster span{color:#333;}#mermaid-svg-jTAbOAK77UgqGxzc div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-jTAbOAK77UgqGxzc .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-jTAbOAK77UgqGxzc rect.text{fill:none;stroke-width:0;}#mermaid-svg-jTAbOAK77UgqGxzc .icon-shape,#mermaid-svg-jTAbOAK77UgqGxzc .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-jTAbOAK77UgqGxzc .icon-shape p,#mermaid-svg-jTAbOAK77UgqGxzc .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-jTAbOAK77UgqGxzc .icon-shape .label rect,#mermaid-svg-jTAbOAK77UgqGxzc .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-jTAbOAK77UgqGxzc .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-jTAbOAK77UgqGxzc .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-jTAbOAK77UgqGxzc :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 确定通信参数

如9600 8N1
根据板卡和数据手册确定USART与引脚
开启GPIOA和USART1时钟
TX配复用推挽输出
RX配输入模式
配置波特率 字长 停止位 校验
按需求使能TE和RE
接收中断时配置RXNEIE与NVIC
最后使能USART
发送等TXE后写DR
接收等RXNE后读DR

为什么 TX 是复用推挽:TX 波形由 USART 外设驱动,不是普通 GPIO ODR 控制;推挽能主动输出高低电平。为什么 RX 是输入:外部设备驱动这根线,USART 从 GPIO 输入路径读取电平。具体输入模式和重映射以本课程下一节源码为准。

17. 从字节到应用信息的完整分层

#mermaid-svg-sqrfWgQUZnAdele4{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-sqrfWgQUZnAdele4 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-sqrfWgQUZnAdele4 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-sqrfWgQUZnAdele4 .error-icon{fill:#552222;}#mermaid-svg-sqrfWgQUZnAdele4 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-sqrfWgQUZnAdele4 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-sqrfWgQUZnAdele4 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-sqrfWgQUZnAdele4 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-sqrfWgQUZnAdele4 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-sqrfWgQUZnAdele4 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-sqrfWgQUZnAdele4 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-sqrfWgQUZnAdele4 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-sqrfWgQUZnAdele4 .marker.cross{stroke:#333333;}#mermaid-svg-sqrfWgQUZnAdele4 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-sqrfWgQUZnAdele4 p{margin:0;}#mermaid-svg-sqrfWgQUZnAdele4 .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-sqrfWgQUZnAdele4 .cluster-label text{fill:#333;}#mermaid-svg-sqrfWgQUZnAdele4 .cluster-label span{color:#333;}#mermaid-svg-sqrfWgQUZnAdele4 .cluster-label span p{background-color:transparent;}#mermaid-svg-sqrfWgQUZnAdele4 .label text,#mermaid-svg-sqrfWgQUZnAdele4 span{fill:#333;color:#333;}#mermaid-svg-sqrfWgQUZnAdele4 .node rect,#mermaid-svg-sqrfWgQUZnAdele4 .node circle,#mermaid-svg-sqrfWgQUZnAdele4 .node ellipse,#mermaid-svg-sqrfWgQUZnAdele4 .node polygon,#mermaid-svg-sqrfWgQUZnAdele4 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-sqrfWgQUZnAdele4 .rough-node .label text,#mermaid-svg-sqrfWgQUZnAdele4 .node .label text,#mermaid-svg-sqrfWgQUZnAdele4 .image-shape .label,#mermaid-svg-sqrfWgQUZnAdele4 .icon-shape .label{text-anchor:middle;}#mermaid-svg-sqrfWgQUZnAdele4 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-sqrfWgQUZnAdele4 .rough-node .label,#mermaid-svg-sqrfWgQUZnAdele4 .node .label,#mermaid-svg-sqrfWgQUZnAdele4 .image-shape .label,#mermaid-svg-sqrfWgQUZnAdele4 .icon-shape .label{text-align:center;}#mermaid-svg-sqrfWgQUZnAdele4 .node.clickable{cursor:pointer;}#mermaid-svg-sqrfWgQUZnAdele4 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-sqrfWgQUZnAdele4 .arrowheadPath{fill:#333333;}#mermaid-svg-sqrfWgQUZnAdele4 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-sqrfWgQUZnAdele4 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-sqrfWgQUZnAdele4 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-sqrfWgQUZnAdele4 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-sqrfWgQUZnAdele4 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-sqrfWgQUZnAdele4 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-sqrfWgQUZnAdele4 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-sqrfWgQUZnAdele4 .cluster text{fill:#333;}#mermaid-svg-sqrfWgQUZnAdele4 .cluster span{color:#333;}#mermaid-svg-sqrfWgQUZnAdele4 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-sqrfWgQUZnAdele4 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-sqrfWgQUZnAdele4 rect.text{fill:none;stroke-width:0;}#mermaid-svg-sqrfWgQUZnAdele4 .icon-shape,#mermaid-svg-sqrfWgQUZnAdele4 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-sqrfWgQUZnAdele4 .icon-shape p,#mermaid-svg-sqrfWgQUZnAdele4 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-sqrfWgQUZnAdele4 .icon-shape .label rect,#mermaid-svg-sqrfWgQUZnAdele4 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-sqrfWgQUZnAdele4 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-sqrfWgQUZnAdele4 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-sqrfWgQUZnAdele4 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 应用数据

数字 字符 命令
编码或数据包规则
一个或多个字节
USART添加起始校验停止位
TX线路高低电平
对端USART采样并恢复字节
HEX显示或字符解码
对端应用处理

USART 只负责把数据字可靠地变成帧并恢复数据字,不知道 0x41 是字母 A、传感器值 65,还是协议命令。字符串结束、包头包尾、长度和校验属于上层协议,将在后续数据包课程处理。

18. 常见故障排查

现象 优先检查
串口助手完全无数据 COM 口、波特率、共地、TX→RX、USART/GPIO 时钟、TE/UE
全是乱码 两端波特率/字长/校验/停止位不一致;PCLK 或 BRR 计算错误;电平标准不匹配
只能发送不能接收 RX 接线、RE、RX 引脚模式、RXNE/RXNEIE、NVIC
发一个字节后卡住 等待了错误标志,或 TXE/TC 理解混淆
接收偶尔丢字节 RXNE 未及时读导致 ORE;中断处理过慢;波特率过高
收到数据但 NE/FE 置位 噪声、地线差、波特率误差、接线过长或停止位不匹配
HEX 正常但文本"奇怪" 数据不是可打印字符,或字符编码/换行约定不同
复位时电脑偶尔收到异常字符 TX 引脚上电阶段状态、USB 转串口模块供电或参数不一致

19. 转写与表述校正

  • "USIT/USPID/USIDE"等识别结果应按上下文校正为 USART/UART。
  • "GX/X、TXD/XD"等应为 TX/RX 或 TXD/RXD。
  • "电瓶标准"应为"电平标准"。
  • "RS22.0"应为 RS-232,"RS485.0"应为 RS-485。
  • "基校验/偶两遍"应为奇校验/偶校验。
  • "状态计算器、数据问题 DR、配置计算器 CR"应为状态寄存器 SR、数据寄存器 DR、控制寄存器 CR。
  • 转写中把 RXNE 偶尔识别成 TXNE。STM32F1 的接收非空标志正式名称是 RXNE
  • "串口只能发送十六进制"不够严谨:线路发送的是二进制位;十六进制只是人类书写一个字节的方式。
  • 课堂把 3.3 V 和 5 V 都概括为 TTL 电平是入门简化。实际连接必须继续核对输入阈值、输出电平和引脚耐压,不能只看协议名称。
  • 老师说 USART 可配置 0.5/1/1.5/2 停止位属外设能力;普通异步模式主要用 1 或 2,0.5/1.5 与智能卡用途相关。

20. 本节边界与下一步

本节已经完成串口协议与 USART 硬件模型:知道线怎么接、位怎么发、接收器怎么采样,以及寄存器和标志位在数据通路中的位置。

下一节才进入标准库代码:配置 RCC 和 GPIO、填写 USART_InitTypeDef、调用 USART_SendData、等待 TXE、读取 USART_ReceiveData、配置 RXNE 中断,并实现发送数组、字符串、数字和 printf 重定向。

21. 复习自测

  1. 为什么 TTL 串口必须共地?
  2. 为什么 TX 要接对方 RX,而不能 TX 接 TX?
  3. 9600 8N1 发送一个字节在线路上共有多少位?理论每秒最多多少字节?
  4. 为什么总线空闲和停止位都规定为高电平?
  5. 0x0F 按低位先行时 D0~D7 依次是什么?
  6. STM32F1 要传 8 位有效数据并启用校验,M 和 PCE 应怎样配置?
  7. TXE=1 是否代表最后一个停止位已经发完?为什么?
  8. RXNE 长时间不清除会导致什么错误?会丢掉哪一份数据?
  9. 16 倍采样为什么要在一位中心连续采 3 次?
  10. USART1 与 USART2 计算 BRR 时分别使用哪个 PCLK?
  11. 72 MHz、9600 波特时为什么 BRR 是 0x1D4C
  12. USART_DR 为什么同一个地址既能写发送数据,又能读接收数据?

22. 参考资料与页码索引

  • 课堂转写:00:05~03:16 程序现象;03:16~07:38 通信概念;07:38~18:05 串口硬件、电平和帧;18:05~42:41 时序、USART 结构、采样和波特率;42:41~47:37 模块与手册。
  • 老师 PPT:《STM32入门教程》第 108 页通信接口;第 110~113 页接线、电平、参数和波形;第 114~116 页 USART 简介与结构;第 119~121 页起始位侦测、数据采样和波特率。
  • 师兄笔记:《STM32笔记》PDF 第 87~92 页;第 87~89 页为通信、硬件、电平、时序和 USART 简介,第 90~92 页为框图、基本结构、数据帧、采样与波特率。
  • 《STM32F10xxx参考手册(中文)》PDF 第 516~525 页:USART 特性、数据帧、发送器、接收器、起始位、错误和波特率。
  • 《STM32F10xxx参考手册(中文)》PDF 第 538~547 页:中断以及 SR、DR、BRR、CR1、CR2、CR3、GTPR 寄存器。
  • 《STM32F103x8B数据手册(中文)》PDF 第 17~20 页:具体封装的 USART 引脚、默认复用和重映射功能。

23. 一句话总结

异步串口先用共地且电平兼容的 TX/RX 线路传输"空闲高、起始低、数据低位先行、停止高"的数据帧,STM32 USART 再通过 BRR 生成波特率、发送和接收移位寄存器自动处理逐位时序,并用 TXE、TC、RXNE 与错误标志把硬件进度交给软件。

相关推荐
一条破秋裤2 小时前
22_串口HEX与文本数据包收发
stm32·嵌入式硬件
sunoo-2292 小时前
51单片机学习Day2:数码管动态扫描、定时器与中断系统深度总
单片机·嵌入式硬件·学习·51单片机
小娄~~3 小时前
LVGL,STM32U575RIT6+指纹模块
stm32·单片机·嵌入式硬件
Brilliantwxx3 小时前
【STM32】 HAL库深度入门:从设计思想到 USART 全模式实战
stm32·单片机·嵌入式硬件
JNX_SEMI4 小时前
HTD8239 5.5V~36V宽压H桥驱动:适配12V/24V主流电机供电系统
单片机·嵌入式硬件
2401_862880824 小时前
51单片机 --- GPIO、中断、定时器、PWM
单片机·嵌入式硬件·51单片机
国科安芯4 小时前
基于ECC加固的抗辐射MCU在卫星载荷数据管理中的应用分析
单片机·嵌入式硬件·mcu·抗辐射·ecc加固·卫星数据管理
abc light6 小时前
单片机(1)
单片机·嵌入式硬件
云泽8086 小时前
STM32 USART 详解(四):数据帧及标志位的收发机制与寄存器深度剖析
stm32·单片机·嵌入式硬件