免费获取学习方案
ARTICLE DETAIL

资讯详情

深耕编程基础知识与建站技术分享的一线实战洞察。

第321篇 嵌入式通信协议SPI/I2C/UART/CAN

第321篇 嵌入式通信协议SPI/I2C/UART/CAN 上篇聊了嵌入式C编程的实践。这篇聊嵌入式中最常用的四种通信协议——SPI、I2C、UART和CAN。做机器人开发传感器数据采集、电机控制、调试日志全都离不开这些总线。面试中这几类协议的对比是高频题。UART最朴素的串行通信UARTUniversal Asynchronous Receiver/Transmitter是最简单的点对点通信协议。两根线TX和RX不需要时钟线靠预设的波特率同步数据。UART的帧格式起始位1位低电平→ 数据位5-9位通常8位→ 校验位可选→ 停止位1-2位高电平。没有时钟线意味着双方必须约定相同的波特率——常见的有9600、115200、921600。波特率误差要控制在2%以内否则接收端会采样错误。UART的优点是简单、通用几乎所有MCU都有。缺点是点对点、速度有限通常不超过几Mbps、没有硬件流控时可能丢数据。在机器人中UART最常见的用途是调试串口打印日志和GPS模块、蓝牙模块等低速外设通信。实际项目中UART有几个常见的坑第一DMA接收是必须的。如果用中断逐字节接收高波特率下CPU会被中断淹没。用DMA空闲中断IDLE interrupt检测一帧数据接收完毕是标准做法。第二数据对齐。如果发送端和接收端波特率不匹配长时间运行后会累积误差导致乱码。解决方案是用硬件自动波特率检测STM32的Auto Baud Rate功能。第三RS485。长距离UART通信要用RS485差分信号需要控制收发方向DE/RE引脚在软件中要处理好方向切换的时序。SPI高速全双工SPISerial Peripheral Interface是同步、全双工的通信协议。四根线SCK时钟、MOSI主出从入、MISO主入从出、CS片选。SPI的工作方式很简单主机产生时钟信号每个时钟周期MOSI发送一位、MISO同时接收一位。数据像移位寄存器一样交换——主机发送的同时也在接收。SPI的速度可以很快常见的有10MHz、20MHz甚至80MHz。在机器人中SPI常用于高速传感器IMU、激光雷达前端和Flash存储器。SPI的变体需要注意Mode 0-3CPOL和CPHA的组合决定时钟极性和采样相位、MSB/LSB优先。配置SPI时必须确保主机和从机的Mode一致否则数据会错位。多从机有两种接法每个从机单独一根CS线标准方式或者所有从机串接成移位寄存器链daisy-chain。后者节省IO口但延迟更大。SPI的高速传输离不开DMA。手动用CPU逐字节传输在20MHz以上时钟下效率极低。用DMASPI可以实现零CPU开销的块传输——配置DMA源地址、目标地址、传输长度启动后DMA自动搬运数据。双缓冲double buffer模式可以让DMA传输和CPU处理并行DMA往Buffer A写数据时CPU处理Buffer B的旧数据。I2C省线的多设备总线I2CInter-Integrated Circuit只需要两根线SCL时钟和SDA数据支持多主多从。每个从机有7位或10位的地址主机通过地址选择通信对象。I2C的通信过程主机发START条件 → 发7位地址1位读写方向 → 从机ACK → 传输数据 → 每个字节后跟ACK → 主机发STOP条件。I2C的速度分三档标准模式100kHz、快速模式400kHz、高速模式3.4MHz。实际项目中400kHz最常用。I2C的关键细节开漏输出上拉电阻。SDA和SCL都是开漏的需要外接上拉电阻通常4.7kΩ。上拉电阻的大小影响通信速度——电阻太大上升沿慢太小电流大。时钟拉伸clock stretching。从机可以拉低SCL来让主机等待这在从机处理较慢时很有用但有些主机不支持这个特性。总线冲突。多主设备同时通信时需要仲裁arbitrationI2C通过线与逻辑自动仲裁——发出高电平但检测到低电平的主机退出。I2C在机器人中常用于低速传感器温湿度、气压、磁力计和EEPROM。它的优势是省IO口一个总线上可以挂几十个设备。实际使用I2C时最常见的故障是总线死锁——从机拉低SDA不释放通常发生在通信中途主机复位。解决方法主机手动发送9个SCK时钟脉冲让从机释放SDA。更稳妥的做法是在驱动中加入总线恢复逻辑。另外I2C的地址冲突也要注意——不同厂家的传感器可能使用相同的7位地址挂在同一条总线上会冲突这时需要用I2C多路复用器比如TCA9548A来隔离。CAN工业级可靠通信CANController Area Network是汽车和工业领域最常用的通信协议。两根差分线CAN_H和CAN_L抗干扰能力极强。CAN的核心特性消息寻址。不是地址寻址而是每个消息有一个标识符ID接收方通过ID过滤决定是否接收。这跟I2C的地址寻址完全不同。非破坏性仲裁。多个节点同时发送时ID值最小的优先发送其他节点自动退出不会破坏数据。硬件CRC校验。每个CAN帧都有15位CRC接收端硬件自动校验错误帧自动重发。差分信号。CAN_H和CAN_L的电压差表示逻辑状态抗共模干扰能力强可以走几十米的线缆。CAN的数据速率经典CAN最高1Mbps总线长度不超过40米CAN FD最高8Mbps数据段最大64字节。在机器人中CAN常用于电机驱动器通信比如ODrive、Moteus和多关节协调控制。CAN总线的物理层也值得了解。CAN收发器比如TJA1050把MCU的TX/RX信号转换为差分信号。总线两端各需一个120Ω终端电阻匹配线缆阻抗防止信号反射。如果忘记加终端电阻通信会在高波特率下出错。总线上节点越多每个节点的输入阻抗并联后越低所以有最大节点数的限制经典CAN约110个节点。四种协议的对比面试中经常让你对比这四种协议。核心维度维度UARTSPII2CCAN线数2(TX/RX)4CS2(SCL/SDA)2(差分)速率~1Mbps~80MHz~3.4MHz~8Mbps(FD)双工全双工全双工半双工半双工多设备不支持需多CS地址寻址消息仲裁距离短短短长(差分)可靠性低中中高(CRC重发)选择原则短距离高速用SPI短距离多设备省IO用I2C长距离高可靠用CAN简单调试用UART。面试要点SPI的四种模式。CPOL决定时钟空闲状态0低1高CPHA决定采样边沿0第一边沿1第二边沿。Mode 0最常用空闲低电平第一边沿采样。面试时能画时序图说明CPOL和CPHA的含义基本就过关了。I2C的START和STOP条件。STARTSCL高电平期间SDA从高到低。STOPSCL高电平期间SDA从低到高。这两个条件不传输数据只用于标记通信的开始和结束。CAN的CSMA/CDAMP。载波监听多路访问/碰撞检测仲裁按消息优先级。这个机制保证了高优先级消息总能及时发送——在机器人控制中急停信号的ID设得最小确保最高优先级。实际项目中如何选择协议。面试官经常给你一个场景让你选型。关键考虑因素数据量每秒多少字节、实时性要求延迟容忍度、拓扑结构点对点还是多点、环境干扰强度、距离。把这些因素列清楚选型自然就出来了。不要只背协议参数要能结合场景分析。给你的建议实际项目中这四种协议经常混合使用。一个典型的机器人系统UART接GPS和蓝牙SPI接IMU和FlashI2C接气压计和磁力计CAN接电机驱动器。调试通信问题时逻辑分析仪是最好的工具。一个几十块钱的逻辑分析仪可以抓取SPI/I2C/UART的波形比示波器方便得多。CAN的调试需要专门的CAN分析仪比如PCAN或Kvaser但也可以用逻辑分析仪看差分信号。写驱动时先读芯片的数据手册确认时序要求建立时间、保持时间再配置MCU的外设寄存器。不要凭感觉配置——SPI的Mode配错一个位数据就全是乱的。上一篇第320篇 嵌入式C编程实践下一篇预告第322篇 CAN总线深入解析
返回列表