嵌入式开发这行啊,本质上就是和“通信”死磕,CPU 和传感器要通信、 MCU 和 MCU 要通信、板子和板子要通信、设备和服务器要通信、甚至你调试程序的时候,电脑和开发板都在通信。

今天这一篇,我准备把嵌入式开发里最核心、最常见、最容易在面试和项目里出现的 12 种通信协议,总结出来和大家说说。

不是为了装大佬啊,就是想让你们少走点弯路(其实这些协议不用死记硬背,关键是理解原理,知道什么时候用什么协议),毕竟头发这东西,掉了就再也长不回来了啊。

一、有线通信协议:7 种

有线通信最大的buff就是稳、抗干扰、不丢包!不管是电路板上芯片之间的短距离数据交互,还是厂区里长距离的信号传递,基本都靠有线协议兜底。是嵌入式硬件通信的核心。

1.1 UART

只要你玩过STM32、做过嵌入式调试,百分百接触过UART。我们常用的串口打印、printf调试、串口助手收发数据、蓝牙/GPS/4G模块的AT指令控制,核心全靠它。

它的本质是异步串行通信,啥意思呢?

其实翻译成大白话超简单:UART不用时钟线同步数据,收发双方提前约定好“语速(波特率)”,一位一位轮流传数据。省了一根时钟线,接线超级简单,TX接对方RX、RX接对方TX、共地就能用,是最容易上手的协议,这设计确实省了一根线,但也埋下了祸根——双方没有时钟同步,只要晶振误差、线材干扰、时钟配置有偏差,数据就会错位乱码。

UART的一帧数据由起始位(低电平)、数据位(5-9位,常用8位)、可选的校验位(奇偶校验)、停止位(高电平,1位或2位)组成,看着是不是挺简单的?

但实际项目里,光一个波特率不对齐就能折腾你半天。很多同学以为115200是个铁定的标准,其实晶振的误差、STM32的时钟配置、线材长度、旁边的电机干扰,都会让实际波特率跑偏。

UART的抗干扰能力确实弱,这是它的硬伤。所以它的主场就是板内调试、日志输出、跟一些低速模块通信,比如GPS模块、蓝牙模块、AT指令控制4G模块。你非要拿它拉着几十米的线过工业现场,那丢包率能让你哭。

很多同学学会基础串口中断就以为掌握了UART,我也是这么过来的~haha

但这只是基础入门,后续的DMA传输、空闲中断、环形缓冲区适配,以及棘手的粘包问题,才是UART调试的真正难啃的大骨头,也是项目中最耗费时间的问题。

给你们看个最基础的串口中断接收代码,就是那种“能跑但经不起推敲”的版本:

void USART1_IRQHandler(void)
{
    if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)
    {
        uint8_t data = USART_ReceiveData(USART1);
        rx_buffer[rx_index++] = data;  // 没检查溢出,没处理环形边界
    }
}

你看,连溢出判断都没有,多来几个包rx_index就飞了。但这恰恰是每个嵌入式工程师的必经之路——先写个能用的,然后被bug教育,再回来补判断、加DMA、搞环形队列。这不就是成长么?

UART定义了数据的帧格式和传输方式,通过起始位、数据位、校验位和停止位组成的帧结构,实现设备间的异步数据传输 。

在实际应用中,UART 通常搭配 RS232 物理层标准进行通信,分属通信协议栈的不同层级:UART是数据帧格式的协议规范,RS232是定义电压电平的物理层标准。简单说,UART规定“数据怎么组织”,RS232规定“信号用多高电压传输”。

1.2 RS485

既然聊了 RS232,就不能不提它的升级版 ——RS485(直接理解为RS232的工业升级版),采用差分信号传输方式,这使得它在抗电磁干扰能力很强。

与 RS232 不同,RS485 支持半双工多节点组网,在一条总线上最多可连接 128 个节点,极大地扩展了通信的范围和灵活性 。其最大通信距离可达 1200 米,在工业自动化、楼宇控制等领域,常常需要长距离传输数据并连接多个设备,RS485 的这些特性使其成为理想之选。在工业自动化生产线中,大量的传感器、执行器等设备分布在不同位置,通过 RS485 总线可以将它们连接起来,实现数据的集中采集和控制指令的下达 。

