串口通信是单片机与外部设备交互最常用的方式,但裸数据收发容易出错。要让通信可靠、可扩展,就需要在串口之上设计一套通信协议:规定帧格式、添加校验、并用状态机解析数据。本文从帧结构设计讲起,逐步实现一套实用的串口通信协议。
一、为什么需要通信协议直接发字节虽然简单,却存在三个问题:数据边界不清(不知道一帧从哪开始到哪结束)、无法检错(数据被干扰也不知道)、扩展困难(收发双方各写各的格式)。通信协议通过在原始字节之上增加帧头、帧尾、长度、校验和等功能字段,为通信双方约定统一的格式和流程,从而可靠地传输数据。协议设计的目标,就是在可靠性和简单性之间找到平衡点。
二、帧结构设计一个典型的帧结构包含:帧头(如0xAA 0x55两字节,用于同步和识别)、长度字段(标识有效数据长度)、命令字/功能码(区分不同功能)、数据域(实际载荷)、校验字段(如累加和、CRC16)、帧尾(如0x0D 0x0A)。设计时要注意几点:帧头要选择不容易在数据中出现的高频码型,必要时配合转义;长度字段决定了单帧最大载荷;校验方式的选择要兼顾可靠性与计算开销,简单场景用累加和,对可靠性要求高的场景用CRC16。清晰、统一的帧结构是协议稳定运行的基础。
三、校验算法实现累加和校验实现最简单:把所有字节相加取低8位作为校验值,接收端重新累加并比较。CRC校验可靠性更高,能检测多位错误,常用CRC16/CCITT;其原理是把数据当作多项式处理,通过移位和异或生成校验码。在51单片机或STM32上,CRC可用查表法加快计算速度。发送端计算并附加校验值,接收端对整帧(含校验值)重新计算,若结果为0或与附加值一致则判定数据正确,否则丢弃或请求重发。可靠的校验是协议健壮性的重要一环。
四、状态机解析帧数据接收数据用状态机解析非常清晰。常见做法是维护一个接收状态,依次经历WAIT_HEAD1、WAIT_HEAD2、WAIT_LEN、WAIT_DATA、WAIT_CHECK等状态:匹配到帧头进入下一状态,收集长度字段后按长度接收数据域,最后校验校验值。用状态机的好处是每收到一个字节只做一次判断,不依赖阻塞等待,适合在串口中断或定时轮询中处理。解析完成后置标志位,主程序检测到标志再处理完整帧,做到收发解耦。把帧结构、校验和状态机三部分组合起来,就能搭建一套健壮、易扩展的串口通信协议,为设备间稳定交互打下坚实基础。
|