USART串口协议
一.通信接口

PPT顶部用两句话概括了通信的本质:
-
通信的目的:"将一个设备的数据传送到另一个设备,扩展硬件系统。"
- 解析:单片机(MCU)自身的资源是有限的(比如内存、计算能力)。通过通信接口,我们可以把数据传给传感器(获取外界信息)、屏幕(显示信息)、另一个单片机(协同计算)或者电脑(调试和记录)。这就是"扩展硬件系统"。
-
通信协议:"制定通信的规则,通信双方按照协议规则进行数据收发。"
- 解析 :两个设备之间连线通电了,不能随便乱发高低电平,否则对方根本听不懂。必须有统一的"语言规则",包括:用几伏电压代表1、什么时候开始发、一次发几位、发多快等等。这套规则就是通信协议。
第二部分:表格表头维度说明(评价标准)
在横向对比之前,我们需要先搞懂表头里这6个词到底是什么意思:
-
名称:通信协议的名字(USART、I2C、SPI、CAN、USB)。
-
引脚:物理连接需要接哪几根线。
-
双工:
-
全双工:可以同时发送和接收数据(比如打电话,TX发送的同时RX也能接收)。
-
半双工:发送和接收不能同时进行,必须轮流交替(比如对讲机,发送时不能接收,接收时不能发送)。
-
-
时钟:
-
同步:有一根专门传输时钟信号(节拍器)的线,接收方跟随节拍工作,无需担心速度不匹配的问题。
-
异步:没有时钟线。双方必须提前约定好传输速度(波特率),依靠数据帧中的起始位和停止位来对齐。
-
-
电平:
-
单端:信号线只有一根,电平是相对于"地线(GND)"来测量的(比如3.3V代表1,0V代表0)。容易受到干扰。
-
差分 :使用两根线(一正一反),依靠两根线的电压差来表示1和0。抗干扰能力极强,适合远距离传输。
-
-
设备:总线上能挂载多少个设备(点对点就是只能1对1;多设备就是可以挂载很多个)。
第三部分:表格逐行精讲(五大通信接口)
现在,我们按照表格从上到下,逐一拆解这五种协议:
1. USART(最常用的基础串口)
-
引脚(TX、RX):TX负责发,RX负责收。
-
双工(全双工):因为TX和RX独立,所以可以同时收发。
-
时钟(异步):没有时钟线。这就是为什么你在配置串口时,双方必须都配置成一样的"波特率(如9600、115200)",否则收到的就是乱码。
-
电平(单端) :通常就是我们说的TTL电平(0V和3.3V/5V)。因为单端抗干扰差,所以串口一般只用于板级通信或短距离调试。
-
设备(点对点):通常是一个单片机连一个电脑,或者一个单片机连一个模块,不能把好几个设备的TX直接拧在一起。
2. I2C(集成电路总线)
-
引脚(SCL、SDA):SCL是时钟线(Serial Clock),SDA是数据线(Serial Data)。只有两根线!
-
双工(半双工):因为只有一根SDA数据线,同一时刻要么发数据,要么收数据,不能同时。
-
时钟(同步):有SCL时钟线,所以是同步通信。
-
电平(单端):也是单端信号。因为单端且线少,I2C通常用于连接板载的慢速外设(如EEPROM、温湿度传感器)。注意:I2C的引脚必须外接上拉电阻(开漏输出)。
-
设备(多设备):这是I2C的强项。两根线上可以挂几十上百个设备,每个设备有自己的"I2C地址",主机通过地址来呼叫特定设备。
3. SPI(串行外设接口)
-
引脚(SCLK、MOSI、MISO、CS):SCLK是时钟;MOSI(Master Out Slave In)是主机发、从机收;MISO(Master In Slave Out)是主机收、从机发;CS(片选)用于选择跟哪个从机说话。
-
双工(全双工):MOSI和MISO独立,可以同时收发。
-
时钟(同步):有SCLK时钟线,同步通信。
-
电平(单端):单端信号,通常用于板载通信。
-
设备(多设备):通过CS片选线实现多设备。比如你有3个SPI设备,就需要3根CS线,每个设备单独接一根。SPI速度比I2C快很多,常用于Flash、屏幕等高速设备。
4. CAN(控制器局域网)
-
引脚(CAN_H、CAN_L):两根差分线。
-
双工(半双工):虽然有两根线,但它们是一对差分信号,同一时刻只能代表一个逻辑状态,收发不能同时进行。
-
时钟(异步):没有时钟线,靠约定的波特率。
-
电平(差分) :这是重点! CAN使用的是差分电平(两根线的电压差)。这让它具备极强的抗电磁干扰能力,能在恶劣的工业环境和汽车内部(几百米甚至几千米)传输数据。
-
设备(多设备):CAN是一种总线,可以挂载几十个节点(比如汽车里的各种ECU),而且自带优先级仲裁机制(ID小的优先发送)。
5. USB(通用串行总线)
-
引脚(DP、DM):Data Plus 和 Data Minus,两根差分数据线。
-
双工(半双工):PPT上将USB标记为半双工(严格来说,USB 2.0是半双工,USB 3.0以上加入了全双工差分对,但基础架构仍是基于轮询的)。
-
时钟(异步):没有独立的时钟线,时钟信息编码在数据流中(NRZI编码),接收方通过锁相环(PLL)恢复时钟。
-
电平(差分):差分信号,抗干扰能力强,支持热插拔和长距离(相对板级)传输。
-
设备(点对点):USB在物理拓扑上是严格的"主机(Host)-设备(Device)"点对点结构。虽然你可以用一个USB HUB扩展出很多接口,但在逻辑链路上,主机永远是轮流和每个设备进行点对点通信。
总结与学习建议
这张PPT的精髓在于**"对比"**。当你在做项目时,你要选型:
-
要调试打印信息,简单易用 -> USART
-
要接很多个低速传感器,线越少越好 -> I2C
-
要接屏幕/Flash,要求速度极快 -> SPI
-
要汽车/工业级长距离、强抗干扰 -> CAN
-
要接电脑、免驱或者传大文件 -> USB
二.串口通信
)
串口优点与应用场景
1. 串口的四大优点:"成本低、容易使用、通信线路简单,可实现两个设备的互相通信"
-
成本低:硬件上不需要复杂的控制器,单片机内部自带串口外设,连线上只需要几根杜邦线,几毛钱就能搞定。
-
容易使用:协议相对简单,不需要像USB那样处理复杂的枚举和驱动,配置好波特率就能发数据。
-
通信线路简单 :最少只需要三根线------TX(发送)、RX(接收)、GND(地线)。对比一下I2C、SPI,串口可以说是最简单的通信方式了。
-
点对点互相通信:基于全双工的特性,A可以给B发,B也可以给A发。
2. 串口的三大应用场景:"单片机与单片机、单片机与电脑、单片机与各式各样的模块"
-
单片机与单片机:比如两块开发板互传数据,板1的TX接板2的RX,板1的RX接板2的TX,交叉连接即可。
-
单片机与电脑 :这是你未来调试代码最常用的手段!单片机把程序运行的状态、传感器数据通过串口发给电脑上的"串口助手"显示出来,相当于给单片机装了个"显示屏"。
-
单片机与各式各样的模块:这是"极大地扩展了单片机的应用范围"的关键。GPS模块、蓝牙模块、WiFi模块、语音模块、甚至是某些屏幕,很多都是通过串口和单片机通信的。单片机不需要知道模块内部怎么工作,只要通过串口发指令,模块就能干活。
PPT三图模块讲解
1. 左图:USB转TTL模块(最核心的调试工具)
-
外观:一头是USB插头(插电脑),另一头是4个排针(VCC, GND, TX, RX),中间通常有一块黑色的芯片(常见的是CH340、CP2102、FT232)。
-
作用 :现在的电脑已经没有传统的DB9串口了,只有USB口。单片机的串口是TTL电平(0V/3.3V或5V),电脑的USB协议(差分电平)单片机不懂。这个模块的作用就是**"翻译官"**,把电脑的USB信号转换成单片机能听懂的TTL串口信号。
-
注意:图片上有一个黄色的跳线帽,通常用来选择输出3.3V还是5V。你接单片机时,一定要看单片机的电压,千万别选错,否则可能烧坏单片机。
2. 中图与右图:无线串口模块(透传模块,如蓝牙、WiFi、LoRa)
-
外观:核心是一块很小的电路板,上面有主控芯片、晶振,还有一个天线(中图左侧有明显的蛇形PCB天线,右图看起来像是蓝牙模块如HC-05/06,带引脚和天线)。
-
作用 :它们大大扩展了单片机的"硬件实力"。这些模块的底层可能是复杂的蓝牙协议、WiFi协议,但它们对单片机暴露出来的接口永远是最简单的串口(TX/RX)。
-
透传概念:单片机只要像平时发串口数据一样,把"开灯"这两个字的字符串发给模块,模块就会自动通过无线电把这两个字发给手机。手机发回来的"开灯成功",模块又会自动通过串口喂给单片机。单片机完全不需要懂什么蓝牙协议、TCP/IP协议,这就是串口的强大之处。
三.硬件电路(TX与RX)
核心要点解析
1. 简单双向串口通信有两根通信线(发送端TX和接收端RX)
-
这就是我们之前提到的全双工。设备1通过自己的TX线把数据发出去,通过自己的RX线接收数据。因为收发各占用一根线,所以互不干扰。
-
注意:图中还有VCC和GND。严格的"通信线"是TX和RX,但为了让电路完整,通常还需要电源线(可选,看是否由一方给另一方供电)和地线(GND,必须接)。
2. TX与RX要交叉连接(重点!)
-
这是初学者最容易犯错的地方。看图中间的连线:设备1的TX接到了设备2的RX;设备1的RX接到了设备2的TX。
-
为什么? 打个比方,你(设备1)和对面的人(设备2)说话。你的嘴巴(TX) 要对着对方的耳朵(RX) ;对方的嘴巴(TX) 要对着你的耳朵(RX)。如果TX接TX,就变成了嘴巴对嘴巴,谁也听不见谁。
-
口诀 :"TX接RX,RX接TX"(收发交叉)。
3. 当只需单向的数据传输时,可以只接一根通信线
-
如果你只是想让设备1给设备2发数据,不需要设备2回复(比如单片机给一块只用来显示的串口屏发数据),那么你完全可以只接一根线:设备1的TX接设备2的RX。
-
当然,GND地线还是得接,否则没有共同的电压参考点,信号会乱。
-
这种叫做"单工"通信。省掉一根线可以降低成本,减少接线复杂度。
4. 当电平标准不一致时,需要加电平转换芯片(避坑指南!)
这是硬件连接中硬件损坏的"重灾区",一定要理解:
-
什么是电平标准?比如单片机输出的是TTL电平 (高电平3.3V或5V代表1,0V代表0)。而早期电脑的DB9串口输出的是RS232电平(负逻辑,-12V代表1,+12V代表0)。
-
如果你把单片机的TX(3.3V TTL)直接怼到电脑的RS232接口上,高压瞬间就会把单片机引脚烧毁。
-
所以,遇到不同电平标准的设备,中间必须加一个**"翻译官"(电平转换芯片)**。比如:
-
单片机(3.3V) <-> 电脑USB:需要 CH340 或 CP2102 等USB转TTL芯片。
-
单片机(TTL) <-> 老式工控机(RS232):需要 MAX3232 芯片。
-
单片机(3.3V) <-> 单片机(5V):虽然有时3.3V单片机能容忍5V输入,但为了保险,最好加电平转换电路或至少串一个电阻限流。
-
四.电平标准
这张PPT的主题是**"电平标准"** ,它解决的是串口通信在物理层最底层的问题:"在电线上,多高的电压代表1,多低的电压代表0?"
在前面的"硬件电路"PPT中我们提到过,如果电平标准不一致,会烧毁芯片。这张PPT就是详细解释为什么会有这种情况。
我们逐行详细拆解:
1. 核心概念:什么是电平标准?
"电平标准是数据1和数据0的表达方式,是传输线缆中人为规定的电压与数据的对应关系"
-
通俗解释 :单片机里面只有0和1(逻辑)。要把它们发出去,就得用电线。物理上的电线只能传电压。所以大家就坐下来开会,约定好:"如果这根线上的电压是X伏,那就代表1;如果是Y伏,那就代表0。" 这个**"约定",就是电平标准**。
-
核心认知 :通信协议(UART)和电平标准是两码事。 UART规定的是"一帧数据要有起始位、8个数据位、停止位";而TTL/RS232/RS485规定的是"在导线上用几伏特来表示这一个个的0和1"。
2. 三种常见的电平标准详解
① TTL电平(板上通信之王)
"+3.3V或+5V表示1,0V表示0"
-
特点 :正逻辑(正电压代表1,零电压代表0)。
-
应用场景 :板级通信。也就是同一块电路板上,芯片与芯片之间的通信(比如你的STM32和板子上的温湿度传感器)。现在的单片机绝大多数都是TTL电平。
-
为什么有3.3V和5V之分? 因为有些老芯片是5V供电,新的低功耗芯片是3.3V供电。如果一个3.3V的芯片给5V的芯片发数据,5V芯片可能识别不到3.3V是"1"。反之,5V芯片给3.3V芯片发数据,就会烧毁3.3V芯片。
-
缺点:电压低、单端信号(参考GND),抗干扰能力极差,只能传输几十厘米,一般不出电路板。
② RS232电平(老式电脑接口)
"-3~-15V表示1,+3~+15V表示0"
-
特点 :负逻辑(负电压代表1,正电压代表0)。而且电压非常高(最高可达±15V)。
-
应用场景:早期的电脑DB9接口(那个巨大的9针串口)、老式工业设备。
-
为什么这么反直觉? 历史上早期的长距离通信为了抗干扰,电压摆幅做得很大(±15V)。为了和TTL区分开,加上负逻辑,RS232的电平定义刚好是TTL的反相。
-
避坑指南 :绝对不可以把RS232的电平直接接到单片机的TTL引脚上! 15V的负电压或者正电压,瞬间会把单片机引脚击穿。它们之间必须加转换芯片(比如经典的MAX3232芯片)。
③ RS485电平(工业长距离之王)
"两线压差+2~+6V表示1,-2~-6V表示0(差分信号)"
-
特点 :差分信号 。它不看单根线对地的电压,而是看两根线(通常叫A线和B线)之间的电压差。如果A比B高2~6V,就是1;如果B比A高2~6V,就是0。
-
优势:抗干扰能力极强!如果旁边有电机产生干扰,两根线上会同时叠加相同的干扰电压,因为它是看"差值",干扰就被抵消了(共模抑制)。
-
应用场景:工业控制、远距离传输(可达1200米)、汽车内部。
-
注意事项 :RS485通常是半双工的(同一时刻只能发或者只能收)。单片机通过串口(TTL)加上一个转换芯片(比如MAX485)来收发RS485信号。
3. 一图胜千言:总结与对比
| 电平标准 | 1 的表示 | 0 的表示 | 传输方式 | 典型距离 | 常见场景 |
|---|---|---|---|---|---|
| TTL | +3.3V/5V | 0V | 单端 (对GND) | 几十厘米 (板级) | 单片机、传感器 |
| RS232 | -3~-15V | +3~+15V | 单端 (对GND) | 十几米 | 老式电脑、工业设备 |
| RS485 | 压差+2~+6V | 压差-2~-6V | 差分 (两线) | 1200米 | 工业总线、强干扰环境 |
五.串口参数及时序