工业场景最常用的Modbus-RTU协议,底层物理载体就是RS485。简单来说,RS485负责硬件数据传输,Modbus-RTU负责规范数据格式和通信规则,让不同厂家的设备可以互联互通,广泛用于智能电表、生产线传感器、楼宇控制等场景。

使用 RS485 时,通常需要自定义上层协议,以满足具体应用的需求,这对开发的技术能力有一定要求;并且在高速率传输时,RS485 的传输距离会受到限制,其传输速率低于以太网等高速通信协议,不太适合对实时性要求极高的大数据量传输场景。

1.3 I2C

I2C是嵌入式板内通信的极简协议,总线只需要SDA数据线+SCL时钟线两根线,就能挂载一堆外设,完美解决嵌入式设备引脚资源紧张的问题。

I2C 支持多主多从的拓扑结构,每个设备都有唯一的地址,主设备通过发送设备地址来选择与之通信的从设备,实现了总线仲裁,允许多个主设备同时连接到总线上,组网超级灵活。

其传输速率相对适中,标准模式下为 100kbps,快速模式下可达 400kbps,高速模式下为 3.4Mbps,仅适用于板内短距离通信(1米以内),专门用于连接 EEPROM、RTC(实时时钟)、传感器等低速外设。在智能手表等可穿戴设备中,I2C 常被用于连接加速度计、陀螺仪等传感器,将传感器采集到的数据传输给主控芯片。

日常项目中,EEPROM存储、RTC实时时钟、温湿度传感器、陀螺仪、OLED屏幕等小型外设,基本都是用I2C和主控通信,在智能穿戴、小型物联网设备中普及率极高。但受总线负载电容限制,无法长距离传输,且为了保证信号的稳定传输,必须搭配上拉电阻增加硬件设计复杂度,完全不适合高速数据传输场景。

1.4 SPI

如果说I2C是低速省心款,那SPI就是板内高速通信的天花板。它是四线制同步串行协议,依靠MISO(主输入从输出)、MOSI(主输出从输入)、SCLK(串行时钟)和 CS(片选)四根线通信,支持全双工同时收发数据,传输速率能达到数十MHz,吊打I2C。

SPI采用主从架构,一个主控可以挂载多个从设备,每个从设备对应独立的片选线,主设备通过控制片选线来选择与之通信的从设备,时序简单、传输效率极高。

高速的特性让它专门适配板内大数据传输场景,比如Flash存储读写、显示屏刷新、高速ADC采样、智能摄像头图像数据传输等。

四根线材占用大量引脚资源,引脚紧张的小型设备根本用不了;信号抗干扰一般,仅适合板内或极短距离板间通信,不适合长距离传输。

1.5 CAN/CAN FD

在汽车电子、高端工业自动化领域,CAN总线是绝对的刚需,主打高可靠、高实时、抗干扰、容错性强。

同样采用差分信号传输,能在复杂电磁环境下稳定工作。和普通协议最大的区别是:CAN支持多主节点通信,所有设备可以主动发数据,不用主控轮询,通信效率更高;自带完善的错误检测、自动重传、故障节点隔离功能,单个设备故障不会瘫痪整个总线,安全性拉满。

我们车内的发动机控制、车身灯光、底盘、门窗等所有电子控制系统,全部靠CAN总线互联互通。

CAN FD(Flexible Data-Rate CAN)是CAN的升级版,保留了传统CAN所有的可靠性优势,大幅提升传输性能,数据段最高传输速率可达8Mbps,支持更长数据帧,完美适配汽车自动驾驶、高端工业控制的大数据、高实时的传输需求。

分享一份工程可用的STM32标准库CAN初始化代码,自带过滤器配置、自动重传:

#include "stm32f4xx.h"

