3. Modbus协议核心原理

Modbus 是 Altivar 变频器最常用的串行通信协议之一。它的本质并不复杂:一台主站发起请求,一台或多台从站应答,请求和应答都围绕“功能码 + 寄存器地址 + 数据”展开。理解这五个关键词——主从架构、功能码、寄存器映射、帧格式、CRC 与异常响应——就掌握了 Modbus 通信的骨架。

主从架构:谁说话,谁应答

Modbus 采用严格的主从模式。主站(通常是 PLC、HMI 或上位机)主动发出请求帧,从站(如 Altivar 变频器)只有在被点名时才应答。从站之间不会互相通信,也不会主动上报。每个从站有一个 1~247 的站号(Slave Address),主站通过站号选择目标设备。

这种架构带来两个工程要点:其一,主站必须管理轮询节奏,避免同时向多个从站发请求造成总线冲突;其二,从站响应时间有限,若主站在规定时间内未收到应答,应判定为超时并重试。Altivar 变频器通常支持 Modbus RTU 和 Modbus ASCII 两种串行传输模式,站号、波特率、校验位等参数需与主站一致。

功能码:请求做什么

功能码(Function Code)是 Modbus 请求帧中的第一个字节,决定从站执行什么操作。常用功能码如下:

功能码名称作用Altivar 典型用途
0x01读线圈读取开关量输出状态读取继电器输出状态
0x02读离散输入读取开关量输入状态读取逻辑输入状态
0x03读保持寄存器读取 16 位参数值读取频率、电流、状态字
0x04读输入寄存器读取只读测量值读取实际输出频率
0x06写单个寄存器写入一个 16 位值修改给定频率
0x10写多个寄存器连续写入多个值批量下发命令字

功能码的最高位还承担异常标志:正常响应中功能码与请求相同;若从站返回的功能码最高位为 1(即原功能码 + 0x80),表示发生异常,后续字节为异常码。

寄存器映射:地址与数据的对应关系

Modbus 把从站数据组织成四类寄存器空间:线圈(0x)、离散输入(1x)、输入寄存器(3x)、保持寄存器(4x)。在协议帧中,地址以 0 为基准传输,而工程文档常以 1 为基准描述,因此存在“协议地址 = 文档地址 − 1”的换算关系。

以 Altivar 为例,常见映射包括:状态字(如 3201 或 0x0C81 附近)、频率给定、实际输出频率、电流、故障代码等。实际工程中必须查阅对应型号的 Modbus 通信手册,确认每个参数的寄存器地址、数据类型(16 位有符号/无符号、32 位高低字顺序)和读写属性。例如,若手册标注“输出频率:地址 3202,单位 0.1 Hz”,则读到数值 500 表示 50.0 Hz。

寄存器地址的“文档地址”与“协议地址”相差 1 是常见错误来源。编程时先确认手册使用的是哪一种基准,再决定是否减 1。

RTU 与 ASCII 帧格式

Modbus 串行传输有两种帧格式:RTU 和 ASCII。RTU 以二进制传输,效率高,是工业现场主流;ASCII 以可读字符传输,便于调试但效率低。

RTU 帧结构:站号(1 字节)+ 功能码(1 字节)+ 数据(N 字节)+ CRC(2 字节)。帧与帧之间以至少 3.5 个字符时间的静默间隔分隔。

ASCII 帧结构:起始符“:”+ 站号(2 个 ASCII 字符)+ 功能码(2 个字符)+ 数据(N 个字符)+ LRC(2 个字符)+ 结束符 CR LF。每个字节被拆成两个十六进制字符传输。

下面是一个 RTU 读保持寄存器的请求示例(站号 1,读地址 0x0C81 起 2 个寄存器):

请求:01 03 0C 81 00 02 CRC_L CRC_H
响应:01 03 04 Data1_H Data1_L Data2_H Data2_L CRC_L CRC_H

其中 CRC 由发送方计算并附加在帧尾,接收方重新计算并比对。若 CRC 不匹配,从站丢弃该帧,不返回任何响应,主站最终表现为超时。

CRC 校验:保证帧完整性

CRC-16/Modbus 使用多项式 0xA001(反向表示),初始值 0xFFFF。计算时对帧中除 CRC 外的每个字节与当前 CRC 异或,然后逐位右移,若最低位为 1 则再异或 0xA001,重复 8 次。最终得到的 16 位值按低字节在前、高字节在后附加到帧尾。

工程上不需要手算 CRC,但需要理解它的作用:CRC 能检测单比特、双比特、奇数个错误以及大多数突发错误。若现场出现“偶发通信失败”,优先检查波特率、校验位、接地和屏蔽,而不是怀疑 CRC 算法本身。

异常响应:从站如何说“不”

当从站无法完成请求时,会返回异常响应。其结构为:站号 + 功能码(原功能码 + 0x80)+ 异常码 + CRC。常见异常码包括:

  • 0x01 非法功能:从站不支持该功能码。
  • 0x02 非法数据地址:请求的寄存器地址不存在或不可访问。
  • 0x03 非法数据值:写入的数据超出允许范围。
  • 0x04 从站设备故障:从站执行时发生内部错误。
  • 0x06 从站忙:从站正在处理长任务,暂时无法响应。

例如,主站请求功能码 0x03 读取一个不存在的地址,从站可能返回:01 83 02 CRC_L CRC_H。其中 0x83 = 0x03 + 0x80,0x02 表示非法数据地址。主站程序应解析异常码并给出明确提示,而不是简单重试。

Modbus 主从请求/响应与异常判定 主站 Master PLC / HMI / 上位机 发起请求、轮询、超时重试 从站 Slave Altivar 变频器 站号 1~247,被动应答 请求帧:站号 + 功能码 + 数据 + CRC 正常响应:站号 + 功能码 + 数据 + CRC 异常响应:站号 + (功能码+0x80) + 异常码 + CRC RTU 帧结构 站号 1B 功能码 1B 数据 N 字节 CRC 2B 帧间静默 ≥ 3.5 字符时间 常见异常码 0x01 非法功能 0x02 非法地址 0x03 非法数据值 0x04 从站故障 0x06 从站忙 判定逻辑:功能码最高位 = 1 → 异常响应;CRC 错误 → 从站静默丢弃,主站超时。

工程落地要点

把上述原理落到 Altivar 集成工程中,需要关注以下几点。第一,主站轮询周期要大于从站最大响应时间,避免请求堆积。第二,读写寄存器前先确认地址基准和数据类型,尤其是 32 位参数的高低字顺序。第三,CRC 错误和异常响应要分开处理:CRC 错误通常意味着物理层干扰,异常响应则说明请求本身有问题。第四,ASCII 模式仅建议用于调试,正式运行优先使用 RTU。第五,若从站返回 0x06(从站忙),主站应等待一段时间再重试,而不是立即连续发送。

掌握这些内容后,后续配置 Altivar 的 Modbus 通信参数、编写读写程序、排查通信故障时,就能从帧结构和异常码出发快速定位问题,而不是盲目更换线缆或反复重启设备。