这张PPT的主题是**"串口参数及时序"** 。如果说前面的PPT是在铺路和买票,这张PPT则是告诉你**"列车的车厢长什么样,乘客(数据)怎么排队上车"**。
这是串口通信中最核心的**协议层(数据链路层)**内容,也是你未来写代码配置串口时必须要设置的参数。我们分两部分详细拆解:上半部分的"五大参数"和下半部分的"时序图"。
第一部分:五大参数详细解析
1. 波特率(Baud Rate):串口通信的速率
-
通俗解释:就是通信的"语速"。它表示每秒传输多少个bit(位)。
-
关键点 :因为串口是异步通信(没有时钟线),收发双方必须提前约定好一模一样的波特率。如果A用9600,B用115200,B就会把A的数据完全解读错(乱码)。
-
常见值:9600、19200、38400、115200等。
-
进阶提醒:波特率不仅代表速率,在硬件上它决定了每一位数据在电平线上持续的时间(比如9600波特率下,1个bit持续约104微秒)。
2. 起始位(Start Bit):标志一个数据帧的开始,固定为低电平
-
为什么需要它? 串口线平时空闲的时候,电平是高电平(1)。当发送方想发数据时,它得先"拍一拍"接收方的肩膀。怎么拍?就是把线拉低。
-
关键点 :接收方一直盯着电线,一旦检测到高电平变低电平(下降沿),就知道"有数据来了",于是开始准备接收。所以起始位必须是低电平(0)。
3. 数据位(Data Bits):数据帧的有效载荷
-
通俗解释:就是你真正想发的数据。
-
关键点(极易出错) :PPT特别强调了**"低位先行(LSB First)"**。这点极其重要!
-
假设你要发送一个字节
0x55(二进制0101 0101)。 -
串口会先发最右边的
1(D0),然后0,然后1......最后才发最左边的0(D7)。接收方收到后也会按照这个顺序重新拼装成0x55。如果你自己写软件模拟时序,搞反了就会收到完全错误的数据。
-
-
数据位长度:通常是8位(对应一个标准字节),也可以是5~9位。
4. 校验位(Parity Bit):用于数据验证,根据数据位计算得来
-
通俗解释:相当于快递上的封条,用来检查数据在传输过程中有没有被干扰产生错误。
-
常见类型:
-
奇校验(Odd):加上校验位后,数据位+校验位里"1"的总数必须是奇数。
-
偶校验(Even):加上校验位后,数据位+校验位里"1"的总数必须是偶数。
-
无校验(None):最常用的,不校验,传输效率最高。
-
-
局限性:它只能检测出"奇数个"错误,如果数据位里有两个bit同时翻车了,它是检测不出来的。只能用于简单的错误检测。
5. 停止位(Stop Bit):用于数据帧间隔,固定为高电平
-
为什么需要它? 告诉接收方"这一帧数据发完了"。同时,它也是为下一帧数据做准备。
-
关键点 :固定为高电平(1),长度可以是0.5位、1位、1.5位或2位(通常选1位)。停止位高电平,起始位低电平,刚好形成一个下降沿,完美衔接下一帧数据。
第二部分:底部时序图解析
这两个波形图展示了实际传输时的电平变化:
左图(常见模式):1帧共10位
-
结构:空闲(高) -> 1位起始位(低) -> 8位数据位(D0~D7) -> 1位停止位(高) -> 空闲(高)
-
这是最经典的 "8-N-1"模式(8位数据,无校验,1位停止位)。
-
注意看D0~D7下面的横线:LSB(最低有效位)在左,MSB(最高有效位)在右,完美图解了"低位先行"。
右图(进阶模式):1帧共11位
-
结构:空闲 -> 起始位 -> 9位数据位(D0~D7 + RB8/TB8) -> 停止位 -> 空闲。
-
这多出来的第9位是什么?它通常是校验位 ,或者是用于多单片机通信时的地址位/数据位标志(在STM32等单片机中,常常把USART配置成9位数据位来充当校验位或多机通信)。
六:串口时序波形分析及理解