void CAN_Init(void)
{
    GPIO_InitTypeDef GPIO_InitStruct;
    CAN_InitTypeDef CAN_InitStruct;
    CAN_FilterInitTypeDef CAN_FilterInitStruct;

    // 使能CAN1、GPIOA时钟
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);

    // 配置PA11(RX)、PA12(TX)复用功能
    GPIO_InitStruct.GPIO_Pin = GPIO_Pin_11 | GPIO_Pin_12;
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;
    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP;
    GPIO_Init(GPIOA, &GPIO_InitStruct);

    // 绑定CAN复用功能
    GPIO_PinAFConfig(GPIOA, GPIO_PinSource11, GPIO_AF_CAN1);
    GPIO_PinAFConfig(GPIOA, GPIO_PinSource12, GPIO_AF_CAN1);

    // CAN基础参数配置
    CAN_InitStruct.CAN_TTCM = DISABLE;  // 关闭时间触发模式
    CAN_InitStruct.CAN_ABOM = ENABLE;   // 总线关闭自动恢复
    CAN_InitStruct.CAN_AWUM = DISABLE;  // 关闭自动唤醒
    CAN_InitStruct.CAN_NART = DISABLE;  // 开启自动重传(工程必备,保障可靠性)
    CAN_InitStruct.CAN_RFLM = DISABLE;
    CAN_InitStruct.CAN_TXFP = DISABLE;
    CAN_InitStruct.CAN_Mode = CAN_Mode_Normal; // 正常工作模式
    CAN_InitStruct.CAN_SJW = CAN_SJW_1tq;
    CAN_InitStruct.CAN_BS1 = CAN_BS1_8tq;
    CAN_InitStruct.CAN_BS2 = CAN_BS2_7tq;
    CAN_InitStruct.CAN_Prescaler = 5;
    CAN_Init(CAN1, &CAN_InitStruct);

    // 配置CAN过滤器(必须配置,否则无法接收数据)
    CAN_FilterInitStruct.CAN_FilterIdHigh = 0x0000;
    CAN_FilterInitStruct.CAN_FilterIdLow = 0x0000;
    CAN_FilterInitStruct.CAN_FilterMaskIdHigh = 0x0000;
    CAN_FilterInitStruct.CAN_FilterMaskIdLow = 0x0000;
    CAN_FilterInitStruct.CAN_FilterFIFOAssignment = CAN_Filter_FIFO0;
    CAN_FilterInitStruct.CAN_FilterMode = CAN_FilterMode_IdMask;
    CAN_FilterInitStruct.CAN_FilterScale = CAN_FilterScale_32bit;
    CAN_FilterInitStruct.CAN_FilterActivation = ENABLE;
    CAN_FilterInit(&CAN_FilterInitStruct);
}

CAN/CAN FD 的硬件成本相对较高,需要专门的 CAN 控制器和收发器等硬件设备;而且其协议栈复杂度高于一般的串行协议,开发和调试的难度较大,对开发者的技术水平要求较高,一般只用于高可靠性、高实时性的工业、汽车场景。

1.6 以太网

如果需要嵌入式设备高速、远距离、大数据量联网,以太网是唯一首选,传输速率覆盖10M/100M/1000Mbps甚至更高,视频流、批量日志、海量设备数据都能轻松传输。

兼容性拉满,所有电脑、服务器、智能设备都能无缝接入,是目前嵌入式物联网、工业组网的核心通信方式。网络摄像头实时传视频、工业设备远程监控、嵌入式设备大数据上传,全部依赖以太网实现。

以太网的核心短板是功耗偏高,对于电池供电、低功耗刚需的物联网终端设备不友好;同时TCP/IP协议栈复杂,开发、移植和维护难度大,需要开发者具备扎实的网络基础。

1.7 USB

USB(Universal Serial Bus)是大家最熟悉的通信接口,最大亮点就是即插即用、支持热插拔,无需复杂配置,插上就能自动识别、建立通信,是嵌入式设备和PC交互的首选。

速率覆盖全档位:低速1.5Mbps、全速12Mbps、USB2.0高速480Mbps、USB3.0超高速5Gbps+,适配各类数据传输需求。

USB2.0原生线缆最大传输距离为5米,搭配有源中继器最大可扩展至20米。

嵌入式场景中,USB常用于设备固件升级、电脑与开发板数据互传、日志打印,还能外接U盘、键盘、打印机等外设,拓展设备功能。

缺点是协议层级多、逻辑繁琐,设备枚举、配置、传输流程复杂,开发难度远高于串口、I2C;且功耗较高,不适合超低功耗待机的物联网设备。

往期文章推荐

图解 TCP/IP协议,看图秒懂

图解 C/C++ 多线程,看图秒懂

爆肝整理!嵌入式开发必知10种调试手段

【图解】SSH(安全外壳协议)工作原理

