摘要:本文系统讲解嵌入式通信的基础知识,从通信的本质与历史演变出发,介绍通信的多种划分方式(传输介质、时钟同步、数据传输方向、数据位传输方式),并重点剖析 STM32 中常用的 UART/USART 通信:包括 UART 与 USART 的区别、接线方法、数据帧结构、波特率计算、相关寄存器、串口电平标准(TTL、RS232、RS485),最后总结串口乱码、数据丢失等常见问题的调试技巧,帮助读者快速掌握串口通信的实战要点。
一、什么是通信
1、我们见到的通信
通信的本质是信息的传递与交换。在人类历史上,通信方式经历了漫长的演变:
烽火台:古代边防军事通信,通过点燃烟火传递敌情信号,"烽火戏诸侯"便是利用烽火传递信息的典故。特点是传递速度快,但信息量极少,只能传递预设的简单信号。
飞鸽传书:利用信鸽的归巢本能传递书信,可携带一定文字信息,但受天气、距离和鸽子状态影响,可靠性有限。
驿站快马:通过接力方式传递公文和信件,是古代官方主要的长途通信手段。
旗语、鼓号:在近距离或战场上通过视觉、听觉信号传递指令。
这些原始通信方式的共同局限是:传输距离有限、信息量小、速度慢、易受干扰。
2、电子领域通信
在电子与计算机领域,通信指设备与设备之间进行数据的交互,即通过电信号或光信号按照一定的协议规范,在两个或多个电子设备之间传递二进制数据。
电子通信的核心要素包括:
发送端(Tx):将数据编码为电信号并发送出去的设备。
接收端(Rx):接收电信号并解码还原为数据的设备。
传输介质:信号传播的载体,如导线(有线)、空气(无线)、光纤等。
通信协议:收发双方约定的数据格式、时序规则和纠错机制,确保数据能被正确理解。
与传统通信相比,电子通信具有速度快、容量大、抗干扰能力强、可长距离传输等优势,是现代嵌入式系统、计算机网络和物联网的基础。
二、通信的划分
通信可以从不同维度进行分类,以下是嵌入式领域最常见的几种划分方式:
1、按传输介质划分
无线通信:利用电磁波在空气中传播信号,无需物理连线。
常见方式:Wi-Fi、蓝牙(Bluetooth)、星闪、ZigBee、LoRa、NB-IoT(窄带宽物联)、4G/5G、GPRS 2G 等。
优点:部署灵活、移动性强、无需布线。
缺点:易受干扰、安全性相对较低、功耗较高。
有线通信:通过物理导线(如铜线、光纤)传输信号。
常见方式:UART、SPI、I2C、USB、以太网(Ethernet)、CAN 等。
优点:传输稳定、抗干扰能力强、安全性高、速度快。
缺点:需要物理布线、移动性差、设备间距离受线缆限制。
2、按时钟同步方式划分
同步通信:收发双方共用同一时钟信号,数据在时钟节拍下同步传输。
特点:需要额外的时钟线(SCK/CLK),数据传输效率高,适合高速大批量数据传输。
典型协议:SPI、I2S。
同步通信优点:安全、快。
缺点:占用 IO 资源多。
异步通信:收发双方不共用时钟,各自使用独立的本地时钟,通过约定的波特率和数据帧格式来同步。
特点:无需时钟线,只需两根数据线(TX/RX)即可通信;通过起始位和停止位标识数据帧的开始和结束。
缺点:每个字节都需要额外的起始位和停止位,传输效率相对较低。
典型协议:UART。
优点:占用 IO 资源少。
缺点:慢、丢包率高。
3、按数据传输方向划分
模式 | 定义 | 特点 | 典型示例 |
|---|---|---|---|
单工 | 数据只能沿一个方向传输,发送端只能发送,接收端只能接收。 | 方向固定,不可反向。 | 广播、电视、遥控器发射 |
半双工 | 数据可以双向传输,但同一时刻只能沿一个方向传输,收发不能同时进行。 | 需要切换收发方向,存在切换延迟。 | 对讲机、I2C、SPI(单条数据线时) |
全双工 | 数据可以同时双向传输,发送和接收互不影响。 | 需要独立的发送和接收通道,效率最高。 | UART、电话、以太网 |
4、按数据位传输方式划分
串行通信:数据按位(bit)依次在一条数据线上传输,每次只传一位。
优点:占用引脚少(通常只需 TX、RX 两根线),布线简单,适合长距离传输。
缺点:传输速度相对较低(相对于并行)。
典型协议:UART、SPI、I2C、USB、CAN。
并行通信:数据的多个位同时在多条数据线上传输,一次可传输多个 bit。
优点:传输速度快,一次可传输 8/16/32 位数据。
缺点:占用引脚多,布线复杂,信号线间存在串扰,不适合长距离和高速场景。
典型示例:传统打印机并口、IDE 接口、STM32 FSMC 外部存储器接口。
在现代嵌入式系统中,串行通信已成为主流。随着芯片工艺和信号处理技术的进步,串行通信的速度已大幅提升(如 USB 3.0、PCIe),且引脚少、抗干扰强的优势更加突出。
三、STM32中的通信
STM32 系列微控制器集成了丰富的通信外设,能够满足各种嵌入式应用场景的通信需求。以下是 STM32 中常见的通信外设及其特点:
通信外设 | 通信方式 | 同步/异步 | duplex | 典型应用场景 |
|---|---|---|---|---|
UART / USART | 串行、有线 | 异步(UART)/ 同步+异步(USART) | 全双工 | 串口调试、GPS 模块、蓝牙模块、Wi-Fi 模块、与 PC 通信 |
SPI | 串行、有线 | 同步 | 全双工 | Flash 存储、OLED/LCD 显示屏、ADC/DAC、SD 卡、NRF24L01 |
I2C | 串行、有线 | 同步 | 半双工 | 传感器(温湿度、加速度)、EEPROM、RTC 时钟、OLED 屏 |
CAN | 串行、有线 | 异步 | 半双工 | 汽车电子、工业控制、多机通信网络 |
USB | 串行、有线 | 异步 | 全双工 | 虚拟串口(VCP)、USB 主机/设备、HID 设备、U盘 |
Ethernet | 串行、有线 | 异步 | 全双工 | 网络通信、物联网网关、远程控制 |
485 | 串行、有线 | 异步 |
各通信方式的选择建议
调试与简单数据传输:优先选择 UART,使用简单、工具成熟,几乎所有开发板都引出串口。
高速短距离板内通信:选择 SPI,速度快(可达几十 MHz),适合与高速外设(Flash、显示屏)通信。
多设备、低速、少引脚:选择 I2C,只需两根线(SCL/SDA)即可挂载多个从设备,适合传感器网络。
多机长距离、高可靠性:选择 CAN,支持差分信号传输,抗干扰能力强,最远可达数公里。
与 PC 高速通信:选择 USB,可虚拟为串口(CDC)或使用自定义协议,速度远高于普通串口。
STM32 不同型号的通信外设数量和种类有所差异。例如 F1 系列通常有 3 个 USART + 2 个 SPI + 2 个 I2C + 1 个 USB;F4 系列则有 6 个 UART/USART + 3 个 SPI + 3 个 I2C + 2 个 CAN + USB OTG 等。使用时需查阅对应型号的数据手册。
四、UART和USART
1、是什么
UART(Universal Asynchronous Receiver/Transmitter,通用异步收发器)是一种通用的串行异步通信协议,也是嵌入式系统中最常用、最基础的通信方式之一。它将并行数据转换为串行数据发送出去,同时将接收到的串行数据转换为并行数据。
USART(Universal Synchronous/Asynchronous Receiver/Transmitter,通用同步异步收发器)是 UART 的增强版,在支持异步通信的基础上,额外支持同步通信模式(提供时钟输出引脚 SCLK)。
在 STM32 中,USART 可以工作在异步模式(此时功能等同于 UART),也可以工作在同步模式。而 UART 外设仅支持异步模式。
2、UART 和 USART 的区别
对比项 | UART | USART |
|---|---|---|
全称 | 通用异步收发器 | 通用同步异步收发器 |
同步模式 | 不支持 | 支持(提供 SCLK 时钟引脚) |
异步模式 | 支持 | 支持 |
引脚数量 | TX、RX(最少 2 根) | TX、RX、SCLK(同步模式需 3 根) |
时钟源 | 收发双方各自独立时钟 | 异步模式同 UART;同步模式由主机提供时钟 |
在实际开发中,绝大多数场景使用的都是异步模式,此时 USART 和 UART 的用法完全相同。STM32 的 USART 外设默认工作在异步模式,因此教程中常说的"串口"通常指的就是 USART 的异步模式。
3、UART 接线
UART 通信最基本的连接需要三根线:
TX(Transmit,发送端):数据发送引脚,设备 A 的 TX 连接设备 B 的 RX。
RX(Receive,接收端):数据接收引脚,设备 A 的 RX 连接设备 B 的 TX。
GND(Ground,地线):共地,确保双方电平参考一致,这是通信稳定的必要条件。
接线原则:TX 接 RX,RX 接 TX,GND 接 GND(交叉连接)。
设备 A 设备 B
┌─────────┐ ┌─────────┐
│ TX │───▶ │ RX │
│ RX │◀─── │ TX │
│ GND │──── │ GND │
└─────────┘ └─────────┘
注意事项:
如果只需要单向传输(如只发送不接收),可以只接 TX-RX 和 GND 两根线。
部分 UART 还支持硬件流控引脚 RTS(请求发送)和 CTS(清除发送),用于防止数据溢出,但一般场景不使用。
必须确保双方电平一致(如都是 3.3V TTL 电平),否则需要电平转换芯片(如 MAX3232 转 RS232,或 CH340/CP2102 转 USB)。
4、UART 通信协议
UART 异步通信以数据帧(Frame)为单位传输,每一帧包含以下部分:
(1)数据帧结构
空闲位(Idle):总线空闲时保持高电平。
起始位(Start Bit):1 位,由高电平拉低为低电平,表示一帧数据的开始。接收端检测到下降沿后开始接收数据。
数据位(Data Bits):5~9 位,通常为 8 位(1 字节)。低位在前(LSB First),高位在后(MSB Last)。
校验位(Parity Bit):可选,0 或 1 位。用于数据校验,可选择奇校验(Odd)、偶校验(Even)或无校验(None)。
停止位(Stop Bit):1 位、1.5 位或 2 位,高电平,表示一帧数据的结束。
(2)波特率(Baud Rate)
波特率表示每秒传输的二进制位数,单位是 bps(bit per second)。常见的波特率有:9600、19200、38400、57600、115200 等。
收发双方必须设置相同的波特率,否则会因时钟偏差导致数据错乱。
以最常用的8N1 格式(8 位数据位、无校验、1 位停止位)和 115200 波特率为例:
每帧实际传输位数 = 1(起始)+ 8(数据)+ 1(停止)= 10 位(面试会问)。
每秒可传输字节数 = 115200 / 10 = 11520 字节/秒。
(3)常见配置组合
配置 | 含义 | 使用场景 |
|---|---|---|
8N1 | 8 数据位、无校验、1 停止位 | 最常用,绝大多数场景默认配置 |
8E1 | 8 数据位、偶校验、1 停止位 | 需要数据校验的工业场景 |
8O1 | 8 数据位、奇校验、1 停止位 | 需要数据校验的工业场景 |
8N2 | 8 数据位、无校验、2 停止位 | 部分老设备或对可靠性要求高的场景 |
5、UART 框图
STM32 USART 外设的内部结构主要包含以下几个部分:
各部分功能说明:
发送数据寄存器(TDR / DR):CPU 将待发送的数据写入该寄存器,数据会自动转移到发送移位寄存器。
发送移位寄存器(TX Shift Register):将并行数据按位串行化,在波特率时钟驱动下从 TX 引脚逐位发送出去。
接收移位寄存器(RX Shift Register):从 RX 引脚逐位接收串行数据,组装成并行数据后转移到接收数据寄存器。
接收数据寄存器(RDR / DR):存放接收到的完整数据,CPU 从该寄存器读取数据。
波特率发生器(Baud Rate Generator):根据 BRR 寄存器的配置,对系统时钟分频,产生收发所需的波特率时钟。
控制寄存器(CR1/CR2/CR3):配置 USART 的工作模式、数据位、校验位、停止位、中断使能等。
状态寄存器(SR):反映 USART 当前的工作状态,如发送寄存器空(TXE)、发送完成(TC)、接收寄存器非空(RXNE)、溢出错误(ORE)等。
6、UART 相关寄存器
以 STM32F1 系列为例,USART 主要涉及以下寄存器(基地址因 USART 编号不同而异):
寄存器 | 全称 | 主要功能 |
|---|---|---|
USART_SR | 状态寄存器 | 反映 TXE、TC、RXNE、IDLE、ORE、FE、NE、PE 等状态标志位 |
USART_DR | 数据寄存器 | 低 9 位有效,写入即发送,读取即接收(TDR 和 RDR 共用同一地址) |
USART_BRR | 波特率寄存器 | 设置波特率分频值,高 12 位为 DIV_Mantissa,低 4 位为 DIV_Fraction |
USART_CR1 | 控制寄存器 1 | UE(USART 使能)、M(数据位长度)、PCE(校验使能)、PS(校验选择)、TXEIE/TCIE/RXNEIE(中断使能)、TE/RE(发送/接收使能) |
USART_CR2 | 控制寄存器 2 | STOP(停止位位数)、LINEN、CLKEN(同步模式时钟使能)、CPOL/CPHA(同步时钟极性/相位) |
USART_CR3 | 控制寄存器 3 | CTSE/RTSE(硬件流控使能)、DMAT/DMAR(DMA 发送/接收使能)、IREN(红外模式)、EIE(错误中断使能) |
USART_GTPR | 保护时间和分频寄存器 | 智能卡模式下的保护时间和红外分频 |
常用状态位说明(USART_SR)
TXE(位 7):发送数据寄存器空。当 TDR 中的数据已转移到移位寄存器时置 1,表示可以写入下一个数据。写入 DR 后硬件自动清零。
TC(位 6):发送完成。当一帧数据(包括停止位)完全从 TX 引脚发送出去,且 TXE=1 时置 1。需要软件清零(先读 SR,再写 DR)。
RXNE(位 5):接收数据寄存器非空。当移位寄存器中的数据已转移到 RDR 时置 1,表示有数据可读。读取 DR 后硬件自动清零。
IDLE(位 4):检测到空闲总线。当 RX 引脚持续一帧时间为高电平时置 1,常用于判断一帧数据接收结束。需软件序列清零(读 SR 再读 DR)。
ORE(位 3):溢出错误。当 RDR 中已有数据未读,又接收到新数据时置 1,表示数据丢失。
FE(位 1):帧错误。检测到无效的停止位时置 1。
PE(位 0):校验错误。接收到的数据校验位不匹配时置 1。
波特率计算(USART_BRR)
波特率分频值计算公式:
$$\text{USARTDIV} = \frac{f_{CK}}{16 \times \text{BaudRate}$$
其中 f$${}_{CK$$ 为 USART 的时钟频率(APB1 或 APB2 总线时钟)。
例如:USART1 挂在 APB2 上,f$${}_{CK$$ = 72MHz,目标波特率 115200:
$$\text{USARTDIV} = \frac{72000000}{16 \times 115200} = \frac{72000000}{1843200} \approx 39.062$$
DIV_Mantissa = 39(整数部分)
DIV_Fraction = 0.0625 × 16 = 1(小数部分 × 16 取整)
USART_BRR = (39 << 4) | 1 = 0x271
7、串口电平标准
UART 本身只定义了通信协议(数据帧格式、时序),但没有规定物理电平标准。在实际应用中,常见的串口电平标准有以下三种:
电平标准 | 逻辑1(高电平) | 逻辑0(低电平) | 信号类型 | 典型距离 | 应用场景 |
|---|---|---|---|---|---|
TTL | 3.3V 或 5V | 0V | 单端、正逻辑 | 板内 / 短距离(<1m) | MCU 引脚直接输出、开发板串口 |
RS232 | -3V ~ -15V(通常 -12V) | +3V ~ +15V(通常 +12V) | 单端、负逻辑 | 约 15m | 老式 PC 串口、工业设备 |
RS485 | A-B > +200mV | A-B < -200mV | 差分(A/B 双线) | 最远 1200m | 工业现场总线、多机通信、Modbus |
(1)TTL 电平
TTL 电平是 MCU 引脚直接输出的电平,STM32 的 IO 口通常为 3.3V TTL 电平(部分引脚兼容 5V 输入)。逻辑上高电平代表 1,低电平代表 0,是最常见的板内通信电平。
3.3V TTL 和 5V TTL 设备互连时需要注意:3.3V 设备的 TX 接 5V 设备的 RX 通常没问题(3.3V 可被识别为高电平),但 5V 设备的 TX 接 3.3V 设备的 RX 可能会烧坏 3.3V 引脚,需要电平转换或分压。
(2)RS232 电平
RS232 是传统的串行通信标准,使用 ±12V 电压,且逻辑是反转的:负电压代表逻辑 1,正电压代表逻辑 0。这与 TTL 电平完全不同,因此 TTL 设备与 RS232 设备通信时必须使用电平转换芯片。
常用的 TTL 转 RS232 芯片:MAX3232(3.3V 供电)、MAX232(5V 供电)。
(3)RS485 电平
RS485 使用差分信号(A 线和 B 线),通过两根线之间的电压差来表示逻辑 0 和 1,具有很强的抗干扰能力,支持长距离传输和多设备挂载(一条总线上最多可挂 32 个设备)。
STM32 的 UART 本身不直接输出 RS485 电平,需要外接SP3485、MAX485等收发芯片,并通过一个 GPIO 控制收发方向(DE/RE 引脚)。
(4)常见电平转换方案
转换方向 | 常用芯片/模块 | 说明 |
|---|---|---|
TTL ↔ USB | CH340、CP2102、PL2303、FT232 | 最常用,开发板通过 USB 连接电脑串口助手 |
TTL ↔ RS232 | MAX3232、MAX232 | 连接老式 PC 串口或 RS232 设备 |
TTL ↔ RS485 | MAX485、SP3485 | 工业现场总线、长距离通信 |
8、常见问题与调试技巧
(1)串口乱码
串口乱码是最常见的问题,表现为接收到的字符全是看不懂的符号。按以下顺序排查:
波特率不匹配:确认发送端和接收端的波特率设置完全一致(如都是 115200)。这是乱码最常见的原因。
时钟配置错误:STM32 的波特率由系统时钟分频得到,如果系统时钟(HSE/PLL)配置不正确,实际波特率会偏离设定值。检查 SystemClock_Config() 配置。
电平不匹配:确认双方使用相同的电平标准(都是 TTL 或经过正确的电平转换)。3.3V TTL 直接接 RS232 一定会乱码。
接线错误:确认 TX 接 RX、RX 接 TX(交叉连接),GND 必须共地。TX 接 TX、RX 接 RX 会导致完全收不到数据或乱码。
数据格式不匹配:确认数据位、校验位、停止位设置一致(如都是 8N1)。
(2)数据丢失或接收不完整
溢出错误(ORE):当接收数据寄存器(RDR)中的数据还没被读取,新的数据又接收到了,就会触发溢出错误,导致新数据丢失。查询方式下如果 CPU 处理其他任务时间过长,来不及读取 DR,就会出现这个问题。
解决方法:在读取 DR 前检查 ORE 标志位,如果 ORE=1,先读 SR 再读 DR 来清除该标志;或者提高读取频率,避免数据积压。
uint8_t USART1_ReceiveByte(void) { // 等待接收数据寄存器非空 while (!(USART1->SR & USART_SR_RXNE)); // 检查溢出错误(可选) if (USART1->SR & USART_SR_ORE) { // 读 SR 再读 DR 清除 ORE 标志 (void)USART1->SR; (void)USART1->DR; } return (uint8_t)(USART1->DR); }(3)第一个字节发送丢失
在初始化 USART 后立即发送第一个字节,有时会出现第一个字节丢失的现象。原因是 USART 使能(UE=1)后,发送器需要一个时间来完成初始化,如果在 TE 置位后立即写 DR,第一个字节可能不会被正确发送。
解决方法:初始化后等待 TC 标志位置 1,或者在发送第一个字节前加一个短暂延时。
void USART1_Init(void) { // ... 其他初始化代码 ... USART1->CR1 |= USART_CR1_UE; // 使能 USART // 等待发送器就绪(TC=1 表示发送完成,空闲状态) while (!(USART1->SR & USART_SR_TC)); }(4)串口助手使用要点
端口选择:在设备管理器中确认 USB 转串口模块对应的 COM 口号。
波特率设置:必须与开发板程序中的波特率一致。
发送模式:ASCII 模式发送文本字符;HEX 模式发送十六进制原始数据(适合发送二进制协议数据)。
行结束符:发送时可选择追加 "\r\n"(回车换行),方便接收端按行解析。
时间戳和显示模式:调试时建议开启 HEX 显示,可以直观看到每个字节的原始值,方便判断是乱码还是协议数据。
(5)硬件调试技巧
万用表测电平:空闲状态下 TX 引脚应为高电平(3.3V),如果一直是低电平,可能是引脚配置错误或硬件损坏。
LED 指示:在 TX 或 RX 线上串联 LED 和电阻,发送/接收数据时 LED 会闪烁,可直观判断是否有数据传输。
回环测试:将开发板的 TX 和 RX 直接短接,发送什么就应该收到什么,可快速判断串口本身是否正常工作。
五、总结
本文围绕嵌入式通信,特别是 STM32 中的 UART/USART 串口通信,系统梳理了从基础概念到实战调试的完整知识链路,核心要点如下:
通信分类:通信可按传输介质(有线/无线)、时钟同步方式(同步/异步)、数据传输方向(单工/半双工/全双工)以及数据位传输方式(串行/并行)等多个维度划分,其中串行通信凭借引脚少、抗干扰强的优势已成为现代嵌入式系统的主流。
UART 与 USART 的区别:UART 仅支持异步通信,而 USART 在异步基础上额外支持同步模式(提供 SCLK 时钟引脚)。实际开发中绝大多数场景使用异步模式,此时两者用法完全相同。
通信协议要点:UART 以数据帧为单位传输,包含起始位、数据位、校验位和停止位;收发双方必须设置相同的波特率(如 115200)和数据格式(如 8N1),否则会导致数据错乱。
电平标准:常见串口电平标准有 TTL(3.3V/5V 正逻辑)、RS232(±12V 负逻辑)和 RS485(差分信号),不同电平之间互连必须使用对应的转换芯片(如 MAX3232、MAX485、CH340 等)。
调试技巧:串口乱码、数据丢失、第一个字节发送丢失等问题,通常与波特率、时钟配置、电平匹配、接线方式和数据格式有关,可通过回环测试、万用表测电平、LED 指示等方法快速定位。
六、参考资料
以下资料可帮助读者进一步深入学习 STM32 串口通信与嵌入式开发:
STM32 参考手册(Reference Manual):以 STM32F1 系列为例,可查阅 RM0008《STM32F101xx、STM32F102xx、STM32F103xx、STM32F105xx 和 STM32F107xx 高级 ARM-based 32 位 MCU 参考手册》,其中 USART 章节详细介绍了寄存器、数据帧结构和波特率计算。
STM32 数据手册(Datasheet):对应型号的数据手册(如 STM32F103C8T6 数据手册)包含引脚定义、电气特性和通信外设资源分配,是硬件设计和接线的重要依据。
串口调试工具:推荐使用 XCOM、SSCOM、PuTTY 等串口调试助手,支持 ASCII/HEX 收发、时间戳显示和自动发送,便于调试和验证串口通信。
官方与社区教程:可参考 ST 官方文档与例程(STM32Cube 固件包中的 UART/USART 示例),以及 CSDN、正点原子、野火等社区发布的 STM32 串口通信实战教程,结合实际项目加深理解。