很多嵌入式新手永远搞不懂串口经常遇到一个经典bug串口助手明明设置8位数据一开奇偶校验STM32最高位直接出错、乱码。大部分人一辈子都不知道原因。今天我用最简单、最直白、没有任何废话的人话彻底讲透UART串口底层原理、帧结构、校验位坑、以及STM32特殊规则。一、串口到底是怎么传数据的UART串口是串行通信。直白说数据线只有一根数据只能一位一位排队发送不是一次性发送8位。1、串口空闲状态平时不发数据时TX、RX电平永远保持高电平逻辑1。2、起始位Start Bit要发数据时先把电平拉低拉低1bit时间 起始位。作用告诉接收方我要开始发数据了请准备接收。3、数据位Data Bit随后按照波特率一位一位发送二进制数据。默认低位在前、高位在后。4、校验位Parity Bit——可选在数据位后面额外增加1位用来简单校验数据是否出错。5、停止位Stop Bit数据发送完成拉高电平保持1bit或2bit时间表示一帧结束。二、为什么串口一次接收8位很多人问为什么串口默认一次收8位不能收5位、12位吗1、真实传输过程串口线上永远是1bit、1bit慢慢挪。不是一次性发8位。2、移位寄存器串口外设内部有一个硬件移位寄存器。它的工作逻辑超级简单检测到起始位 → 开始逐位采集电平收满你设定的数据位数把一串bit拼成1个完整数据送入DR数据寄存器通知CPU读取3、通俗总结不是串口只能收8位。是你设置了8位硬件帮你攒够8位打包成1字节再交给你。你设置7位它就攒7位设置9位就攒9位。三、串口助手的8位 和 STM32的8位这是90%嵌入式工程师踩过的坑也是你之前最高位出错的根本原因。1、串口助手定义串口助手的配置数据位8位 纯有效数据校验位额外多出1位不算在8位内停止位额外多出1位举例8E18位数据、偶校验、1停止位物理线路实际传输1起始8数据1校验1停止 共11位2、STM32定义STM32的 USART 有一个特殊规定WordLength字长 包含校验位的总长度这就是所有bug的根源3、错误示范你之前踩的坑开启奇偶校验STM32仍然设置8位字长硬件解析规则8位总长度 7位数据 1位校验位结果你的最高位被硬件强行当成校验位读到的数据永远最高位错乱高位数据大量出错4、正确做法只要开启奇偶校验STM32必须设置为9位字长四、完整串口帧流程举例子发送一个字节 0x55二进制 01010101配置8N1电平变化顺序空闲高电平 → 起始位(拉低) → 0 1 0 1 0 1 0 1 → 停止位(拉高)硬件检测起始位开始同步逐位采集8个bit移位寄存器拼成1字节存入DR寄存器置位RXNE标志程序员读取DR清除标志五、常见疑问1、为什么默认都是8位因为8位 1字节是计算机最小通用单位所有协议、硬件全部适配。2、停止位算不算数据位不算。停止位纯粹用于分隔帧不保存任何有效数据。3、校验位作用是什么简单检错。防止电磁干扰导致某一位电平出错。4、Modbus为什么默认无校验因为Modbus自带CRC校验不需要硬件奇偶校验多余且浪费时间。