1. 印证"起始位"是下降沿(S)
看每一段波形的开头,都有一个红色的 S(Start) 。
你可以清晰地看到,在 S 之前,波形处于高位(空闲)。突然垂直落下,变成低电平。这就是"下降沿"! 接收方就是靠捕捉这个下降沿来唤醒接收逻辑的。
2. 印证"数据位低位先行(LSB First)"(经典左边三幅图)
-
左上图(0x55) :0x55 的二进制是
0101 0101。但你看波形中 S 后面的 8 个位,依次是1 0 1 0 1 0 1 0。完美证明了低位(最右边的1)先发,高位(最左边的0)后发。 -
左二图(0xAA) :0xAA 的二进制是
1010 1010。波形显示 S 之后是0 1 0 1 0 1 0 1,同样是低位先行。 -
左三图(0xFF):全1,波形一直是高电平。
-
左四图(0x00):全0,波形一直是低电平。
3. 印证"停止位"是高电平(P)
看每段波形结尾的红色 P(Stop) 。
在 8 个数据位发完之后,波形被拉高,保持高电平。这就是我们说的"停止位固定为高电平",用于给这一帧数据画上句号。后面紧接着又是高电平(空闲状态)。
4. 印证"波特率"(对比左上和右上)
-
左上角 :参数是
9600。0x55 的一整帧占据了大概 1000us(1ms)。 -
右上角 :参数是
4800(波特率减半,速度变慢)。同样发 0x55,波形完全一样,但时间拉长了,一帧占据大概 2000us(2ms)。 -
结论:波特率越低,每一个 bit 在时间轴上就越宽。收发双方必须严格匹配,否则接收方会在错误的时刻去采样电平,导致错乱。
5. 印证"校验位"(右二图:0x55, 偶校验)
这个波形最直观。发送 0x55(有4个1,偶数),选择偶校验 。为了维持"1的总个数为偶数",校验位必须是 0。
你看波形:S -> 1 0 1 0 1 0 1 0(8位数据) -> C(多出来的1个bit,电平是低/0) -> P。
这正好对应了PPT里"1帧共11位"的特殊情况(8数据+1校验+起止)。
6. 印证"停止位长度"和"连续发送"(右下角两幅图)
-
右三图(连续发送0x55) :你看
P和下一个S是无缝衔接的。刚发完上一帧的停止位(高),立马拉低开启下一帧的起始位(低)。这就形成了一个新的下降沿。 -
右四图(2位停止位) :在数据位
1 0 1 0 1 0 1 0后面,你可以明显看到高电平保持了两个 bit 的时间(比上面的P宽了一倍),这就是"2位停止位"。
USART串口外设
一.USART简介

