通信协议入门:单片机怎样把一个数字发送出去?

通信协议入门:单片机怎样把一个数字发送出去?

我们每天都在说"发送一个字节",但导线上并没有一个叫"字节"的东西在奔跑。导线上真正存在的,只是随时间变化的电压。

UART、I²C、SPI、CAN 看起来各不相同,但它们都在解决同一件事:

发送端怎样把信息变成物理信号,接收端又怎样从物理信号中还原信息。

这一篇不要求你有任何电路基础。我们只从一个数字开始,完整走完它从程序到导线、再从导线回到程序的过程。

读完以后,你应该能够回答三个问题:

  1. 数字、二进制、数据帧和电平是什么关系?
  2. 发送端和接收端必须提前约定哪些规则?
  3. 拿到一张时序图,应该从哪里开始看?

一、我们要发送的,到底是什么?

假设程序要发送字符 A

计算机不会直接保存"A 的形状",而是按照字符编码表,把它保存成一个数字。在 ASCII 编码中:

表达方式 用途
字符 A 人容易理解
十进制 65 普通数字写法
十六进制 0x41 程序和调试工具常用
二进制 0100 0001 8 个数据位

这四种写法描述的是同一个数。

需要注意的是,0x41 只有在程序按照 ASCII 解释时才代表字符 A。它也可以代表温度 65 ℃、设备状态 65,或者某条命令的参数。

导线不知道 0x41 是什么。数据的含义来自通信双方共同遵守的约定。

二、二进制的书写顺序,不等于线上的发送顺序

我们通常把 0x41 写成:

0100 0001

默认是最高位 b7 写在左边,最低位 b0 写在右边。

但是,协议真正发送时不一定从左边开始:

  • UART 通常从最低位 b0 开始发送,也就是 LSB First。
  • I²C 通常从最高位开始发送,也就是 MSB First。
  • SPI 可以由设备和控制器配置决定。
  • CAN 的字段和字节都有自己的发送规则。

所以看到一个二进制数时,不能直接认为"最左边那一位一定最先发送"。

第一条重要结论:纸面书写顺序和时间上的发送顺序是两件事。

三、为什么不能把 8 个数据位直接扔到线上?

如果发送端直接输出 8 个电平,接收端会遇到很多问题:

  • 它不知道传输什么时候开始。
  • 它不知道现在看到的是第几个比特。
  • 它不知道这一组数据什么时候结束。
  • 它不知道数据是否被干扰。
  • 它可能不知道这组数据属于哪个设备或哪类消息。

因此,通信协议通常会在有效数据前后增加控制信息,组成一个有边界的整体,这就是数据帧

不同协议采用了不同方法:

协议 怎样标记开始 怎样组织数据 怎样结束或确认
UART 起始位 数据位、可选校验位 停止位
I²C START 地址、R/W、数据 ACK/NACK、STOP
SPI 通常由 CS 选中设备 按时钟连续移位 通常由 CS 释放结束
CAN SOF ID、控制、数据、CRC ACK、EOF

数据帧通常在解决四类问题:

  1. 边界:从哪里开始,到哪里结束。
  2. 身份或含义:数据属于哪个设备或哪类消息。
  3. 长度:后面应该继续接收多少数据。
  4. 可靠性:是否需要应答、校验、CRC 或重发。

四、比特怎样变成真实导线上的电压?

数字电路会把逻辑 0 和逻辑 1 转换成不同的电压范围。

以常见的 3.3 V CMOS 信号为例:

  • 高电平通常接近 3.3 V。
  • 低电平通常接近 0 V。

但接收器并不是要求电压"必须恰好等于 3.3 V 或 0 V",而是根据芯片数据手册规定的输入阈值,把实际电压判断为高或低。

同一个逻辑帧还可以经过不同收发器,变成不同的物理信号:

  • MCU 的 UART 可以直接使用 3.3 V CMOS 电平。
  • UART 经过 RS-232 收发器后,可以变成正负电压。
  • UART 经过 RS-485 收发器后,可以变成差分电压。
  • CAN 控制器的数据经过 CAN 收发器后,变成 CAN_H 与 CAN_L 上的差分信号。

这也是为什么 UART 不等于 RS-232,也不等于 RS-485

五、理解通信时,最好把它分成三层

层次 它关心的问题 常见例子
应用含义 这个数代表字符、温度还是命令? ASCII、寄存器表、DBC 信号
协议与帧 先发什么、怎样采样、怎样确认? UART、I²C、SPI、CAN
物理信号 用什么电压、驱动方式和线缆? CMOS、RS-232、RS-485、CAN PHY

