两根线,怎样传递一句话?|单片机动画课 07

课程插图

单片机已经能读按钮和电压,但它怎么告诉另一台设备“我读到了什么”?一种常见方式是 UART 串行通信:把数据拆成一个个二进制位,按约定的时间顺序发送。

本课标题的“两根线”指 TX、RX 两根信号线。普通板间 UART 还需要共同的 GND 参考,以及兼容的电平。 不是随便接两根线就能工作。

动画采用非反相逻辑电平 UART、8N1 帧格式,非仿真、非实测。位时间被大幅放慢;只讨论单字节和接收时序,不演示完整通信软件。

发送端的嘴,对着接收端的耳朵

TX 是发送,RX 是接收。A 的 TX 接 B 的 RX;反方向则是 B 的 TX 接 A 的 RX。两条方向独立,所以两端可以各自发送。

TX 连接对方 RX,两台设备共用电压参考

想象把一句话拆成小纸条逐张递出去。导线上没有整段文字移动,接收器看到的是电压随时间变化,再按双方约定把它还原成数字。

UART 的“异步”,指这里没有专门传送时钟的线,并不代表时间无所谓。发送端和接收端各自计时,需要预先约定相近的波特率和一致的帧格式。

还要分清逻辑 UART 与 RS-232 等电气接口。它们不能因为都叫串口,就把电压标准混在一起。本课只画兼容的逻辑电平连接。

一个字节,外面还有包装

常见的 8N1 表示:8 个数据位、无奇偶校验、1 个停止位。此外,每帧前面还有 1 个起始位。

字母 A 的字节从起始位到停止位依次发送

普通非反相 UART 空闲为高。开始发送时先拉低一个位时间,作为起始位;随后发送八个数据位,低位在前;最后回到高电平,形成停止位。

字母 A 的 ASCII 编码是十六进制 0x41,按平时书写顺序是二进制 01000001。但线上按最低位先发,数据部分的时间顺序为:1、0、0、0、0、0、1、0。动画中的 b0 到 b7 就是这个顺序。

起始位与停止位不是字符内容,它们帮助接收器识别边界。一个 8N1 字节实际占用十个位时间。所以在连续无间隙的理想条件下,9600 bit/s 发送八位数据,最多相当于每秒 960 个这样的字节,不能直接当作 9600 个字节。

接收器为什么会读错?

接收器检测到起始变化后,用自己的时钟估计后续各位的位置。常见做法会在位内部采样,具体还有过采样等实现细节。

双方的位时间不匹配,采样位置逐渐偏离

这张图刻意把接收器的位时间拉长。开始偏差不大,后面采样点却可能跑到相邻的数据位,甚至跑进停止位区域。结果可能是错误字节,也可能出现帧错误。

图中是说明趋势的单次取样模型,不是某颗 UART 的容差测试,也不能据此判断“差多少百分比一定失败”。真实容差与帧长、时钟误差、接收实现等有关。

在 Uno R3 的 Arduino 环境,下面两行分别负责配置速率和发送一个字节;它们是调用片段,不是完整程序:

Serial.begin(9600);  // setup() 中配置
Serial.write(0x41); // 发送字节 0x41

Serial.write(65) 发送一个数值为 65 的字节;Serial.print(65) 通常发送数字文本“65”,是两个字符。看懂这个区别,就能避免把数值、字符和显示结果混成一回事。

一个常见误区

“双方波特率一样,就一定能正常通信。”还需要帧格式、电平、接线、共同参考和软件读取都合适。若接收缓冲区满了,电气传输正常也可能丢数据。

一句话还可能包含多个字节。中文文本通常通过字符编码变成多个字节,UART 不负责理解“中文”或“英文”,它只负责按帧传送位。

看完再猜

发送 0x41 时,在线路上最先出现的是它的数据位 1 吗?

不是,先出现的是起始位 0,然后才是最低数据位 1。下一课我们再看另一种通信:多台传感器共用同一组线,单片机怎样知道该找谁?

资料:Arduino UART 说明、Microchip USART 帧格式说明。

发现更多好玩的开源项目

专注 Arduino、开源硬件、端侧 AI 和值得收藏的开发者工具。

课程插图

长按二维码关注「GitStar」

所有动画为教学原理示意,非芯片仿真、非硬件实测。网页发布:2026-09-21。