2、数字通信基础:同步与异步通信、串行与并行、时钟与数据线、电平标准(TTL/CMOS)、常见术语(波特率、位序、帧格式)
在深入MCU的I2C、SPI、UART接口协议之前,必须先建立数字通信的底层认知框架。无论是板级芯片间的数据交换,还是与外部传感器、存储器的交互,本质上都是在解决“如何将二进制比特流从A点可靠地传输到B点”的问题。本章将围绕通信的时序模型(同步/异步)、数据组织形式(串行/并行)、物理层信号(时钟与数据线)、电气标准(TTL/CMOS)以及核心术语(波特率、位序、帧格式)展开,为后续学习具体协议打下坚实的理论基础。
上图展示了本章的核心知识架构。数字通信的四大支柱——同步/异步模型、串行/并行结构、时钟与数据线关系、电平标准——共同决定了上层协议(I2C、SPI、UART)的工作方式。而波特率、位序、帧格式等术语则是描述这些通信过程的具体“语言”。下面我们逐一深入剖析。
2.1 同步通信与异步通信:时钟的“共享”与“约定”
核心原理
同步通信(Synchronous)和异步通信(Asynchronous)的根本区别在于时钟信号的传递方式。同步通信中,发送方和接收方共享同一时钟源,通常由主机(Master)主动产生时钟信号(如SCL、SCK),并发送给从机(Slave)。数据线上的每一位(Bit)都在时钟的上升沿或下降沿被采样,因此收发双方无需事先约定波特率,只要时钟沿清晰、稳定,数据就能准确传输。I2C和SPI都属于同步通信。
异步通信(如UART)则不传输时钟信号。收发双方必须预先约定完全相同的波特率(例如115200bps),并且通过数据帧中的起始位(Start Bit)和停止位(Stop Bit)来界定每个字节的边界。接收方利用本地时钟(通常为波特率的16倍频采样)在数据位的中间点进行采样,以避开信号跳变的不稳定区域。
判断方法
- 看连接线数量:若两根线(如SCL+SDA)或三根线(SCK+MOSI+MISO)中有一根是专用时钟线,则为同步通信;若只有一根数据线(TX/RX)且无时钟线,则为异步通信。
- 看协议帧格式:同步协议通常以“地址+数据”或“命令+数据”为传输单元,无起始位/停止位;异步协议每个字节前必有起始位(低电平),字节后必有停止位(高电平)。
- 看速率限制:同步通信速率可高达数十MHz(如SPI),异步通信受限于波特率精度和采样误差,通常不超过几Mbps。
案例拆解:MCU与温度传感器的通信选型
假设我们需要在STM32F103上挂载一个数字温度传感器(如TMP102)。该传感器同时支持I2C和SPI接口。若系统要求低功耗、仅需偶尔读取温度,且I2C总线已挂载多个其他从机,则选择I2C(同步)更合适,因为它只需两根线且支持多设备寻址。若系统要求高速连续采样(如电机控制中的温度监控),则SPI(同步)的速率优势更明显。若传感器仅提供UART接口(如某些GPS模块),则必须使用异步通信,并确保MCU的UART波特率与模块匹配(如9600或115200),否则会出现乱码。
常见误区
误区一:认为“同步一定比异步快”。实际上,同步通信的速率受限于时钟线质量、从机最大时钟频率和布线长度;异步通信在短距离、低速率下同样可靠。误区二:忽略异步通信的“空闲电平”。UART总线空闲时必须保持高电平,若误将空闲电平设为低,会导致接收方误判起始位,产生连续错误。
2.2 串行通信与并行通信:引脚数量与传输效率的权衡
核心原理
串行通信(Serial)通过一根数据线逐位发送数据,而并行通信(Parallel)通过多根数据线同时发送一个字节(如8位或16位)。并行通信的典型例子是MCU与外部SRAM或LCD屏的8080/6800接口,需要8根或16根数据线加上地址线、读写控制线。串行通信则包括UART、SPI、I2C、USB、PCIe等。串行通信虽然单次传输位数少,但引脚占用少、抗干扰能力强(无数据线间串扰)、布线简单,且可通过提高时钟频率来弥补并行传输的带宽劣势。
对比表格
| 维度 | 串行通信 | 并行通信 |
|---|---|---|
| 数据线数量 | 1根(半双工)或2根(全双工) | ≥8根(通常8/16/32) |
| 时钟频率 | 高(可达百MHz级) | 低(通常几十MHz,受限于同步偏移) |
| 引脚占用 | 少(2-4个GPIO) | 多(10-30个GPIO) |
| 抗干扰性 | 强(差分或单线,无串扰) | 弱(并行线间易串扰) |
| 典型应用 | I2C/SPI/UART/USB/PCIe | SRAM/LCD并口/FPGA配置 |
实战场景:MCU驱动TFT-LCD屏
某产品使用2.4英寸TFT-LCD(分辨率320x240,16位色)。若采用并行8080接口,需要16根数据线+5根控制线,共21个GPIO,刷新一帧(320*240*2字节=153.6KB)在10MHz总线速率下约需15ms。若改用SPI串行接口(4线制),仅需4个GPIO,但SPI时钟通常为20MHz,且每次传输8位,刷新同样一帧需要约61ms(考虑协议开销)。因此,对刷新率要求高的场景(如视频播放)应选并行接口,对引脚紧张且刷新率要求不高的场景(如静态图片显示)选SPI更合理。
总结复盘
选择串行还是并行,本质是GPIO资源、传输速率、布线复杂度、功耗之间的权衡。在MCU系统中,串行协议(I2C/SPI/UART)占据主导,因为MCU引脚有限且外设速率要求不高。并行接口仅用于高速大屏或外部存储器扩展。
2.3 时钟线与数据线:时序关系的核心
核心原理
在同步通信中,时钟线(SCL/SCK)和数据线(SDA/MOSI/MISO)的时序关系决定了数据采样的正确性。以SPI为例,主机在SCK的上升沿或下降沿将数据放到MOSI线上,从机在对应的另一个沿采样。I2C则更为严格:数据线SDA只能在SCL低电平期间变化,在SCL高电平期间必须保持稳定,否则会被误判为起始或停止条件。异步通信虽然没有时钟线,但数据线本身的电平跳变(下降沿)作为“帧起始”的参考点,接收方通过本地时钟在数据位中间采样。
关键参数
- 建立时间(Setup Time):数据必须在时钟有效沿到来之前保持稳定的最短时间。
- 保持时间(Hold Time):数据在时钟有效沿之后必须继续保持稳定的最短时间。
- 上升/下降时间:信号从低到高或从高到低跳变所需时间,过慢会导致采样点偏移。
案例拆解:I2C总线通信失败排查
某工程师调试I2C接口的EEPROM(AT24C02)时,发现写入数据后读回全为0xFF。使用示波器观察SDA和SCL波形,发现SDA在SCL高电平期间发生了跳变(即数据变化发生在时钟高电平期间),这违反了I2C协议。进一步检查发现,MCU的I2C引脚配置为开漏输出,但外部上拉电阻阻值过大(10kΩ),导致SDA线上升沿过慢(约2μs),在SCL高电平期间尚未稳定到高电平,被从机误判为停止条件。将上拉电阻改为2.2kΩ后,上升沿缩短至0.3μs,通信恢复正常。
常见误区
误区一:认为时钟线频率越高越好。实际上,过高的时钟频率会加剧信号反射和串扰,尤其在杜邦线连接时。误区二:忽略I2C的时钟延展机制。当从机慢时,它会拉低SCL迫使主机等待,若主机不支持此特性,会导致通信超时。
2.4 电平标准:TTL与CMOS的电气兼容性
核心原理
数字电路中的高电平“1”和低电平“0”并非固定电压,而是由逻辑器件(TTL或CMOS)的输入/输出阈值决定。TTL(Transistor-Transistor Logic)基于双极性晶体管,其供电电压通常为5V,输出高电平最小值VOH=2.4V,输出低电平最大值VOL=0.4V;输入高电平最小值VIH=2.0V,输入低电平最大值VIL=0.8V。CMOS(Complementary Metal-Oxide-Semiconductor)基于场效应管,其供电电压范围宽(1.8V~5.5V),输出高电平接近VCC,输出低电平接近GND,输入阈值通常为VCC/2。
兼容性判断
| 发送端/接收端 | 5V TTL | 3.3V CMOS | 5V CMOS |
|---|---|---|---|
| 5V TTL | 兼容 | 可能不兼容(TTL高电平2.4V,3.3V CMOS VIH=2.0V,可识别) | 兼容 |
| 3.3V CMOS | 不兼容(3.3V输出高电平3.3V,5V TTL VIH=2.0V,可识别,但5V TTL VOH=2.4V,3.3V CMOS VIH=2.0V,可识别) | 兼容 | 不兼容(3.3V输出无法达到5V CMOS VIH=3.5V) |
| 5V CMOS | 兼容(5V输出高电平5V,TTL VIH=2.0V) | 不兼容(5V输出高电平5V,3.3V CMOS VIH=2.0V,但3.3V器件耐压可能不足) | 兼容 |
实战场景:3.3V MCU与5V传感器接口
STM32F103的GPIO为3.3V CMOS电平,而某超声波传感器(HC-SR04)的Trig引脚要求5V高电平触发。若直接连接,3.3V高电平虽高于传感器VIH(通常2.5V),但传感器Echo引脚输出5V高电平,会超过STM32的耐压(VDD+0.3V=3.6V),可能损坏MCU。解决方案:使用电平转换电路(如MOSFET双向电平转换器)或分压电阻(将5V分压至3.3V)。对于I2C总线,则需使用专用电平转换芯片(如PCA9306)。
总结复盘
电平标准是物理层的基础,设计时必须明确MCU和外设的供电电压、IO电平类型。优先选择同电平器件;若必须混接,需使用电平转换器或开漏+上拉方案(如I2C)。
2.5 常见术语:波特率、位序、帧格式
核心原理
波特率(Baud Rate)指每秒传输的符号数(Symbols/s),在二进制编码中,1波特=1bps。但若采用多电平编码(如PAM4),波特率与比特率不同。UART中波特率即比特率,常见值有9600、115200、460800等。位序(Bit Order)指数据字节中先发送哪一位。UART通常先发送LSB(最低有效位),而SPI和I2C通常先发送MSB(最高有效位),但可通过配置寄存器改变。帧格式(Frame Format)定义了数据传输的基本单元结构,包括起始位、数据位(5-9位)、校验位(可选)、停止位(1或2位)。
帧格式详解
UART帧格式(8N1):
空闲(高) | 起始位(低) | D0 | D1 | D2 | D3 | D4 | D5 | D6 | D7 | 停止位(高)
|<-------- 8个数据位,LSB先发 -------->|
SPI帧格式(8位):
SCK上升沿采样,MSB先发:D7 D6 D5 D4 D3 D2 D1 D0
I2C帧格式:
起始条件(S) | 7位地址+读写位 | ACK | 8位数据 | ACK | ... | 停止条件(P)
案例拆解:UART波特率配置错误导致乱码
某设备使用UART与PC通信,PC端串口助手设置为115200-8-N-1,但MCU实际配置为9600-8-N-1。结果PC接收到的数据为乱码。分析:MCU发送一个字节“0x55”(二进制01010101),在9600波特率下每位持续约104μs,而PC以115200采样(每位约8.68μs),导致PC在一个实际数据位内采样到多个点,误判为多个字节。解决:将MCU的波特率寄存器值重新计算(如STM32的USART_BRR),确保实际波特率与PC一致。若使用外部晶振,还需考虑晶振误差(如8MHz晶振产生115200波特率误差为0.34%,在允许范围内)。
常见误区
误区一:混淆“波特率”和“比特率”。在FSK或QPSK等调制中,一个符号可携带多个比特,此时两者不等。误区二:忽略I2C的地址位序。I2C的7位地址在帧中占据高7位,读写位在最低位,若将地址左移一位再与读写位组合,会导致寻址错误。误区三:认为所有协议都先发LSB。实际上,SPI和I2C默认MSB先发,而UART和CAN是LSB先发,编程时需根据协议手册明确配置。