很多初学者觉得通信协议混乱,是因为把这三层混在了一起。

例如"UART 发送字符 A"实际上包含了三个步骤:

  1. 应用层决定数字 0x41 代表字符 A
  2. UART 把 0x41 放进起始位、数据位和停止位构成的帧。
  3. 输出电路把每一位转换成随时间变化的电压。

接收端则按相反方向还原。

六、接收端怎样知道现在是第几个比特?

接收器不会一次性看到一个完整字节。它只能在某些时刻读取线路电压,这个动作叫采样

同步协议和异步协议的做法不同:

  • I²C、SPI 等同步协议提供时钟线,接收端在约定的时钟边沿或电平窗口采样。
  • UART 没有独立时钟线,通信双方必须提前约定波特率,接收端发现起始位后按位时间定期采样。
  • CAN 没有单独的时钟线,但各节点通过边沿同步和位时序规则保持一致。

数据在采样点到来前必须已经稳定,并在采样点之后继续保持一小段时间,这就是:

  • 建立时间(Setup Time)
  • 保持时间(Hold Time)

如果数据正好在采样时刻变化,接收端就可能得到错误结果。

七、拿到一张时序图,应该怎么读?

不要一开始就盯着所有缩写。可以固定按照下面的顺序:

  1. 先从左向右确认时间方向。
  2. 一次只看一根信号线。
  3. 找到通信前的空闲状态。
  4. 找到第一次关键变化,也就是起始条件。
  5. 找出接收端真正采样的时刻。
  6. 在采样点读取 0 或 1。
  7. 最后再把连续比特组合成字段、字节和数据帧。

八、用一分钟检查自己是否理解

尝试不看上文回答下面的问题:

  1. 导线上直接传输的是字符 A 吗?
  2. 把二进制写成 0100 0001,是否说明一定先发送最左边的 0?
  3. 为什么通信双方必须使用相同的协议规则?
  4. UART 和 RS-232 为什么不能画等号?

参考答案

  1. 不是。导线上传输的是随时间变化的物理信号;接收端先还原数字,再按照编码解释为字符。
  2. 不是。那只是常见书写顺序,真正的发送顺序由协议和配置决定。
  3. 因为电平自身没有边界和含义,双方必须对速率、位序、帧格式和电气条件达成一致。
  4. UART 主要描述异步数据帧;RS-232 主要描述电气接口。UART 帧可以经过 RS-232 收发器传输,但两者不是同一个概念。

写在最后

学习通信协议,不应该从背缩写开始。

先问清楚:

  • 信息原本是什么?
  • 它被编码成了哪些比特?
  • 协议在比特外增加了什么规则?
  • 比特怎样变成线上的物理信号?
  • 接收端在什么时刻采样?

只要这条链路能够在脑中连起来,后面学习 UART、I²C、SPI 和 CAN,就不会再像面对几组毫无联系的术语。

相关推荐
小僧景贤2 小时前
STM32 工程文件深度解析(Keil‑MDK + STM32CubeIDE)
stm32·单片机·stm32cubeide
国科安芯3 小时前
低轨卫星姿态与轨道控制系统中高可靠MCU的选型研究——基于AS32S601的抗辐照性能试验数据分析
分布式·科技·单片机·嵌入式硬件·系统架构
小羊先生car4 小时前
RTOS-F429-HAL-Freertos内存管理(2026/8/5)
c语言·单片机·rtos
zcmodeltech6 小时前
工业生产线沙盘模型多段灯带时序控制系统设计:基于STM32与Modbus RTU的连铸-热轧-镀锌全流程联动方案
stm32·单片机·嵌入式硬件·物联网·制造·嵌入式实时数据库·多分类
小僧景贤8 小时前
STM32F407 时钟系统超详解
stm32·单片机·嵌入式硬件
西城微科方案开发8 小时前
胎压计方案开发
单片机·嵌入式硬件
国科安芯8 小时前
卫星星务计算机数据管理中SEU容错机制的技术实现研究——以AS32S601存储器ECC架构为例
网络·单片机·算法·fpga开发·架构·云计算·risc-v
JckOLF04Z8 小时前
自动开机调用迅雷下载数据库备份,完成后自动关机
数据库·单片机·嵌入式硬件
国科安芯9 小时前
卫星电推进系统阀门驱动控制中的宽温域高可靠MCU应用研究——基于AS32S601电气特性与辐照试验数据的工程分析
单片机·嵌入式硬件·fpga开发·云计算·信息与通信·卫星·抗辐射芯片