1. 身份解析:什么是USART?
"USART(Universal Synchronous/Asynchronous Receiver/Transmitter)通用同步/异步收发器"
-
拆解:
-
U (Universal):通用。
-
S (Synchronous):同步。也就是有额外的时钟线(CLK),通常我们极少用。
-
A (Asynchronous):异步。这就是我们前面讲的TX/RX两根线,没有时钟线,靠波特率约定。
-
R/T (Receiver/Transmitter):接收器/发送器。
-
-
重点:日常口语中,我们经常把USART和UART混着叫。UART(少了S)只能异步。STM32内的外设全称是USART,因为它既支持异步(常用),又支持同步。
2. 核心机制:硬件外设的魔力
"USART是STM32内部集成的硬件外设,可根据数据寄存器的一个字节数据自动生成数据帧时序,从TX引脚发送出去,也可自动接收RX引脚的数据帧时序,拼接为一个字节数据,存放在数据寄存器里"
-
它解释了为什么我们要用硬件外设,而不是用软件模拟。
-
发送过程(自动打包) :你只需要把想发的字符(比如
'A')丢进"数据寄存器(TDR)"。硬件电路会自动帮你加上起始位、校验位、停止位(就是我们上一张PPT看的时序),自动按照你配置的波特率,从TX引脚把高低电平"滴答滴答"地推出去。全程不需要CPU干预。 -
接收过程(自动解包):RX引脚有电平跳变,硬件电路自动检测起始位,按波特率采样8个数据位,自动剥掉停止位,拼成一个完整的字节,放进"数据寄存器(RDR)",然后告诉你(触发中断标志):"我收到数据啦,快来拿"。
3. 硬件能力:波特率发生器
"自带波特率发生器,最高达4.5Mbits/s"
-
不需要你写代码去手动计时,它内部有专门的时钟分频电路,你可以通过配置寄存器,让它生成你想要的波特率。
-
4.5Mbits/s 非常快(一般的调试波特率115200连它的零头都不到)。极速的波特率意味着可以搭配DMA(下面会讲)传输大量数据
4. 可配置性:帧格式自由定制
"可配置数据位长度(8/9)、停止位长度(0.5/1/1.5/2)... 可选校验位"
-
这完美呼应了上一张"串口参数及时序"的PPT。
-
STM32的硬件USART极其灵活,你可以通过软件配置,决定一帧数据是长什么样。比如:8位数据、1位停止、奇校验;或者9位数据、0.5位停止、无校验。完全由你说了算。
5. 进阶高级功能
"支持同步模式、硬件流控制、DMA、智能卡、IrDA、LIN"
-
硬件流控制:如果发送方发太快,接收方处理不过来怎么办?硬件流控制(RTS/CTS引脚)可以告诉对方"停一停"。
-
DMA(直接存储器访问) :这是初学者到进阶的关键一步! 如果串口要收几百个字节,用中断一个个收,CPU得累死。配合DMA,串口外设可以直接绕过CPU,把数据寄存器里的数据直接搬到内存数组里。CPU彻底解放,去干其他大事。
-
其他:智能卡、IrDA(红外)、LIN(汽车局域网的一种低成本协议)都是特定领域的衍生应用。
6. 具体芯片资源:STM32F103C8T6
二"STM32F103C8T6 USART资源:USART1、USART2、USART3"
-
你手上的这块经典入门神U(通常叫"蓝桥杯板"或"小蓝板"),一共提供了3个串口外设。
-
避坑重点(写代码时极易错):
-
USART1 挂在 APB2 总线(高速总线)上,最高时钟72MHz。
-
USART2 和 USART3 挂在 APB1 总线(低速总线)上,最高时钟36MHz。
-
这决定了你在计算波特率时,给它们配置的时钟源频率是不一样的!如果搞错了,写出来的波特率就会差一倍。
-
二.USART框图
1、 核心主线:数据收发的高速公路(图中部偏上)
这是整张图最关键的部分,负责**"并转串"** (发送)和**"串转并"**(接收)。
1. 发送路径(从右向左看数据流向):
-
PWDATA(顶部):CPU或DMA写入的数据。
-
发送数据寄存器(TDR) :CPU把要发的字节丢进这里。你可以把它想象成一个**"候车室"**。
-
发送移位寄存器 :TDR里的数据会被自动送到这里。它是个**"流水线"** 。它会按照你配置的波特率,把8个bit的数据加上起始位、校验位、停止位,一位一位地推送到下方的 TX引脚 上。
-
💡 硬核知识点(双缓冲) :正因为有TDR和移位寄存器分离的设计(双缓冲),所以当移位寄存器正在往TX线上一位一位推数据时,CPU可以立刻往空的TDR里写入下一个字节。这就保证了数据可以无缝连续发送 ,不会在两个字节之间产生卡顿。当TDR空了,硬件会把状态寄存器里的
TXE标志位置1,告诉CPU"候车室空了,快塞下一个数据"。
2. 接收路径(从左向右看数据流向):
-
RX引脚:数据从外部进来。
-
接收移位寄存器:它一直盯着RX引脚的电平变化,检测到起始位后,按照波特率一位一位地采样,拼成一个完整的字节。
-
接收数据寄存器(RDR) :拼好的字节会被送进RDR。你可以把它想象成**"到达大厅"**。
-
PRDATA(顶部):CPU或DMA通过总线把RDR里的数据读走。
-
💡 硬核知识点 :当RDR里收到数据后,状态寄存器里的
RXNE(接收数据寄存器非空)标志位会置1,告诉CPU"来数据了,赶紧来拿"。如果你一直不拿,下一个数据又来了,就会发生溢出错误(ORE),数据就丢了。
2、 控制大脑:三大配置寄存器(图中部偏下)
在数据主线周围,分布着 CR1、CR2、CR3(控制寄存器)。我们在代码里写的配置,最终都变成了这几个寄存器里的0和1。
-
CR1(最核心) :控制基础参数。比如
M位配置数据长度(8/9位),PCE配置校验位,TE和RE是发送/接收总开关。 -
CR2 :配置停止位长度(
STOP),以及同步模式(CLKEN,CPOL,CPHA)。 -
CR3 :配置高级功能,比如 DMA使能(
DMAT,DMAR)、硬件流控制(RTSE,CTSE)。 -
中断控制(最下方USART中断控制):CR1/CR2/CR3里的各种使能位,结合状态寄存器(SR),最终汇总到这里。一旦发生事件(如收到数据、发送完成),就会向CPU的NVIC(中断控制器)发出中断请求。
3、 节拍器:波特率发生器(图右下角虚线框)
串口是异步通信,没有时钟线,全靠波特率发生器定节拍。
-
fPCLKx :这是来自STM32内部APB总线的时钟(我们在上一张PPT讲过,USART1在APB2,USART2/3在APB1)。图中写着
÷16,说明STM32的USART硬件默认采用16倍过采样。 -
USART_BRR :波特率寄存器。它包含整数部分(
DIV_Mantissa)和小数部分(DIV_Fraction)。 -
计算公式 :波特率 =
fPCLKx / (16 * USARTDIV)。 -
生成的时钟会分别给"发送器时钟"和"接收器时钟",指挥移位寄存器什么时候推一位,什么时候采一位。
4、 外部世界:物理引脚(图左侧)
这些是你需要在开发板上用杜邦线接出去的引脚:
-
TX / RX:最常用的发送和接收引脚。
-
nRTS / nCTS :硬件流控制引脚(n代表低电平有效)。当接收方RDR满了,拉高nRTS告诉发送方"别发了,我撑死了";发送方检测到nCTS被拉高,就会暂停发送。防止数据丢失。
-
SCLK:同步模式下的时钟输出引脚(极少用)。
-
SW_RX / IrDA_OUT / IrDA_IN:智能卡(SmartCard)和红外(IrDA)功能的专用引脚。
5、 状态汇报:状态寄存器(图中下偏右的SR)
SR(Status Register)里有各种标志位:
-
TXE:发送数据寄存器空(候车室空)。 -
TC:发送完成(流水线也彻底空了,最后一个bit发完了)。 -
RXNE:接收数据寄存器非空(到达大厅有包裹)。 -
ORE:溢出错误(包裹没拿走,新包裹又来了)。 -
PE:校验错误。 -
FE:帧错误(停止位没收到高电平)。
总结:看图的正确姿势
当你以后写STM32的USART代码时,脑子里要有这张图:
-
开启时钟(给图右下角的fPCLKx供电)。
-
配置CR1/CR2/CR3(设定数据长度、停止位、校验)。
-
计算并写入BRR(设定波特率)。
-
使能TE和RE(打开收发开关)。
-
等待SR里的TXE/RXNE,或者开启对应的中断,进行数据的读写。
三:USART基本结构