👉 【就业避坑】C++ 就业前景全解析:为什么劝退声不断,大厂核心岗仍刚需 C++?

👉 【大厂技术栈路线】Linux C/C++ 后端开发系统学习路线

👉 【音视频】音视频流媒体高级开发核心学习路径

👉 【Qt进阶】C++ Qt 桌面 & 嵌入式开发一条龙学习攻略

👉 【内核底层】Linux 内核硬核修炼指南

👉 【面试冲刺】C/C++ 高频八股面试题 1000 题(三)

二、无线链路协议:3种

有线通信稳定但受限线材,无线协议则主打灵活、便携、免布线,完美适配智能家居、户外监测、分布式传感器等场景。下面3种是项目落地率最高的无线链路协议。

2.1 BLE(低功耗蓝牙)

BLE(Bluetooth Low Energy)是传统蓝牙的低功耗升级版,核心定位就是超低功耗、间歇性轻量通信,专门为电池供电的小型物联网设备设计。

理想空旷环境极限传输距离50米,日常家居、工业实际有效稳定距离为10~30米。

BLE物理层标称速率1Mbps,但受限于协议机制和低功耗策略,实际业务吞吐量远低于标称值,仅适合小数据包传输,像智能手环、智能灯泡、智能插座、人体传感器等设备,基本都用BLE实现设备配对、状态上报、远程控制,设备空闲时快速休眠,极大延长续航。

BLE的短板就是带宽有限,无法传输高清视频、大文件等大数据流;多设备同时连接时,通信稳定性和传输效率会明显下降,不适合高密度多节点组网场景。

2.2 ZigBee

ZigBee基于IEEE 802.15.4标准,最大的核心优势是网状自组网+自愈多跳通信,是智能家居、工业传感器集群的专用协议,可以自动发现周边设备、搭建组网,数据能通过多个节点跳转传输,突破单设备传输距离限制;如果某个节点故障离线,网络会自动重构路由,不影响整体通信,组网稳定性极强。

主打低速率、低功耗、多节点组网,传输速率250kbps,适合温湿度、门窗状态、安防探测等小数据、高频率的监测场景,可批量挂载上百个传感器节点。

缺点是传输速率极低,仅支持小数据量上报,无法承载大数据;同时不同厂商的ZigBee设备存在兼容性差异,项目落地需要重点做兼容性测试。

2.3 LoRa

LoRa(Long Range)是低功耗广域网的代表技术,主打超远传输、强穿透、低功耗,完美弥补了蓝牙、ZigBee短距离的短板。

空旷户外环境传输距离可达10-15公里,就算在城市楼宇、野外遮挡的复杂场景,也能实现数百米至数公里的稳定通信。依托扩频通信技术,抗电磁干扰能力拉满,适配各类恶劣户外、工业环境。

传输速率0.3~50kbps,速率偏低,只适合低频次、小数据包场景,比如智能水电表抄表、农田环境监测、户外设备资产定位、野外气象采集等。

缺点是传输速率极低,无法承载大数据传输;需要单独部署网关和基站,组网部署成本和运维成本相对较高。

三、物联网应用层协议:2种

MQTT、CoAP 是运行在以太网、4G、LoRa等任意链路之上的应用层通信协议,专门针对嵌入式设备算力弱、内存小、带宽有限的特点设计,是设备对接云端的核心协议。

3.1 MQTT

MQTT(Message Queuing Telemetry Transport)是目前物联网行业的“通用语言”,基于TCP/IP运行,采用发布/订阅模式,最大特点是报文极简、带宽占用极低、适配弱网环境。

它彻底解耦了设备和云端的通信关系,支持一对多消息分发、断线自动重连、遗嘱消息、QoS服务质量分级,稳定性极强。设备可以主动上报传感器数据、设备状态,云端可以下发控制指令、固件升级包,智能家居、工业物联网、智能穿戴设备上云,基本全用MQTT。

唯一不足是依赖TCP长连接,网络波动时会出现延迟、重连耗时问题;自带QoS分级有限,超高可靠性场景需要二次开发优化。

3.2 CoAP

CoAP(Constrained Application Protocol)是为算力、内存、带宽极度受限的低端物联网终端量身打造的协议,基于UDP运行,兼容HTTP语义,上手简单、改造门槛低。

