UART串口通信中起始位与停止位:不是“填参数”,而是时序锚点与容错缓冲的精密设计
你有没有遇到过这样的情况?
UART配置界面里,波特率、数据位、校验位都对得上,线也接好了,示波器上看TX波形规整漂亮,可接收端就是偶尔丢一帧、乱码、甚至直接锁死——重启后又好了。查了一整天,最后发现把停止位从1改成2,问题消失了。
这不是玄学,是起始位与停止位在真实硬件世界里发出的求救信号。
它们看起来只是帧头一个0、帧尾一个1,不传数据、不参与校验、不进FIFO,却决定了整个异步通信链路能不能稳稳地“踩准节奏”。今天我们就抛开教科书式的定义,从一块STM32开发板实际跑起来的信号开始,一层层剥开这两个“小比特”背后隐藏的工程智慧。
起始位:不是“开始标志”,而是接收器的“唤醒中断”
先看一个反直觉的事实:
UART接收器永远不知道下一帧什么时候来,但它必须在下降沿到来后的500纳秒内做出反应——否则就错过整个字节。
这听起来很苛刻,但恰恰是起始位存在的根本原因。
它到底做了什么?
- 不是“告诉对方我要发了”,发送端根本不管接收端听没听见;
- 而是给接收端一个硬性触发条件:只要RX线上出现一次干净的高→低跳变(且持续足够长),就立刻启动本地计时器,开始倒数采样点。
我们用STM32L4的USART外设为例,它的接收逻辑其实是这样工作的:
// 简化版状态机伪代码(非HAL,直击寄存器逻辑) while (1) { if (RX_PIN_FALLING_EDGE_DETECTED) { // 检测到下降沿(起始位开始) start_timer_at_0_5_bit_time(); // 在起始位中间启动首次采样定时器 enable_bit_sampling_i