1. 左侧:动力与节拍源(波特率发生器)
-
PCLK2/1:这是STM32内部总线提供的时钟源(前面讲过,USART1用PCLK2,USART2/3用PCLK1)。
-
波特率发生器:它的作用就是"降频"。总线时钟太快了(几十兆赫兹),串口用不了这么快。它把高频时钟分频,生成我们需要的"波特率节拍"(比如9600Hz、115200Hz)。
-
输出:这个节拍同时交给了"发送控制器"和"接收控制器",确保收发双方(单片机和电脑)步调一致。
2. 上方:发送流水线(CPU -> TX引脚)
-
发送控制器:收到波特率节拍后,开始指挥发送。
-
发送数据寄存器(TDR)------ 候车室:CPU把要发的字节(比如0x55)写进这里。
-
发送移位寄存器 ------ 流水线 :TDR里的数据立刻被送到这里。它会在"发送控制器"的节拍下,自动加上起始位、校验位、停止位,然后一位一位地通过 GPIO(TX引脚) 推出去。
-
关键点:因为TDR(候车室)和移位寄存器(流水线)是分开的,所以当流水线在发A字节时,CPU可以马上把B字节放进候车室。这就是为什么串口能连续不断地发数据。
3. 下方:接收流水线(RX引脚 -> CPU)
-
GPIO(RX引脚) -> 接收移位寄存器 ------ 流水线:外部数据进来,移位寄存器盯着电平,按照波特率一位一位地采样,剥掉起始位和停止位,拼成一个完整的字节。
-
接收数据寄存器(RDR)------ 到达大厅 :拼好的字节被丢进RDR。此时状态寄存器的
RXNE标志位会置1。 -
接收控制器:负责监控接收过程,如果发生错误(比如校验错、帧错),它也会记录下来。
-
CPU读取 :CPU看到
RXNE标志后,直接来读取RDR,就把数据拿走了。
4. 右下角:开关控制
- 对应复杂框图里的CR1寄存器的
TE(发送使能)和RE(接收使能)。相当于整个快递站的总闸。配置好参数后,必须打开这个开关,收发控制器才会开始工作。
四.数据帧
这张图告诉你,如何通过配置寄存器,决定你的数据帧里"有效载荷"有多长。
1. 核心开关:M位
在STM32的USART控制寄存器(CR1)里,有一个 M 位:
-
9位字长(设置了M位):起始位 + 9位数据 + 停止位。此时一帧有11位(算上起止位)。
-
8位字长(未设置M位):起始位 + 8位数据 + 停止位。这是最经典的"8-N-1"模式,一帧10位。
2. 为什么会有9位?
图中标注了"可能的奇偶校验位"。在9位模式下,第8位(第9个bit)通常有两个用途:
-
当作校验位:如果你启用了校验,硬件会自动占用第9位作为校验位,真正传输的数据还是8位。
-
多机通信的地址位:在STM32的多处理器通信(Multiprocessor Communication)中,第9位用来区分这帧数据是"地址"还是"数据"。(这是进阶内容,入门先了解即可)。
3. 图中额外的彩蛋:空闲帧与断开帧
图中间有两条特殊的线:
-
空闲帧(Idle Frame):全1(高电平)。STM32可以主动发送一个空闲帧,通常用来唤醒处于睡眠状态的接收方。
-
断开帧(Break Frame):全0(低电平,包含停止位也是0)。它用于发送一个特殊的"中断"信号,比如在某些协议中用来复位接收方。