报文头部极小、传输开销极低(远低于HTTP),支持组播通信和低功耗休眠机制,适配6LoWPAN、NB-IoT等窄带弱网,多用于传感器节点、低端物联网终端与网关、云端的轻量数据交互。

短板:生态成熟度远低于MQTT,开发工具、开源案例较少;基于UDP无可靠传输机制,丢包、重传、数据校验等可靠性逻辑,需要开发者在应用层自行实现。

四、协议选型与调试技巧

4.1 协议选型

唠到这,估计你们也看出来了,通信协议没有高低之分,只有适合不适合:

协议名称

传输距离

速率

功耗

适用场景

UART/RS232

短,15米以内

最高115200bps,低速稳定

低

设备调试、日志输出、低速模块AT通信(蓝牙、GPS)、板级短距交互

RS485

长,最大1200米

100米10Mbps,1200米100kbps

低

工业现场多节点组网、智能电表、生产线传感器、Modbus-RTU通信

I2C

极短,板内1米以内

100kbps~3.4Mbps

低

板载多外设互联(传感器、EEPROM、RTC、OLED屏幕)

SPI

极短,板内1米以内

高,可达数十MHz

较高

板内高速数据传输(Flash、触摸屏、高速ADC、显示屏)

CAN/CAN FD

较长,10km(低速)/40米(1Mbps)

传统CAN 1Mbps,CAN FD 8Mbps

低

汽车电子、工业自动化、高可靠、高实时性设备组网

以太网

取决于网络部署

10M/100M/1000Mbps高速

较高

嵌入式高速联网、视频传输、大数据上传、远程设备运维

USB2.0

原生5米,有源扩展最大20米

高速480Mbps

中

PC设备交互、固件升级、U盘存储、大容量数据传输

BLE低功耗蓝牙

实际10~30米,理想最大50米

物理层1Mbps,实际吞吐量偏低

极低

智能穿戴、智能家居设备配对、低功耗短距控制与数据上报

ZigBee

10~100米

250kbps

极低

智能家居传感器组网、工业低功耗多节点监测、楼宇安防

LoRa

最远15公里(空旷环境)

0.3~50kbps

极低

智能农业、远程抄表、户外环境监测、资产远距离追踪

MQTT

依托网络,无距离限制

中低,取决于网络带宽

低

物联网设备云端对接、设备远程控制、传感器数据上报

CoAP

依托网络,无距离限制

中低,UDP传输无冗余开销

极低

资源受限终端、窄带物联网、轻量化HTTP风格请求交互

比如短距离、低功耗用 BLE;远距离、低速率用 LoRa;工业现场用 RS485 或 CAN;物联网用 MQTT;高速传输用 SPI。还有一个野路子技巧:优先用现成的库,别自己手写寄存器,除非你想练手。

4.2 调试技巧

调试通信协议,我常用的三板斧:万用表、逻辑分析仪、串口助手,覆盖90%以上通信故障。

> 万用表测电平,排查接线反接、虚接、上拉电阻缺失、电源异常等硬件基础问题;

> 逻辑分析仪抓时序,校验起始/停止条件、应答信号、时钟频率、数据沿触发是否合规;

> 串口助手看原始数据,排查乱码、丢包、粘包、指令无响应等数据异常问题。

核心调试原则:先调硬件,再调软件,绝大多数新手调试翻车,都是硬件接线错误、缺少上拉电阻、电平不匹配,盲目修改代码只会白费功夫。

使用万用表时,重点关注电压是否符合协议要求,以RS232为例,逻辑1电平为-3V-15V,逻辑0电平为+3V+15V,电平超出范围大概率是电平转换芯片损坏或电源故障。

逻辑分析仪是时序调试神器,在调试 SPI 时,可以用它查看时钟信号 SCLK 的频率是否正确,数据传输的沿(上升沿或下降沿)是否符合设备要求,以及片选信号 CS 的拉低和拉高是否与数据传输同步。通过分析这些时序,能快速定位通信错误。

串口助手则是调试 UART、RS232、RS485 等串口通信协议的必备工具。在使用串口助手时,要确保波特率、数据位、校验位、停止位等参数与设备配置一致。可以发送一些特定的数据,比如 “AT” 指令(常用于测试串口设备的通信功能),观察设备的响应,判断数据传输是否正常。

更多推荐