第二张图(图250):配置停止位(0.5 / 1 / 1.5 / 2)
这张图展示了当数据位选定了8位后,停止位长度不同时的时序差异。
在STM32中,停止位不是只有1位,你可以通过CR2寄存器的 STOP 位,配置成4种长度:
-
a) 1个停止位:最标准,最常用。大家平时配置的"1"就是这个。
-
b) 1.5个停止位:注意看它的高电平时间,比1位宽,比2位窄。
-
c) 2个停止位:高电平保持2个bit的时间。通常用于连接一些反应比较慢的老式外设(给他们多一点处理时间),或者提高抗干扰能力。
-
d) 0.5个停止位 :注意看,它只维持了0.5个bit的高电平,紧接着就是下一个起始位(或空闲)。0.5个停止位通常用于**智能卡(SmartCard)**模式,或者接收方为了追求极致速度,只检测半个停止位就准备接收下一帧。
五.起始位侦测

这张PPT(出自STM32参考手册的图252)是USART接收机制里最精妙、也最体现硬件设计智慧的一页。
它的核心主题是:"当RX线上出现一个下降沿时,硬件怎么判断它是真正的起始位,还是干扰噪声(毛刺)?"
结合你之前问的"起始位为什么是下降沿",这张图给出了完美答案:因为电磁干扰,单纯的下降沿不可靠,必须进行"多重采样和投票表决"。
我们来逐行拆解这张复杂的时序图:
1. 核心机制:16倍过采样(16x Oversampling)
你看图中间的"理想的采样时钟",一共有16个箭头。这意味着:在波特率设定的"1位时间"内,硬件其实以16倍速在疯狂运行。 这么做就是为了有足够的空间去"防抖"和"找中心点"。
2. 侦测过程:三步走策略
我们顺着图中的虚线往下看:
-
第一步:捕捉下降沿(检测起点)
-
接收信号线(最上方)从空闲的高电平掉到了低电平(下降沿)。
-
此时,接收状态从"空闲"进入"起始位"状态。
-
-
第二步:第一次多数表决(排除毛刺)
-
信号掉下来后,硬件不会立刻全盘接收。它会在第3、5、7个时钟周期进行第一次采样(看图中左侧的三个箭头)。
-
看最下方的"判断起始位的条件":"每3位里面至少应有2个0"。
-
为什么这样做? 如果这是一个瞬间的干扰毛刺(比如突然跳低又跳高),这三次采样里通常会有高电平。如果这三次里有两次以上是低电平(0),硬件才认为信号"确实一直处于低电平"。
-
-
第三步:第二次多数表决(确认起始位)
-
紧接着,硬件在第8、9、10个时钟周期进行第二次采样。
-
同样要求:"每3位里面至少应有2个0"。
-
如果这两轮表决(3次里至少2次为0)都通过了,硬件才在逻辑上真正认定这是一个有效起始位。
-
如果第二轮表决失败,硬件会认为刚才只是干扰,直接丢弃,重新回到"空闲"状态,等待下一次下降沿。
-
3. 终极目标:对齐"数据采样"中心点
只要你确认了起始位(在第8、9、10个时钟周期确认),后面的数据位采样就顺理成章了。
你看图中的"实际采样时钟"部分,在起始位确认后,后续的8个数据位,都会固定在第8、9、10个时钟周期进行采样。
- 为什么选第8、9、10位? 因为这正好是一位时间的中间位置(1位/2 = 第8位)。在电平正中间采样,是最稳定的,完全避开了电平跳变时可能产生的边缘抖动。
4. 图中的"X"是什么意思?
你看"实际的采样时钟"里有很多"X"。
-
那些带 X 的时钟箭头,代表硬件不采样或者采样后直接丢弃。
-
只有在第3、5、7、8、9、10这些特定节点,硬件才真正读取电平。图中还标注了
7/16和6/16,指的是如果检测不到有效的起始位,这个计时会重置。
总结与实战意义
这张图告诉你一个硬核事实:串口通信非常抗干扰。
它靠的是**"16倍频 + 多数表决(三局两胜)"**。这也是为什么你在实际工程中,哪怕旁边有电机干扰,串口偶尔还能正确收到数据的原因(因为硬件帮你把偶尔的毛刺过滤掉了)。
代码的启示:
-
波特率不能无限拔高:因为硬件要跑16倍的时钟频率去采样。如果你写115200波特率,硬件内部时钟至少需要 115200 * 16 = 1.8432 MHz 的采样时钟。波特率太高,采样就来不及,误码率会飙升。
-
拒绝软件模拟的低效:如果你用软件模拟串口,你很难实现这种"16倍采样和三取二表决"的复杂机制。所以硬件USART才是首选。
六.数据采样

这张PPT(图253)是上一张"起始位侦测"的完美续集。
如果上一张图讲的是"如何确认数据包的到来(防假起始位) ",那么这张图讲的就是"如何精确提取每一个数据位(防噪声干扰)"。
它的核心主题是:"在一个数据位的16个时钟周期里,硬件到底在什么时候读电平?怎么读才最准确?"
我们结合图上的细节,分四步拆解:
1. 核心时钟:16倍过采样
看中间的"采样时钟",编号从 1 到 16。
这再次印证了STM32的硬件USART是在以16倍于波特率的速度在运行。这意味着,哪怕你的波特率是115200,内部硬件实际上在跑 115200 × 16 = 1.8432 MHz 的时钟。位时间被切碎了,就给了硬件"腾挪"的空间。
2. 核心坐标:黄金采样点(8、9、10)
你看图中间的"数据采样"括号,罩住了第 8、9、10 这三个时钟周期。
-
为什么选这三个点?
一个数据位(16个周期)从第1个周期开始,到第16个周期结束。第8、9、10个周期,正好处于这个位的正中间 。
在通信领域,信号在边缘处最容易抖动(比如上升沿/下降沿的过冲、振铃)。避开边缘,在正中心采样,是获取稳定电平的最优解。你可以理解为:跳跳绳时,绳子打地的瞬间(边缘)看不清,但在绳子甩到最高点(中间)时看得最清楚。
3. 核心算法:三局两胜(多数表决)
在第8、9、10个周期,硬件会连续读取三次电平。
-
如果这三个点里有2个或3个 是低电平(0),硬件就判定这个数据位是 0。
-
如果这三个点里有2个或3个 是高电平(1),硬件就判定这个数据位是 1 。
这相当于自带了一个数字滤波器,哪怕第9个周期刚好来了一个瞬间毛刺,只要第8和第10个周期是对的,结果依然正确。
4. 为什么这张图叫"检测噪声的数据采样"?(看最上面的波形)
你看最上方的"接收信号线",在下降沿的地方,画了一块灰色的阴影(毛刺/噪声)。
-
如果是不懂原理的人,可能一看到下降沿就立刻开始读数据(在第1或第2个周期采样),那样绝对会读到错误的值,因为那里正好是电平振荡的区域。
-
STM32的硬件非常聪明:它知道边缘不可靠。它特意等到信号稳定下来,在第8、9、10个周期才去采样。这就完美避开了灰色阴影区域。
5. 箭头上的时间分配(7/16 和 6/16)
你看底部的箭头:
-
7/16:从第1个周期到第8个周期前(等待信号稳定)。
-
6/16:从第8个周期到第10个周期(核心采样区)。
-
7/16 :从第11个周期到第16个周期(留出时间,准备迎接下一个位的起始或停止位)。
加起来正好是 16/16,一个完整的数据位时间。
💡 总结与实战意义
这张PPT告诉你:硬件USART极其抗造。
它不仅能防"假起始位"(上张图),还能防"位内毛刺"(这张图)。
这也解释了新手常问的一个问题:
"为什么我自己用 GPIO 延时(软件模拟串口)读出来的数据经常乱码,而用硬件USART就很稳?"
答:因为软件模拟很难做到**"16倍频采样 + 第8、9、10个时钟中心点三局两胜"**这种极其苛刻的底层时序控制。MCU的CPU还要处理别的任务,稍微被中断打断一下,采样点就偏了。而硬件USART是不受CPU干预的,它的时序精度是纳秒级的。
七.波特率发生器
这张PPT的主题是**"波特率发生器"** 。如果说前几张PPT解决的是"怎么采样"的问题,这张PPT解决的就是**"怎么产生那个极其精准的16倍采样时钟"**的问题。
这是异步串口通信最底层的**"心脏起搏器"**。我们结合PPT的公式和下方的寄存器截图,分四个层次来详细拆解:
一、 核心公式解密:为什么有个"16"?
公式:波特率 = f_PCLK2/1 / (16 * DIV)
这个公式是整个波特率发生器的灵魂,我们把它拆解成三部分:
-
f_PCLK2/1:这是"原料"。也就是给USART外设供电的时钟源频率(前面讲过,USART1挂APB2,USART2/3挂APB1)。
-
16:这是"固定系数"。对应我们上一张PPT讲的"16倍过采样"。因为STM32内部是以16倍速在运行,所以要先把总线时钟除以16,得到实际的"位时间"基准。
-
DIV (USARTDIV) :这是"分频系数"。就是我们写进
USART_BRR寄存器里的值。
这个公式告诉我们:只要知道了单片机的总线时钟频率和你想用的波特率,就能反推出DIV的值。
二、 硬件寄存器解剖:如何表达小数?
看PPT下半部分的寄存器图(图25.6.3),这是最精妙的地方。
假设你的 f_PCLK 是 72MHz(STM32F103常见的USART1时钟),你想配置波特率为 115200 。
按照公式计算 DIV:
DIV = 72,000,000 / (16 * 115200) = 39.0625
你看,结果是带小数的! 而数字电路是没法直接存小数的。STM32的解决方案非常聪明:
-
位15:4
DIV_Mantissa[11:0]:12位整数部分。存储 39(二进制为 0010 0111)。 -
位3:0
DIV_Fraction[3:0]:4位小数部分 。怎么表示 0.0625?STM32规定,这4位代表的是小数部分 * 16。所以0.0625 * 16 = 1,把 1 存进这4位里。
所以,你往 USART_BRR 寄存器里写入的最终值是:
(39 << 4) | 1 = 624 | 1 = 625 (0x271)
(在HAL库中,我们只需要给参数 115200,库函数会自动帮我们算好并写入BRR)。
为什么精度这么重要?
因为串口是异步的,允许的误差通常是 ±2% 到 ±3%。如果小数部分被粗暴地舍去(比如DIV算出来是39.0625,你直接填39),那么实际波特率偏差会达到 0.0625 / 39 ≈ 0.16%。这看起来很小,但如果连续传几百个字节,累积的误差就会越来越大,最终导致采样点偏移到电平边缘,产生乱码。有了这4位小数,STM32就能极其精准地逼近你想要的波特率。
三、 注意事项解读
"注意:如果TE或RE被分别禁止,波特计数器停止计数"
这是一个低功耗设计的细节。
-
如果你不需要发送数据,把
TE(发送使能)关了,硬件就会自动停止发送器的波特率计数,不再产生多余的时钟翻转,节省一点点功耗。 -
但要注意,在配置波特率发生器(写BRR寄存器)之前,一定要确保
TE和RE是关闭的,等配置完毕,再使能它们。这是标准的安全操作流程。
四、 💥 实战避坑指南(极其重要!)
这张PPT的公式里写着 f_PCLK2/1,这是初学者最容易踩坑的地方!因为你必须去查芯片的"时钟树"。
以你的 STM32F103C8T6(PPT里提到的)为例:
-
USART1 挂在 APB2 总线上,APB2的最高频率是 72 MHz。
-
USART2 和 USART3 挂在 APB1 总线上,APB1的最高频率是 36 MHz。
当你写代码时:
-
你给 USART1 配置 115200,底层会用 72MHz 去算 DIV。
-
你给 USART2 配置 115200,底层会用 36MHz 去算 DIV。算出来的 DIV 刚好是 USART1 的一半。
如果串口助手收到的全是乱码,或者稍微长一点的字符串就出错:
-
首先检查你自己算DIV时的总线时钟频率写对没有(是不是把USART2当成72MHz去算了)。
-
其次,可以稍微降低一点波特率(比如从115200降到9600),波特率越低,容错率越高,对时钟精度的要求就越低。



